sound: soc: codec: add es8316_pcm_shutdown function

Fix hdmi intermittent playback when headphone is plugged in.

Signed-off-by: Ken Wang <ken@radxa.com>
This commit is contained in:
Ken Wang 2024-07-26 17:06:18 +08:00 committed by Jianfeng Liu
parent 41073c8a4b
commit dc1d92c8e2

View file

@ -67,6 +67,7 @@ struct es8316_priv {
unsigned int allowed_rates[NR_SUPPORTED_MCLK_LRCK_RATIOS];
struct snd_pcm_hw_constraint_list sysclk_constraints;
bool jd_inverted;
int pwr_count;
};
/*
@ -561,6 +562,7 @@ static int es8316_pcm_startup(struct snd_pcm_substream *substream,
ES8316_CLKMGR_DAC_MCLK_MASK,
ES8316_CLKMGR_MCLK_DIV_NML |
ES8316_CLKMGR_DAC_MCLK_EN);
es8316->pwr_count++;
if (playback) {
snd_soc_component_write(component, ES8316_SYS_LP1, 0x3F);
@ -591,6 +593,42 @@ static int es8316_pcm_startup(struct snd_pcm_substream *substream,
return 0;
}
static void es8316_pcm_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
bool playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
if (playback) {
snd_soc_component_write(component, ES8316_CPHP_OUTEN, 0x00);
snd_soc_component_write(component, ES8316_DAC_PDN, 0x11);
snd_soc_component_write(component, ES8316_CPHP_LDOCTL, 0x03);
snd_soc_component_write(component, ES8316_CPHP_PDN2, 0x22);
snd_soc_component_write(component, ES8316_CPHP_PDN1, 0x06);
snd_soc_component_write(component, ES8316_HPMIX_SWITCH, 0x00);
snd_soc_component_write(component, ES8316_HPMIX_PDN, 0x33);
snd_soc_component_write(component, ES8316_HPMIX_VOL, 0x00);
snd_soc_component_write(component, ES8316_SYS_PDN, 0x00);
snd_soc_component_write(component, ES8316_SYS_LP1, 0xFF);
snd_soc_component_write(component, ES8316_SYS_LP2, 0xFF);
snd_soc_component_update_bits (component, ES8316_CLKMGR_CLKSW,
ES8316_CLKMGR_DAC_ANALOG_MASK,
ES8316_CLKMGR_DAC_ANALOG_DIS);
} else {
snd_soc_component_write(component, ES8316_ADC_PDN_LINSEL, 0xC0);
snd_soc_component_update_bits (component, ES8316_CLKMGR_CLKSW,
ES8316_CLKMGR_ADC_MCLK_MASK |
ES8316_CLKMGR_ADC_ANALOG_MASK,
ES8316_CLKMGR_ADC_MCLK_DIS |
ES8316_CLKMGR_ADC_ANALOG_DIS);
}
if (--es8316->pwr_count == 0) {
snd_soc_component_write(component, ES8316_CLKMGR_CLKSW, 0xF3);
}
}
static int es8316_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@ -668,6 +706,7 @@ static const struct snd_soc_dai_ops es8316_ops = {
.set_sysclk = es8316_set_dai_sysclk,
.mute_stream = es8316_mute,
.no_capture_mute = 1,
.shutdown = es8316_pcm_shutdown,
};
static struct snd_soc_dai_driver es8316_dai = {
@ -907,6 +946,7 @@ static int es8316_probe(struct snd_soc_component *component)
int ret;
es8316->component = component;
es8316->pwr_count = 0;
es8316->mclk = devm_clk_get_optional(component->dev, "mclk");
if (IS_ERR(es8316->mclk)) {