From 6398ca28ead83f77a8d9aadae13b8281d50c0775 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 Conflicts: sound/soc/amlogic/auge/tdm.c --- 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 | 18 ++++++++++++++++++ 6 files changed, 46 insertions(+), 19 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 e021552211ba..4ad78596e0f0 100644 --- a/sound/soc/amlogic/auge/spdif.c +++ b/sound/soc/amlogic/auge/spdif.c @@ -70,6 +70,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 { @@ -1500,6 +1502,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 = { @@ -1507,6 +1510,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[] = { @@ -1544,6 +1548,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); @@ -1564,6 +1569,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"); @@ -1587,7 +1594,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 04172b61eb3d..799424868f6f 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__, @@ -658,7 +660,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 ab71d3e9d65f..15dd5bb812af 100644 --- a/sound/soc/amlogic/auge/tdm.c +++ b/sound/soc/amlogic/auge/tdm.c @@ -92,6 +92,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,6 +521,18 @@ static int aml_dai_tdm_trigger(struct snd_pcm_substream *substream, int cmd, { struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai); + /* share buffer trigger */ + if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + && p_tdm->chipinfo + && p_tdm->chipinfo->same_src_fn + && (p_tdm->samesource_sel >= 0) + && (aml_check_sharebuffer_valid(p_tdm->fddr, + p_tdm->samesource_sel)) + && p_tdm->en_share) + sharebuffer_trigger(cmd, + p_tdm->samesource_sel, + p_tdm->chipinfo->same_src_spdif_reen); + switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: @@ -1242,6 +1257,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 = { @@ -1251,6 +1267,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 = { @@ -1260,6 +1277,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[] = {