ASoC: Tegra: Fix I2S_SLOT_CTRL2 reg access
Sumit Bhattacharya [Wed, 20 Feb 2013 16:48:55 +0000 (21:48 +0530)]
When I2S_SLOT_CTRL2 register is modified for TX or RX port previous
value in the register for the other port need to be saved. This will
fix concurrent playback capture issues in BT SCO mode.

Bug 1233807

Change-Id: I618c0e929e0d2c6f16a327a1cc66c61a6d8f6fe6
Signed-off-by: Sumit Bhattacharya <sumitb@nvidia.com>
Reviewed-on: http://git-master/r/202583
Reviewed-by: Scott Peterson <speterson@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com>

sound/soc/tegra/tegra30_i2s.c
sound/soc/tegra/tegra30_i2s.h

index e05b55a..20faef8 100644 (file)
@@ -6,8 +6,8 @@
  *
  * Based on code copyright/by:
  *
- * Copyright (c) 2009-2010, NVIDIA Corporation.
- * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2009-2013, NVIDIA Corporation.
+ * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
  * Scott Peterson <speterson@nvidia.com>
  *
  * Copyright (C) 2010 Google, Inc.
@@ -108,6 +108,9 @@ static int tegra30_i2s_show(struct seq_file *s, void *unused)
                REG(TEGRA30_I2S_LCOEF_2_4_0),
                REG(TEGRA30_I2S_LCOEF_2_4_1),
                REG(TEGRA30_I2S_LCOEF_2_4_2),
+#ifndef CONFIG_ARCH_TEGRA_3x_SOC
+               REG(TEGRA30_I2S_SLOT_CTRL2),
+#endif
        };
 #undef REG
 
@@ -554,15 +557,19 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
                        bitcnt = (i2sclock / srate) - 1;
                        sym_bitclk = !(i2sclock % srate);
 #ifndef CONFIG_ARCH_TEGRA_3x_SOC
-                       val = 0;
-                       for (i = 0; i < params_channels(params); i++)
-                               val |= (1 << i);
-                       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                               val = val <<
+                       val = tegra30_i2s_read(i2s, TEGRA30_I2S_SLOT_CTRL2);
+
+                       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+                               val &=
+                                 ~TEGRA30_I2S_SLOT_CTRL2_TX_SLOT_ENABLES_MASK;
+                               val |= ((1 << params_channels(params)) - 1) <<
                                  TEGRA30_I2S_SLOT_CTRL2_TX_SLOT_ENABLES_SHIFT;
-                       else
-                               val = val <<
+                       } else {
+                               val &=
+                                 ~TEGRA30_I2S_SLOT_CTRL2_RX_SLOT_ENABLES_MASK;
+                               val |= ((1 << params_channels(params)) - 1) <<
                                  TEGRA30_I2S_SLOT_CTRL2_RX_SLOT_ENABLES_SHIFT;
+                       }
                        tegra30_i2s_write(i2s, TEGRA30_I2S_SLOT_CTRL2, val);
 #endif
                } else {
index 562bf53..040baef 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * tegra30_i2s.h - Definitions for Tegra 30 I2S driver
  *
- * Copyright (c) 2010-2011, NVIDIA Corporation.
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
 
 #ifndef CONFIG_ARCH_TEGRA_3x_SOC
 #define TEGRA30_I2S_SLOT_CTRL2_TX_SLOT_ENABLES_SHIFT   0
+#define TEGRA30_I2S_SLOT_CTRL2_TX_SLOT_ENABLES_MASK    (0xffff << TEGRA30_I2S_SLOT_CTRL2_TX_SLOT_ENABLES_SHIFT)
+
 #define TEGRA30_I2S_SLOT_CTRL2_RX_SLOT_ENABLES_SHIFT   16
+#define TEGRA30_I2S_SLOT_CTRL2_RX_SLOT_ENABLES_MASK    (0xffff << TEGRA30_I2S_SLOT_CTRL2_RX_SLOT_ENABLES_SHIFT)
 #endif
 
 /* Fields in TEGRA30_I2S_CIF_RX_CTRL */