audio: auge: fix spdif reset when used for share buffer [1/1]
authorXing Wang <xing.wang@amlogic.com>
Tue, 5 Mar 2019 02:45:46 +0000 (10:45 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Fri, 8 Mar 2019 11:34:15 +0000 (03:34 -0800)
PD#SWPL-3655

Problem:
spdif output 8 channel, channel map in wrong order.

Solution:
reset spdif before enable as soon as quickly.
modification is limited for tl1 now

Verify:
x301

Change-Id: I224032390404be85c77d7436a9be9148df09c997
Signed-off-by: Xing Wang <xing.wang@amlogic.com>
sound/soc/amlogic/auge/sharebuffer.c
sound/soc/amlogic/auge/sharebuffer.h
sound/soc/amlogic/auge/spdif.c
sound/soc/amlogic/auge/spdif_hw.c
sound/soc/amlogic/auge/spdif_hw.h
sound/soc/amlogic/auge/tdm.c

index f94fd2a..855d7a6 100644 (file)
@@ -68,7 +68,7 @@ static int sharebuffer_spdifout_free(struct snd_pcm_substream *substream,
        return 0;
 }
 
-void sharebuffer_enable(int sel, bool enable)
+void sharebuffer_enable(int sel, bool enable, bool reenable)
 {
        if (sel < 0) {
                pr_err("Not support same source\n");
@@ -77,7 +77,7 @@ void sharebuffer_enable(int sel, bool enable)
                // TODO: same with tdm
        } else if (sel < 5) {
                /* same source with spdif a/b */
-               spdifout_enable(sel - 3, enable);
+               spdifout_enable(sel - 3, enable, reenable);
        }
 }
 
@@ -127,18 +127,18 @@ int sharebuffer_free(struct snd_pcm_substream *substream,
 }
 
 
-int sharebuffer_trigger(int cmd, int samesource_sel)
+int sharebuffer_trigger(int cmd, int samesource_sel, bool reenable)
 {
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               sharebuffer_enable(samesource_sel, true);
+               sharebuffer_enable(samesource_sel, true, reenable);
                break;
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               sharebuffer_enable(samesource_sel, false);
+               sharebuffer_enable(samesource_sel, false, reenable);
                break;
        default:
                return -EINVAL;
index 25dca7d..e32a9f4 100644 (file)
@@ -21,7 +21,7 @@ extern int sharebuffer_prepare(struct snd_pcm_substream *substream,
        void *pfrddr, int samesource_sel);
 extern int sharebuffer_free(struct snd_pcm_substream *substream,
                void *pfrddr, int samesource_sel);
-extern int sharebuffer_trigger(int cmd, int samesource_sel);
+extern int sharebuffer_trigger(int cmd, int samesource_sel, bool reenable);
 
 extern void sharebuffer_get_mclk_fs_ratio(int samesource_sel,
        int *pll_mclk_ratio, int *mclk_fs_ratio);
index 3650c6e..3dd0d5f 100644 (file)
@@ -72,6 +72,8 @@ struct spdif_chipinfo {
        bool eq_drc_en;
        /* pc, pd interrupt is separated. */
        bool pcpd_separated;
+       /* same source, spdif re-enable */
+       bool same_src_spdif_reen;
 };
 
 struct aml_spdif {
@@ -1469,6 +1471,7 @@ struct spdif_chipinfo tl1_spdif_a_chipinfo = {
        .chnum_en     = true,
        .hold_start   = true,
        .eq_drc_en    = true,
+       .same_src_spdif_reen = true,
 };
 
 struct spdif_chipinfo tl1_spdif_b_chipinfo = {
@@ -1476,6 +1479,7 @@ struct spdif_chipinfo tl1_spdif_b_chipinfo = {
        .chnum_en     = true,
        .hold_start   = true,
        .eq_drc_en    = true,
+       .same_src_spdif_reen = true,
 };
 
 static const struct of_device_id aml_spdif_device_id[] = {
@@ -1513,6 +1517,7 @@ static int aml_spdif_platform_probe(struct platform_device *pdev)
        struct aml_spdif *aml_spdif = NULL;
        struct spdif_chipinfo *p_spdif_chipinfo;
        int ret = 0;
+       bool spdif_reenable = false;
 
 
        aml_spdif = devm_kzalloc(dev, sizeof(struct aml_spdif), GFP_KERNEL);
@@ -1533,6 +1538,8 @@ static int aml_spdif_platform_probe(struct platform_device *pdev)
                aml_spdif->clk_cont = 1;
 
                aml_spdif->chipinfo = p_spdif_chipinfo;
+
+               spdif_reenable = p_spdif_chipinfo->same_src_spdif_reen;
        } else
                dev_warn_once(dev,
                        "check whether to update spdif chipinfo\n");
@@ -1555,7 +1562,7 @@ static int aml_spdif_platform_probe(struct platform_device *pdev)
                return -EINVAL;
 
        if (aml_spdif->clk_cont)
-               spdifout_play_with_zerodata(aml_spdif->id);
+               spdifout_play_with_zerodata(aml_spdif->id, spdif_reenable);
 
        ret = devm_snd_soc_register_component(dev, &aml_spdif_component,
                &aml_spdif_dai[aml_spdif->id], 1);
index ff1eb5b..713edb6 100644 (file)
@@ -450,13 +450,6 @@ static void spdifout_fifo_ctrl(int spdif_id,
        offset = EE_AUDIO_SPDIFOUT_B_SWAP - EE_AUDIO_SPDIFOUT_SWAP;
        reg = EE_AUDIO_SPDIFOUT_SWAP + offset * spdif_id;
        audiobus_write(reg, 1<<4);
-
-       /* reset afifo */
-       offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
-       reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * spdif_id;
-       audiobus_update_bits(reg, 3<<28, 0);
-       audiobus_update_bits(reg, 1<<29, 1<<29);
-       audiobus_update_bits(reg, 1<<28, 1<<28);
 }
 
 static bool spdifout_is_enable(int spdif_id)
@@ -470,7 +463,7 @@ static bool spdifout_is_enable(int spdif_id)
        return ((val >> 31) == 1);
 }
 
-void spdifout_enable(int spdif_id, bool is_enable)
+void spdifout_enable(int spdif_id, bool is_enable, bool reenable)
 {
        unsigned int offset, reg;
 
@@ -487,6 +480,15 @@ void spdifout_enable(int spdif_id, bool is_enable)
                return;
        }
 
+       /* disable then for reset, to correct channel map */
+       if (reenable)
+               audiobus_update_bits(reg, 1<<31, 0x0<<31);
+
+       /* reset afifo */
+       audiobus_update_bits(reg, 3<<28, 0);
+       audiobus_update_bits(reg, 1<<29, 1<<29);
+       audiobus_update_bits(reg, 1<<28, 1<<28);
+
        audiobus_update_bits(reg, 1<<31, is_enable<<31);
 }
 
@@ -608,7 +610,7 @@ void spdif_set_channel_status_info(
        audiobus_write(reg, chsts->chstat1_r << 16 | chsts->chstat0_r);
 }
 
-void spdifout_play_with_zerodata(unsigned int spdif_id)
+void spdifout_play_with_zerodata(unsigned int spdif_id, bool reenable)
 {
        pr_debug("%s, spdif id:%d enable:%d\n",
                __func__,
@@ -654,7 +656,7 @@ void spdifout_play_with_zerodata(unsigned int spdif_id)
                frddr_init_without_mngr(frddr_index, src0_sel);
 
                /* spdif enable */
-               spdifout_enable(spdif_id, true);
+               spdifout_enable(spdif_id, true, reenable);
        }
 }
 
index d2f6b96..689dc7e 100644 (file)
@@ -79,7 +79,7 @@ extern void spdifout_to_hdmitx_ctrl(int spdif_index);
 
 extern void spdifout_samesource_set(int spdif_index, int fifo_id,
        int bitwidth, int channels, bool is_enable);
-extern void spdifout_enable(int spdif_id, bool is_enable);
+extern void spdifout_enable(int spdif_id, bool is_enable, bool reenable);
 
 extern int spdifin_get_sample_rate(void);
 
@@ -90,7 +90,7 @@ extern int spdifin_get_audio_type(void);
 extern void spdif_set_channel_status_info(
        struct iec958_chsts *chsts, int spdif_id);
 
-extern void spdifout_play_with_zerodata(unsigned int spdif_id);
+extern void spdifout_play_with_zerodata(unsigned int spdif_id, bool reenable);
 extern void spdifout_play_with_zerodata_free(unsigned int spdif_id);
 extern void spdifin_set_src(int src);
 #endif
index 7226e9a..35e9bbf 100644 (file)
@@ -91,6 +91,9 @@ struct tdm_chipinfo {
        /* same source */
        bool same_src_fn;
 
+       /* same source, spdif re-enable */
+       bool same_src_spdif_reen;
+
        /* ACODEC_ADC function */
        bool adc_fn;
 };
@@ -518,9 +521,11 @@ static int aml_dai_tdm_trigger(struct snd_pcm_substream *substream, int cmd,
                && p_tdm->chipinfo->same_src_fn
                && (p_tdm->samesource_sel >= 0)
                && (aml_check_sharebuffer_valid(p_tdm->fddr,
-                               p_tdm->samesource_sel))) {
-                       sharebuffer_trigger(cmd, p_tdm->samesource_sel);
-       }
+                               p_tdm->samesource_sel))
+       )
+               sharebuffer_trigger(cmd,
+                       p_tdm->samesource_sel,
+                       p_tdm->chipinfo->same_src_spdif_reen);
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
@@ -1230,6 +1235,7 @@ struct tdm_chipinfo tl1_tdma_chipinfo = {
        .clk_pad_ctl = true,
        .same_src_fn = true,
        .adc_fn      = true,
+       .same_src_spdif_reen = true,
 };
 
 struct tdm_chipinfo tl1_tdmb_chipinfo = {
@@ -1239,6 +1245,7 @@ struct tdm_chipinfo tl1_tdmb_chipinfo = {
        .clk_pad_ctl = true,
        .same_src_fn = true,
        .adc_fn      = true,
+       .same_src_spdif_reen = true,
 };
 
 struct tdm_chipinfo tl1_tdmc_chipinfo = {
@@ -1248,6 +1255,7 @@ struct tdm_chipinfo tl1_tdmc_chipinfo = {
        .clk_pad_ctl = true,
        .same_src_fn = true,
        .adc_fn      = true,
+       .same_src_spdif_reen = true,
 };
 
 static const struct of_device_id aml_tdm_device_id[] = {