Maybe a bug in tegra210_i2s_alt.c with R28.1

I’m using TX1 with R28.1.

After I set bitclock-master and frame-master for audio codec dai link in dts file.
When aplay xxx.wav. The error will report:
[ 144.774903] tegra210-i2s tegra210-i2s.4: Failed at I2S0_TX sw reset
[ 144.781162] tegra210-i2s tegra210-i2s.4: ASoC: PRE_PMU: I2S1 DAP TX event failed: -22

Then I check the code in tegra210_i2s_alt.c, found that:

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_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;
} else {
	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;
}

    regmap_update_bits(i2s->regmap, sw_reset_reg, sw_reset_mask, sw_reset_en);



}

But in R24.2:

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);



}

So the question is, when have playback stream , TX and RX, which one should be reset?
And which version is Right?

Besides, both of R24.2 and R28.1 has this code:

static const struct snd_soc_dapm_widget tegra210_i2s_widgets = {
SND_SOC_DAPM_AIF_IN(“CIF RX”, NULL, 0, SND_SOC_NOPM,
0, 0),
SND_SOC_DAPM_AIF_OUT(“CIF TX”, NULL, 0, SND_SOC_NOPM,
0, 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),
};

TX and RX should’t be correspond to TX/RX reg?

Anyone from NVidia can confirm that?

@Below change make them different. The r28.1 should be correct one.

commit 67499cabf96884add59e29e940180e3204df0641
Author: Gaurav Tendolkar <gtendolkar@nvidia.com>
Date:   Fri Oct 16 16:40:32 2015 +0530

    ASoC: tegra-alt: Fix i2s soft reset api

    - rx soft reset should be set for playback case
      and tx soft reset for capture case
    - make soft reset registers writable by regmap

    Change-Id: I840332e9ae30506c16c22ad423dc5e264188a858
    Signed-off-by: Gaurav Tendolkar <gtendolkar@nvidia.com>
    Reviewed-on: http://git-master/r/818828
    Reviewed-by: Automatic_Commit_Validation_User
    Reviewed-by: Nitin Pai <npai@nvidia.com>
    Tested-by: Nitin Pai <npai@nvidia.com>

diff --git a/sound/soc/tegra-alt/tegra210_i2s_alt.c b/sound/soc/tegra-alt/tegra210_i2s_alt.c
index 9049126..3f8f352 100644
--- a/sound/soc/tegra-alt/tegra210_i2s_alt.c
+++ b/sound/soc/tegra-alt/tegra210_i2s_alt.c
@@ -147,15 +147,15 @@ static int tegra210_i2s_sw_reset(struct tegra210_i2s *i2s,
        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;
+       } else {
+               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;
        }

        regmap_update_bits(i2s->regmap, sw_reset_reg, sw_reset_mask, sw_reset_en);
@@ -759,6 +759,7 @@ static bool tegra210_i2s_wr_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
        case TEGRA210_I2S_AXBAR_RX_ENABLE:
+       case TEGRA210_I2S_AXBAR_RX_SOFT_RESET:
        case TEGRA210_I2S_AXBAR_RX_INT_MASK:
        case TEGRA210_I2S_AXBAR_RX_INT_SET:
        case TEGRA210_I2S_AXBAR_RX_INT_CLEAR:
@@ -767,6 +768,7 @@ static bool tegra210_i2s_wr_reg(struct device *dev, unsigned int reg)
        case TEGRA210_I2S_AXBAR_RX_SLOT_CTRL:
        case TEGRA210_I2S_AXBAR_RX_CLK_TRIM:
        case TEGRA210_I2S_AXBAR_TX_ENABLE:
+       case TEGRA210_I2S_AXBAR_TX_SOFT_RESET:
        case TEGRA210_I2S_AXBAR_TX_INT_MASK:
        case TEGRA210_I2S_AXBAR_TX_INT_SET:
        case TEGRA210_I2S_AXBAR_TX_INT_CLEAR:

@ShaneCCC

The problem of bitclock-master and frame-master mode still not solve.

Can you share your dts or dtb file when you set bitclock-master and frame-master?

@zhili
Since you already bring the same topic How to enable I2S slave mode? - Jetson TX1 - NVIDIA Developer Forums
Please move to the new topic to discuss.