ASoC: rt5682s: Reduce coupling of I2S1 setting

Some parts of rt5682s CCF function are implemented
by 'I2S1' dapm widget.
The coupling risk exists, so this patch fixes it.

Signed-off-by: Derek Fang <derek.fang@realtek.com>
Link: https://lore.kernel.org/r/20220913025658.5005-2-derek.fang@realtek.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Derek Fang 2022-09-13 10:56:57 +08:00 committed by Mark Brown
parent bfc5e8b860
commit 6ea304a402
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
1 changed files with 67 additions and 39 deletions

View File

@ -1229,41 +1229,58 @@ static int set_dmic_power(struct snd_soc_dapm_widget *w,
return 0;
}
static int set_i2s_clk(struct snd_soc_dapm_widget *w,
static void rt5682s_set_i2s(struct rt5682s_priv *rt5682s, int id, int on)
{
struct snd_soc_component *component = rt5682s->component;
int pre_div;
unsigned int p_reg, p_mask, p_sft;
unsigned int c_reg, c_mask, c_sft;
if (id == RT5682S_AIF1) {
c_reg = RT5682S_ADDA_CLK_1;
c_mask = RT5682S_I2S_M_D_MASK;
c_sft = RT5682S_I2S_M_D_SFT;
p_reg = RT5682S_PWR_DIG_1;
p_mask = RT5682S_PWR_I2S1;
p_sft = RT5682S_PWR_I2S1_BIT;
} else {
c_reg = RT5682S_I2S2_M_CLK_CTRL_1;
c_mask = RT5682S_I2S2_M_D_MASK;
c_sft = RT5682S_I2S2_M_D_SFT;
p_reg = RT5682S_PWR_DIG_1;
p_mask = RT5682S_PWR_I2S2;
p_sft = RT5682S_PWR_I2S2_BIT;
}
if (on && rt5682s->master[id]) {
pre_div = get_clk_info(rt5682s->sysclk, rt5682s->lrck[id]);
if (pre_div < 0) {
dev_err(component->dev, "get pre_div failed\n");
return;
}
dev_dbg(component->dev, "lrck is %dHz and pre_div is %d for iis %d master\n",
rt5682s->lrck[id], pre_div, id);
snd_soc_component_update_bits(component, c_reg, c_mask, pre_div << c_sft);
}
snd_soc_component_update_bits(component, p_reg, p_mask, on << p_sft);
}
static int set_i2s_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct rt5682s_priv *rt5682s = snd_soc_component_get_drvdata(component);
int pre_div, id;
unsigned int reg, mask, sft;
int on = 0;
if (event != SND_SOC_DAPM_PRE_PMU)
return 0;
if (SND_SOC_DAPM_EVENT_ON(event))
on = 1;
if (w->shift == RT5682S_PWR_I2S2_BIT) {
id = RT5682S_AIF2;
reg = RT5682S_I2S2_M_CLK_CTRL_1;
mask = RT5682S_I2S2_M_D_MASK;
sft = RT5682S_I2S2_M_D_SFT;
} else {
id = RT5682S_AIF1;
reg = RT5682S_ADDA_CLK_1;
mask = RT5682S_I2S_M_D_MASK;
sft = RT5682S_I2S_M_D_SFT;
}
if (!rt5682s->master[id])
return 0;
pre_div = get_clk_info(rt5682s->sysclk, rt5682s->lrck[id]);
if (pre_div < 0) {
dev_err(component->dev, "get pre_div failed\n");
return -EINVAL;
}
dev_dbg(component->dev, "lrck is %dHz and pre_div is %d for iis %d master\n",
rt5682s->lrck[id], pre_div, id);
snd_soc_component_update_bits(component, reg, mask, pre_div << sft);
if (!strcmp(w->name, "I2S1") && !rt5682s->wclk_enabled)
rt5682s_set_i2s(rt5682s, RT5682S_AIF1, on);
else if (!strcmp(w->name, "I2S2"))
rt5682s_set_i2s(rt5682s, RT5682S_AIF2, on);
return 0;
}
@ -1715,10 +1732,10 @@ static const struct snd_soc_dapm_widget rt5682s_dapm_widgets[] = {
SND_SOC_DAPM_PGA("Stereo1 ADC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
/* Digital Interface */
SND_SOC_DAPM_SUPPLY("I2S1", RT5682S_PWR_DIG_1, RT5682S_PWR_I2S1_BIT,
0, set_i2s_clk, SND_SOC_DAPM_PRE_PMU),
SND_SOC_DAPM_SUPPLY("I2S2", RT5682S_PWR_DIG_1, RT5682S_PWR_I2S2_BIT,
0, set_i2s_clk, SND_SOC_DAPM_PRE_PMU),
SND_SOC_DAPM_SUPPLY("I2S1", SND_SOC_NOPM, 0, 0,
set_i2s_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY("I2S2", SND_SOC_NOPM, 0, 0,
set_i2s_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0),
@ -2426,12 +2443,15 @@ static int rt5682s_set_bias_level(struct snd_soc_component *component,
RT5682S_PWR_LDO, RT5682S_PWR_LDO);
break;
case SND_SOC_BIAS_STANDBY:
regmap_update_bits(rt5682s->regmap, RT5682S_PWR_DIG_1,
RT5682S_DIG_GATE_CTRL, RT5682S_DIG_GATE_CTRL);
if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
regmap_update_bits(rt5682s->regmap, RT5682S_PWR_DIG_1,
RT5682S_DIG_GATE_CTRL, RT5682S_DIG_GATE_CTRL);
break;
case SND_SOC_BIAS_OFF:
regmap_update_bits(rt5682s->regmap, RT5682S_PWR_DIG_1,
RT5682S_DIG_GATE_CTRL | RT5682S_PWR_LDO, 0);
regmap_update_bits(rt5682s->regmap, RT5682S_PWR_DIG_1, RT5682S_PWR_LDO, 0);
if (!rt5682s->wclk_enabled)
regmap_update_bits(rt5682s->regmap, RT5682S_PWR_DIG_1,
RT5682S_DIG_GATE_CTRL, 0);
break;
case SND_SOC_BIAS_ON:
break;
@ -2473,13 +2493,17 @@ static int rt5682s_wclk_prepare(struct clk_hw *hw)
snd_soc_component_update_bits(component, RT5682S_PWR_ANLG_1,
RT5682S_PWR_FV2, RT5682S_PWR_FV2);
/* Set and power on I2S1 */
snd_soc_component_update_bits(component, RT5682S_PWR_DIG_1,
RT5682S_DIG_GATE_CTRL, RT5682S_DIG_GATE_CTRL);
rt5682s_set_i2s(rt5682s, RT5682S_AIF1, 1);
rt5682s->wclk_enabled = 1;
mutex_unlock(&rt5682s->wclk_mutex);
snd_soc_dapm_mutex_lock(dapm);
snd_soc_dapm_force_enable_pin_unlocked(dapm, "I2S1");
/* Only need to power PLLB due to the rate set restriction */
snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLLB");
snd_soc_dapm_sync_unlocked(dapm);
@ -2505,13 +2529,17 @@ static void rt5682s_wclk_unprepare(struct clk_hw *hw)
snd_soc_component_update_bits(component, RT5682S_PWR_ANLG_1,
RT5682S_PWR_VREF2 | RT5682S_PWR_FV2 | RT5682S_PWR_MB, 0);
/* Power down I2S1 */
rt5682s_set_i2s(rt5682s, RT5682S_AIF1, 0);
snd_soc_component_update_bits(component, RT5682S_PWR_DIG_1,
RT5682S_DIG_GATE_CTRL, 0);
rt5682s->wclk_enabled = 0;
mutex_unlock(&rt5682s->wclk_mutex);
snd_soc_dapm_mutex_lock(dapm);
snd_soc_dapm_disable_pin_unlocked(dapm, "I2S1");
snd_soc_dapm_disable_pin_unlocked(dapm, "PLLB");
snd_soc_dapm_sync_unlocked(dapm);