ASoC: amd: Adding TDM support in hw_params.
authorRavulapati Vishnu vardhan rao <Vishnuvardhanrao.Ravulapati@amd.com>
Mon, 9 Mar 2020 10:50:10 +0000 (16:20 +0530)
committerMark Brown <broonie@kernel.org>
Mon, 9 Mar 2020 14:25:04 +0000 (14:25 +0000)
TDM related settings for ACP registers in hw_params.
When TDM mode is enabled, Hw_params needs to read and write
from/to respective TX/RX (ACP_(I2S/BT)TDM_(TX/RX)FRMT) registers.

Signed-off-by: Ravulapati Vishnu vardhan rao <Vishnuvardhanrao.Ravulapati@amd.com>
Link: https://lore.kernel.org/r/1583751029-2850-1-git-send-email-Vishnuvardhanrao.Ravulapati@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/amd/raven/acp3x-i2s.c

index 91a3881..3a3c47e 100644 (file)
@@ -42,7 +42,7 @@ static int acp3x_i2s_set_tdm_slot(struct snd_soc_dai *cpu_dai,
                u32 tx_mask, u32 rx_mask, int slots, int slot_width)
 {
        struct i2s_dev_data *adata;
-       u32 val, reg_val, frmt_reg, frm_len;
+       u32 frm_len;
        u16 slot_len;
 
        adata = snd_soc_dai_get_drvdata(cpu_dai);
@@ -64,36 +64,7 @@ static int acp3x_i2s_set_tdm_slot(struct snd_soc_dai *cpu_dai,
        default:
                return -EINVAL;
        }
-
-       /* Enable I2S/BT channels TDM, respective TX/RX frame lengths.*/
-
        frm_len = FRM_LEN | (slots << 15) | (slot_len << 18);
-       if (adata->substream_type == SNDRV_PCM_STREAM_PLAYBACK) {
-               switch (adata->i2s_instance) {
-               case I2S_BT_INSTANCE:
-                       reg_val = mmACP_BTTDM_ITER;
-                       frmt_reg = mmACP_BTTDM_TXFRMT;
-                       break;
-               case I2S_SP_INSTANCE:
-               default:
-                       reg_val = mmACP_I2STDM_ITER;
-                       frmt_reg = mmACP_I2STDM_TXFRMT;
-               }
-       } else {
-               switch (adata->i2s_instance) {
-               case I2S_BT_INSTANCE:
-                       reg_val = mmACP_BTTDM_IRER;
-                       frmt_reg = mmACP_BTTDM_RXFRMT;
-                       break;
-               case I2S_SP_INSTANCE:
-               default:
-                       reg_val = mmACP_I2STDM_IRER;
-                       frmt_reg = mmACP_I2STDM_RXFRMT;
-               }
-       }
-       val = rv_readl(adata->acp3x_base + reg_val);
-       rv_writel(val | 0x2, adata->acp3x_base + reg_val);
-       rv_writel(frm_len, adata->acp3x_base + frmt_reg);
        adata->tdm_fmt = frm_len;
        return 0;
 }
@@ -105,12 +76,14 @@ static int acp3x_i2s_hwparams(struct snd_pcm_substream *substream,
        struct snd_soc_pcm_runtime *prtd;
        struct snd_soc_card *card;
        struct acp3x_platform_info *pinfo;
+       struct i2s_dev_data *adata;
        u32 val;
-       u32 reg_val;
+       u32 reg_val, frmt_reg;
 
        prtd = substream->private_data;
        rtd = substream->runtime->private_data;
        card = prtd->card;
+       adata = snd_soc_dai_get_drvdata(dai);
        pinfo = snd_soc_card_get_drvdata(card);
        if (pinfo) {
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -141,21 +114,30 @@ static int acp3x_i2s_hwparams(struct snd_pcm_substream *substream,
                switch (rtd->i2s_instance) {
                case I2S_BT_INSTANCE:
                        reg_val = mmACP_BTTDM_ITER;
+                       frmt_reg = mmACP_BTTDM_TXFRMT;
                        break;
                case I2S_SP_INSTANCE:
                default:
                        reg_val = mmACP_I2STDM_ITER;
+                       frmt_reg = mmACP_I2STDM_TXFRMT;
                }
        } else {
                switch (rtd->i2s_instance) {
                case I2S_BT_INSTANCE:
                        reg_val = mmACP_BTTDM_IRER;
+                       frmt_reg = mmACP_BTTDM_RXFRMT;
                        break;
                case I2S_SP_INSTANCE:
                default:
                        reg_val = mmACP_I2STDM_IRER;
+                       frmt_reg = mmACP_I2STDM_RXFRMT;
                }
        }
+       if (adata->tdm_mode) {
+               val = rv_readl(rtd->acp3x_base + reg_val);
+               rv_writel(val | 0x2, rtd->acp3x_base + reg_val);
+               rv_writel(adata->tdm_fmt, rtd->acp3x_base + frmt_reg);
+       }
        val = rv_readl(rtd->acp3x_base + reg_val);
        val = val | (rtd->xfer_resolution  << 3);
        rv_writel(val, rtd->acp3x_base + reg_val);