diff --git a/sound/soc/tegra-alt/tegra210_admaif_alt.c b/sound/soc/tegra-alt/tegra210_admaif_alt.c
index 06a166a7..99ef4b5f 100644
--- a/sound/soc/tegra-alt/tegra210_admaif_alt.c
+++ b/sound/soc/tegra-alt/tegra210_admaif_alt.c
@@ -15,6 +15,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
+
+#include
#include
#include
#include
@@ -154,6 +156,25 @@ static int tegra210_admaif_sw_reset(struct snd_soc_dai *dai,
return 0;
}
+static int tegra210_admaif_get_status(struct snd_soc_dai *dai,
+ int direction)
+{
+ struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
+ unsigned int status_reg, val;
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ status_reg = TEGRA210_ADMAIF_XBAR_RX_STATUS +
+ (dai->id * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
+ } else {
+ status_reg = TEGRA210_ADMAIF_XBAR_TX_STATUS +
+ (dai->id * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
+ }
+ regmap_read(admaif->regmap, status_reg, &val);
+ val = (val & 0x00000001);
+
+ return val;
+}
+
static int tegra210_admaif_runtime_suspend(struct device *dev)
{
struct tegra210_admaif *admaif = dev_get_drvdata(dev);
@@ -224,7 +245,7 @@ static int tegra210_admaif_hw_params(struct snd_pcm_substream *substream,
struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
struct tegra210_xbar_cif_conf cif_conf;
unsigned int reg, fifo_ctrl, fifo_size;
- int valid_bit, ret;
+ int valid_bit;
cif_conf.audio_channels = params_channels(params);
cif_conf.client_channels = params_channels(params);
@@ -266,13 +287,6 @@ static int tegra210_admaif_hw_params(struct snd_pcm_substream *substream,
fifo_size = 3;
}
- /* HW needs sw reset to make sure previous transaction be clean */
- ret = tegra210_admaif_sw_reset(dai, substream->stream, 0xffff);
- if (ret) {
- dev_err(dev, "Failed at sw reset\n");
- return ret;
- }
-
tegra210_admaif_set_pack_mode(admaif->regmap, reg, valid_bit);
admaif->soc_data->set_audio_cif(admaif->regmap, reg, &cif_conf);
@@ -304,8 +318,10 @@ static void tegra210_admaif_start_playback(struct snd_soc_dai *dai)
static void tegra210_admaif_stop_playback(struct snd_soc_dai *dai)
{
+ struct device *dev = dai->dev;
struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
unsigned int reg;
+ int dcnt = 10, ret;
tegra210_admaif_global_enable(admaif, 0);
reg = TEGRA210_ADMAIF_XBAR_TX_ENABLE +
@@ -313,6 +329,16 @@ static void tegra210_admaif_stop_playback(struct snd_soc_dai *dai)
regmap_update_bits(admaif->regmap, reg,
TEGRA210_ADMAIF_XBAR_TX_ENABLE_MASK,
0);
+
+ /* wait until ADMAIF TX status is disabled */
+ while (tegra210_admaif_get_status(dai, SNDRV_PCM_STREAM_PLAYBACK) &&
+ dcnt--)
+ udelay(100);
+
+ /* HW needs sw reset to make sure previous transaction be clean */
+ ret = tegra210_admaif_sw_reset(dai, SNDRV_PCM_STREAM_PLAYBACK, 0xffff);
+ if (ret)
+ dev_err(dev, "Failed at ADMAIF%d_TX sw reset\n", dev->id);
}
static void tegra210_admaif_start_capture(struct snd_soc_dai *dai)
@@ -330,8 +356,10 @@ static void tegra210_admaif_start_capture(struct snd_soc_dai *dai)
static void tegra210_admaif_stop_capture(struct snd_soc_dai *dai)
{
+ struct device *dev = dai->dev;
struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
unsigned int reg;
+ int dcnt = 10, ret;
tegra210_admaif_global_enable(admaif, 0);
reg = TEGRA210_ADMAIF_XBAR_RX_ENABLE +
@@ -339,6 +367,16 @@ static void tegra210_admaif_stop_capture(struct snd_soc_dai *dai)
regmap_update_bits(admaif->regmap, reg,
TEGRA210_ADMAIF_XBAR_RX_ENABLE_MASK,
0);
+
+ /* wait until ADMAIF RX status is disabled */
+ while (tegra210_admaif_get_status(dai, SNDRV_PCM_STREAM_CAPTURE) &&
+ dcnt--)
+ udelay(100);
+
+ /* HW needs sw reset to make sure previous transaction be clean */
+ ret = tegra210_admaif_sw_reset(dai, SNDRV_PCM_STREAM_CAPTURE, 0xffff);
+ if (ret)
+ dev_err(dev, "Failed at ADMAIF%d_RX sw reset\n", dev->id);
}
static int tegra210_admaif_trigger(struct snd_pcm_substream *substream, int cmd,
diff --git a/sound/soc/tegra-alt/tegra210_adx_alt.c b/sound/soc/tegra-alt/tegra210_adx_alt.c
index 3fff4bc6..aabdcb65 100644
--- a/sound/soc/tegra-alt/tegra210_adx_alt.c
+++ b/sound/soc/tegra-alt/tegra210_adx_alt.c
@@ -16,6 +16,7 @@
* along with this program. If not, see .
*/
+#include
#include
#include
#include
@@ -142,6 +143,62 @@ static void tegra210_adx_update_map_ram(struct tegra210_adx *adx)
tegra210_adx_write_map_ram(adx, i, adx->map[i]);
}
+static int tegra210_adx_sw_reset(struct tegra210_adx *adx,
+ int timeout)
+{
+ unsigned int val;
+ int wait = timeout;
+
+ regmap_update_bits(adx->regmap, TEGRA210_ADX_SOFT_RESET,
+ TEGRA210_ADX_SOFT_RESET_SOFT_RESET_MASK,
+ TEGRA210_ADX_SOFT_RESET_SOFT_EN);
+
+ do {
+ regmap_read(adx->regmap, TEGRA210_ADX_SOFT_RESET, &val);
+ wait--;
+ if (!wait)
+ return -EINVAL;
+ } while (val & 0x00000001);
+
+ regmap_update_bits(adx->regmap, TEGRA210_ADX_SOFT_RESET,
+ TEGRA210_ADX_SOFT_RESET_SOFT_RESET_MASK,
+ TEGRA210_ADX_SOFT_RESET_SOFT_DEFAULT);
+
+ return 0;
+}
+
+static int tegra210_adx_get_status(struct tegra210_adx *adx)
+{
+ unsigned int val;
+
+ regmap_read(adx->regmap, TEGRA210_ADX_STATUS, &val);
+ val = (val & 0x00000001);
+
+ return val;
+}
+
+static int tegra210_adx_stop(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct device *dev = codec->dev;
+ struct tegra210_adx *adx = dev_get_drvdata(dev);
+ int dcnt = 10, ret = 0;
+
+ /* wait until ADX status is disabled */
+ while (tegra210_adx_get_status(adx) && dcnt--)
+ udelay(100);
+
+ /* HW needs sw reset to make sure previous transaction be clean */
+ ret = tegra210_adx_sw_reset(adx, 0xffff);
+ if (ret) {
+ dev_err(dev, "Failed at ADX%d sw reset\n", dev->id);
+ return ret;
+ }
+
+ return (dcnt < 0) ? -ETIMEDOUT : 0;
+}
+
#ifdef TEGRA210_ADX_MAP_READ
static unsigned int tegra210_adx_read_map_ram(struct tegra210_adx *adx,
unsigned int addr)
@@ -301,7 +358,14 @@ int tegra210_adx_set_channel_map(struct snd_soc_dai *dai,
struct tegra210_adx *adx = snd_soc_dai_get_drvdata(dai);
unsigned int byte_mask1 = 0, byte_mask2 = 0;
unsigned int out_stream_idx, out_ch_idx, out_byte_idx;
- int i;
+ int i, ret = 0;
+
+ /* HW needs sw reset to make sure previous transaction be clean */
+ tegra210_adx_sw_reset(adx, 0xffff);
+ if (ret) {
+ dev_err(dev, "Failed at ADX sw reset\n");
+ return ret;
+ }
if ((rx_num < 1) || (rx_num > 64)) {
dev_err(dev, "Doesn't support %d rx_num, need to be 1 to 64\n",
@@ -402,7 +466,9 @@ static struct snd_soc_dai_driver tegra210_adx_dais[] = {
};
static const struct snd_soc_dapm_widget tegra210_adx_widgets[] = {
- SND_SOC_DAPM_AIF_IN("IN", NULL, 0, TEGRA210_ADX_ENABLE, 0, 0),
+ SND_SOC_DAPM_AIF_IN_E("IN", NULL, 0, TEGRA210_ADX_ENABLE,
+ TEGRA210_ADX_ENABLE_SHIFT, 0,
+ tegra210_adx_stop, SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_AIF_OUT("OUT1", NULL, 0, TEGRA210_ADX_CTRL, 0, 0),
SND_SOC_DAPM_AIF_OUT("OUT2", NULL, 0, TEGRA210_ADX_CTRL, 1, 0),
SND_SOC_DAPM_AIF_OUT("OUT3", NULL, 0, TEGRA210_ADX_CTRL, 2, 0),
@@ -481,6 +547,8 @@ static bool tegra210_adx_rd_reg(struct device *dev,
case TEGRA210_ADX_ENABLE:
case TEGRA210_ADX_SOFT_RESET:
case TEGRA210_ADX_CG:
+ case TEGRA210_ADX_STATUS:
+ case TEGRA210_ADX_INT_STATUS:
case TEGRA210_ADX_CTRL:
case TEGRA210_ADX_IN_BYTE_EN0:
case TEGRA210_ADX_IN_BYTE_EN1:
@@ -493,6 +561,29 @@ static bool tegra210_adx_rd_reg(struct device *dev,
};
}
+static bool tegra210_adx_volatile_reg(struct device *dev,
+ unsigned int reg)
+{
+ switch (reg) {
+ case TEGRA210_ADX_AXBAR_RX_STATUS:
+ case TEGRA210_ADX_AXBAR_RX_INT_STATUS:
+ case TEGRA210_ADX_AXBAR_RX_INT_SET:
+ case TEGRA210_ADX_AXBAR_TX_STATUS:
+ case TEGRA210_ADX_AXBAR_TX_INT_STATUS:
+ case TEGRA210_ADX_AXBAR_TX_INT_SET:
+ case TEGRA210_ADX_SOFT_RESET:
+ case TEGRA210_ADX_STATUS:
+ case TEGRA210_ADX_INT_STATUS:
+ case TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL:
+ case TEGRA210_ADX_AHUBRAMCTL_ADX_DATA:
+ return true;
+ default:
+ break;
+ };
+
+ return false;
+}
+
static const struct regmap_config tegra210_adx_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -500,6 +591,7 @@ static const struct regmap_config tegra210_adx_regmap_config = {
.max_register = TEGRA210_ADX_AHUBRAMCTL_ADX_DATA,
.writeable_reg = tegra210_adx_wr_reg,
.readable_reg = tegra210_adx_rd_reg,
+ .volatile_reg = tegra210_adx_volatile_reg,
.cache_type = REGCACHE_RBTREE,
};
diff --git a/sound/soc/tegra-alt/tegra210_amx_alt.c b/sound/soc/tegra-alt/tegra210_amx_alt.c
index 80c167f7..f7da5c12 100644
--- a/sound/soc/tegra-alt/tegra210_amx_alt.c
+++ b/sound/soc/tegra-alt/tegra210_amx_alt.c
@@ -16,6 +16,7 @@
* along with this program. If not, see .
*/
+#include
#include
#include
#include
@@ -167,6 +168,62 @@ static void tegra210_amx_update_map_ram(struct tegra210_amx *amx)
tegra210_amx_write_map_ram(amx, i, amx->map[i]);
}
+static int tegra210_amx_sw_reset(struct tegra210_amx *amx,
+ int timeout)
+{
+ unsigned int val;
+ int wait = timeout;
+
+ regmap_update_bits(amx->regmap, TEGRA210_AMX_SOFT_RESET,
+ TEGRA210_AMX_SOFT_RESET_SOFT_RESET_MASK,
+ TEGRA210_AMX_SOFT_RESET_SOFT_EN);
+
+ do {
+ regmap_read(amx->regmap, TEGRA210_AMX_SOFT_RESET, &val);
+ wait--;
+ if (!wait)
+ return -EINVAL;
+ } while (val & 0x00000001);
+
+ regmap_update_bits(amx->regmap, TEGRA210_AMX_SOFT_RESET,
+ TEGRA210_AMX_SOFT_RESET_SOFT_RESET_MASK,
+ TEGRA210_AMX_SOFT_RESET_SOFT_DEFAULT);
+
+ return 0;
+}
+
+static int tegra210_amx_get_status(struct tegra210_amx *amx)
+{
+ unsigned int val;
+
+ regmap_read(amx->regmap, TEGRA210_AMX_STATUS, &val);
+ val = (val & 0x00000001);
+
+ return val;
+}
+
+static int tegra210_amx_stop(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct device *dev = codec->dev;
+ struct tegra210_amx *amx = dev_get_drvdata(dev);
+ int dcnt = 10, ret = 0;
+
+ /* wait until AMX status is disabled */
+ while (tegra210_amx_get_status(amx) && dcnt--)
+ udelay(100);
+
+ /* HW needs sw reset to make sure previous transaction be clean */
+ ret = tegra210_amx_sw_reset(amx, 0xffff);
+ if (ret) {
+ dev_err(dev, "Failed at AMX%d sw reset\n", dev->id);
+ return ret;
+ }
+
+ return (dcnt < 0) ? -ETIMEDOUT : 0;
+}
+
static int tegra210_amx_runtime_suspend(struct device *dev)
{
struct tegra210_amx *amx = dev_get_drvdata(dev);
@@ -329,7 +386,14 @@ int tegra210_amx_set_channel_map(struct snd_soc_dai *dai,
struct tegra210_amx *amx = snd_soc_dai_get_drvdata(dai);
unsigned int byte_mask1 = 0, byte_mask2 = 0;
unsigned int in_stream_idx, in_ch_idx, in_byte_idx;
- int i;
+ int i, ret = 0;
+
+ /* HW needs sw reset to make sure previous transaction be clean */
+ tegra210_amx_sw_reset(amx, 0xffff);
+ if (ret) {
+ dev_err(dev, "Failed at AMX sw reset\n");
+ return ret;
+ }
if ((tx_num < 1) || (tx_num > 64)) {
dev_err(dev, "Doesn't support %d tx_num, need to be 1 to 64\n",
@@ -343,7 +407,7 @@ int tegra210_amx_set_channel_map(struct snd_soc_dai *dai,
}
tegra210_amx_set_master_stream(amx, 0,
- TEGRA210_AMX_WAIT_ON_ALL);
+ TEGRA210_AMX_WAIT_ON_ANY);
memset(amx->map, 0, sizeof(amx->map));
@@ -438,7 +502,9 @@ static const struct snd_soc_dapm_widget tegra210_amx_widgets[] = {
SND_SOC_DAPM_AIF_IN("IN2", NULL, 0, TEGRA210_AMX_CTRL, 1, 0),
SND_SOC_DAPM_AIF_IN("IN3", NULL, 0, TEGRA210_AMX_CTRL, 2, 0),
SND_SOC_DAPM_AIF_IN("IN4", NULL, 0, TEGRA210_AMX_CTRL, 3, 0),
- SND_SOC_DAPM_AIF_OUT("OUT", NULL, 0, TEGRA210_AMX_ENABLE, 0, 0),
+ SND_SOC_DAPM_AIF_OUT_E("OUT", NULL, 0, TEGRA210_AMX_ENABLE,
+ TEGRA210_AMX_ENABLE_SHIFT, 0,
+ tegra210_amx_stop, SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_route tegra210_amx_routes[] = {
@@ -528,6 +594,29 @@ static bool tegra210_amx_rd_reg(struct device *dev,
};
}
+static bool tegra210_amx_volatile_reg(struct device *dev,
+ unsigned int reg)
+{
+ switch (reg) {
+ case TEGRA210_AMX_AXBAR_RX_STATUS:
+ case TEGRA210_AMX_AXBAR_RX_INT_STATUS:
+ case TEGRA210_AMX_AXBAR_RX_INT_SET:
+ case TEGRA210_AMX_AXBAR_TX_STATUS:
+ case TEGRA210_AMX_AXBAR_TX_INT_STATUS:
+ case TEGRA210_AMX_AXBAR_TX_INT_SET:
+ case TEGRA210_AMX_SOFT_RESET:
+ case TEGRA210_AMX_STATUS:
+ case TEGRA210_AMX_INT_STATUS:
+ case TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL:
+ case TEGRA210_AMX_AHUBRAMCTL_AMX_DATA:
+ return true;
+ default:
+ break;
+ };
+
+ return false;
+}
+
static const struct regmap_config tegra210_amx_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -535,6 +624,7 @@ static const struct regmap_config tegra210_amx_regmap_config = {
.max_register = TEGRA210_AMX_AHUBRAMCTL_AMX_DATA,
.writeable_reg = tegra210_amx_wr_reg,
.readable_reg = tegra210_amx_rd_reg,
+ .volatile_reg = tegra210_amx_volatile_reg,
.cache_type = REGCACHE_RBTREE,
};
diff --git a/sound/soc/tegra-alt/tegra210_i2s_alt.c b/sound/soc/tegra-alt/tegra210_i2s_alt.c
index 9eb90a64..c4d32d26 100644
--- a/sound/soc/tegra-alt/tegra210_i2s_alt.c
+++ b/sound/soc/tegra-alt/tegra210_i2s_alt.c
@@ -15,6 +15,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
+
+#include
#include
#include
#include
@@ -96,6 +98,112 @@ static int tegra210_i2s_set_clock_rate(struct device *dev, int clock_rate)
return ret;
}
+static int tegra210_i2s_sw_reset(struct tegra210_i2s *i2s,
+ int direction, int timeout)
+{
+ unsigned int sw_reset_reg, sw_reset_mask, sw_reset_en, sw_reset_default;
+ unsigned int tx_cif_ctrl, rx_cif_ctrl, tx_ctrl, rx_ctrl, ctrl, val;
+ int wait = timeout;
+
+ regmap_read(i2s->regmap, TEGRA210_I2S_AXBAR_TX_CIF_CTRL, &tx_cif_ctrl);
+ regmap_read(i2s->regmap, TEGRA210_I2S_AXBAR_RX_CIF_CTRL, &rx_cif_ctrl);
+ regmap_read(i2s->regmap, TEGRA210_I2S_AXBAR_TX_CTRL, &tx_ctrl);
+ regmap_read(i2s->regmap, TEGRA210_I2S_AXBAR_RX_CTRL, &rx_ctrl);
+ regmap_read(i2s->regmap, TEGRA210_I2S_CTRL, &ctrl);
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ sw_reset_reg = TEGRA210_I2S_AXBAR_TX_SOFT_RESET;
+ sw_reset_mask = TEGRA210_I2S_AXBAR_TX_SOFT_RESET_MASK;
+ sw_reset_en = TEGRA210_I2S_AXBAR_TX_SOFT_RESET_EN;
+ sw_reset_default = TEGRA210_I2S_AXBAR_TX_SOFT_RESET_DEFAULT;
+ } else {
+ sw_reset_reg = TEGRA210_I2S_AXBAR_RX_SOFT_RESET;
+ sw_reset_mask = TEGRA210_I2S_AXBAR_RX_SOFT_RESET_MASK;
+ sw_reset_en = TEGRA210_I2S_AXBAR_RX_SOFT_RESET_EN;
+ sw_reset_default = TEGRA210_I2S_AXBAR_RX_SOFT_RESET_DEFAULT;
+ }
+
+ regmap_update_bits(i2s->regmap, sw_reset_reg, sw_reset_mask, sw_reset_en);
+
+ do {
+ regmap_read(i2s->regmap, sw_reset_reg, &val);
+ wait--;
+ if (!wait)
+ return -EINVAL;
+ } while (val & sw_reset_mask);
+
+ regmap_update_bits(i2s->regmap, sw_reset_reg, sw_reset_mask, sw_reset_default);
+
+ regmap_write(i2s->regmap, TEGRA210_I2S_AXBAR_TX_CIF_CTRL, tx_cif_ctrl);
+ regmap_write(i2s->regmap, TEGRA210_I2S_AXBAR_RX_CIF_CTRL, rx_cif_ctrl);
+ regmap_write(i2s->regmap, TEGRA210_I2S_AXBAR_TX_CTRL, tx_ctrl);
+ regmap_write(i2s->regmap, TEGRA210_I2S_AXBAR_RX_CTRL, rx_ctrl);
+ regmap_write(i2s->regmap, TEGRA210_I2S_CTRL, ctrl);
+
+ return 0;
+}
+
+static int tegra210_i2s_get_status(struct tegra210_i2s *i2s,
+ int direction)
+{
+ unsigned int status_reg, val;
+
+ status_reg = (direction == SNDRV_PCM_STREAM_PLAYBACK) ?
+ TEGRA210_I2S_AXBAR_TX_STATUS :
+ TEGRA210_I2S_AXBAR_RX_STATUS;
+
+ regmap_read(i2s->regmap, status_reg, &val);
+ val = val & 0x00000001;
+
+ return val;
+}
+
+static int tegra210_i2s_rx_stop(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct device *dev = codec->dev;
+ struct tegra210_i2s *i2s = dev_get_drvdata(dev);
+ int dcnt = 10, ret;
+
+ /* wait until I2S RX status is disabled;
+ ADMAIF is first disabled followed by I2S */
+ while (tegra210_i2s_get_status(i2s, SNDRV_PCM_STREAM_CAPTURE) &&
+ dcnt--)
+ udelay(100);
+
+ /* HW needs sw reset to make sure previous transaction be clean */
+ ret = tegra210_i2s_sw_reset(i2s, SNDRV_PCM_STREAM_CAPTURE, 0xffff);
+ if (ret) {
+ dev_err(dev, "Failed at I2S%d_RX sw reset\n", dev->id);
+ return ret;
+ }
+ return 0;
+}
+
+static int tegra210_i2s_tx_stop(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = w->codec;
+ struct device *dev = codec->dev;
+ struct tegra210_i2s *i2s = dev_get_drvdata(dev);
+ int dcnt = 10, ret;
+
+ /* wait until I2S TX status is disabled;
+ ADMAIF is first disabled followed by I2S */
+ while (tegra210_i2s_get_status(i2s, SNDRV_PCM_STREAM_PLAYBACK) &&
+ dcnt--)
+ udelay(100);
+
+ /* HW needs sw reset to make sure previous transaction be clean */
+ ret = tegra210_i2s_sw_reset(i2s, SNDRV_PCM_STREAM_PLAYBACK, 0xffff);
+ if (ret) {
+ dev_err(dev, "Failed at I2S%d_TX sw reset\n", dev->id);
+ return ret;
+ }
+ return 0;
+}
+
static int tegra210_i2s_runtime_suspend(struct device *dev)
{
struct tegra210_i2s *i2s = dev_get_drvdata(dev);
@@ -489,10 +597,12 @@ static const struct snd_soc_dapm_widget tegra210_i2s_widgets[] = {
0, 0),
SND_SOC_DAPM_AIF_OUT("CIF TX", NULL, 0, SND_SOC_NOPM,
0, 0),
- SND_SOC_DAPM_AIF_IN("DAP RX", NULL, 0, TEGRA210_I2S_AXBAR_TX_ENABLE,
- TEGRA210_I2S_AXBAR_TX_EN_SHIFT, 0),
- SND_SOC_DAPM_AIF_OUT("DAP TX", NULL, 0, TEGRA210_I2S_AXBAR_RX_ENABLE,
- TEGRA210_I2S_AXBAR_RX_EN_SHIFT, 0),
+ SND_SOC_DAPM_AIF_IN_E("DAP RX", NULL, 0, TEGRA210_I2S_AXBAR_TX_ENABLE,
+ TEGRA210_I2S_AXBAR_TX_EN_SHIFT, 0,
+ tegra210_i2s_rx_stop, SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_AIF_OUT_E("DAP TX", NULL, 0, TEGRA210_I2S_AXBAR_RX_ENABLE,
+ TEGRA210_I2S_AXBAR_RX_EN_SHIFT, 0,
+ tegra210_i2s_tx_stop, SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_route tegra210_i2s_routes[] = {