mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 14:41:39 +00:00
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:
parent
bfc5e8b860
commit
6ea304a402
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user