From f1b1f034d6df72867894d8daf024f7e3e87e7e9a Mon Sep 17 00:00:00 2001 From: Xing Wang Date: Tue, 5 Mar 2019 10:45:46 +0800 Subject: [PATCH] audio: auge: fix spdif reset when used for share buffer [1/1] 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 --- sound/soc/amlogic/auge/sharebuffer.c | 10 +++++----- sound/soc/amlogic/auge/sharebuffer.h | 2 +- sound/soc/amlogic/auge/spdif.c | 9 ++++++++- sound/soc/amlogic/auge/spdif_hw.c | 22 ++++++++++++---------- sound/soc/amlogic/auge/spdif_hw.h | 4 ++-- sound/soc/amlogic/auge/tdm.c | 14 +++++++++++--- 6 files changed, 39 insertions(+), 22 deletions(-) diff --git a/sound/soc/amlogic/auge/sharebuffer.c b/sound/soc/amlogic/auge/sharebuffer.c index f94fd2a03b0c..855d7a6c31b0 100644 --- a/sound/soc/amlogic/auge/sharebuffer.c +++ b/sound/soc/amlogic/auge/sharebuffer.c @@ -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; diff --git a/sound/soc/amlogic/auge/sharebuffer.h b/sound/soc/amlogic/auge/sharebuffer.h index 25dca7d09ef4..e32a9f4b77a9 100644 --- a/sound/soc/amlogic/auge/sharebuffer.h +++ b/sound/soc/amlogic/auge/sharebuffer.h @@ -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); diff --git a/sound/soc/amlogic/auge/spdif.c b/sound/soc/amlogic/auge/spdif.c index 3650c6e50664..3dd0d5f66fb6 100644 --- a/sound/soc/amlogic/auge/spdif.c +++ b/sound/soc/amlogic/auge/spdif.c @@ -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); diff --git a/sound/soc/amlogic/auge/spdif_hw.c b/sound/soc/amlogic/auge/spdif_hw.c index ff1eb5b67de5..713edb6f4267 100644 --- a/sound/soc/amlogic/auge/spdif_hw.c +++ b/sound/soc/amlogic/auge/spdif_hw.c @@ -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); } } diff --git a/sound/soc/amlogic/auge/spdif_hw.h b/sound/soc/amlogic/auge/spdif_hw.h index d2f6b96dfffc..689dc7e715ca 100644 --- a/sound/soc/amlogic/auge/spdif_hw.h +++ b/sound/soc/amlogic/auge/spdif_hw.h @@ -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 diff --git a/sound/soc/amlogic/auge/tdm.c b/sound/soc/amlogic/auge/tdm.c index 7226e9a10c5f..35e9bbfd8c6f 100644 --- a/sound/soc/amlogic/auge/tdm.c +++ b/sound/soc/amlogic/auge/tdm.c @@ -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[] = {