mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
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 <xing.wang@amlogic.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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[] = {
|
||||
|
||||
Reference in New Issue
Block a user