[alsa-devel] [PATCH] ASoC: rt5645: add clock source selection controls
From: Bard Liao bardliao@realtek.com
We can select the clock source of some digital widgets in rt5645. This patch adds the controls of those selections.
Signed-off-by: Bard Liao bardliao@realtek.com --- sound/soc/codecs/rt5645.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index a7762d0..e8e30b7 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -440,6 +440,89 @@ static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_sel_enum, RT5645_TDM_CTRL_1, 8, rt5645_tdm_adc_data_select);
+static const char * const rt5645_asrc_clk_source[] = { + "clk_sysy_div_out", "clk_i2s1_track", "clk_i2s2_track", + "clk_i2s3_track", "clk_i2s4_track", "clk_sys2", "clk_sys3", + "clk_sys4", "clk_sys5" +}; + +static const SOC_ENUM_SINGLE_DECL(rt5645_da_sto_asrc_enum, RT5645_ASRC_2, + 12, rt5645_asrc_clk_source); + +static const SOC_ENUM_SINGLE_DECL(rt5645_da_monol_asrc_enum, RT5645_ASRC_2, + 8, rt5645_asrc_clk_source); + +static const SOC_ENUM_SINGLE_DECL(rt5645_da_monor_asrc_enum, RT5645_ASRC_2, + 4, rt5645_asrc_clk_source); + +static const SOC_ENUM_SINGLE_DECL(rt5645_ad_sto1_asrc_enum, RT5645_ASRC_2, + 0, rt5645_asrc_clk_source); + +static const SOC_ENUM_SINGLE_DECL(rt5645_ad_monol_asrc_enum, RT5645_ASRC_3, + 4, rt5645_asrc_clk_source); + +static const SOC_ENUM_SINGLE_DECL(rt5645_ad_monor_asrc_enum, RT5645_ASRC_3, + 0, rt5645_asrc_clk_source); + +static int rt5645_clk_sel_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + unsigned int u_bit = 0, p_bit = 0; + struct soc_enum *em = + (struct soc_enum *)kcontrol->private_value; + + switch (em->reg) { + case RT5645_ASRC_2: + switch (em->shift_l) { + case 0: + u_bit = 0x8; + p_bit = RT5645_PWR_ADC_S1F; + break; + case 4: + u_bit = 0x100; + p_bit = RT5645_PWR_DAC_MF_R; + break; + case 8: + u_bit = 0x200; + p_bit = RT5645_PWR_DAC_MF_L; + break; + case 12: + u_bit = 0x400; + p_bit = RT5645_PWR_DAC_S1F; + break; + } + break; + case RT5645_ASRC_3: + switch (em->shift_l) { + case 0: + u_bit = 0x1; + p_bit = RT5645_PWR_ADC_MF_R; + break; + case 4: + u_bit = 0x2; + p_bit = RT5645_PWR_ADC_MF_L; + break; + } + break; + } + + if (u_bit || p_bit) { + switch (ucontrol->value.integer.value[0]) { + case 1 ... 4: /*enable*/ + if (snd_soc_read(codec, RT5645_PWR_DIG2) & p_bit) + snd_soc_update_bits(codec, + RT5645_ASRC_1, u_bit, u_bit); + break; + default: /*disable*/ + snd_soc_update_bits(codec, RT5645_ASRC_1, u_bit, 0); + break; + } + } + + return snd_soc_put_enum_double(kcontrol, ucontrol); +} + static const struct snd_kcontrol_new rt5645_snd_controls[] = { /* Speaker Output Volume */ SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, @@ -511,6 +594,20 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = { SOC_SINGLE("TDM IF1_DAC1_R Sel", RT5645_TDM_CTRL_3, 8, 7, 0), SOC_SINGLE("TDM IF1_DAC2_L Sel", RT5645_TDM_CTRL_3, 4, 7, 0), SOC_SINGLE("TDM IF1_DAC2_R Sel", RT5645_TDM_CTRL_3, 0, 7, 0), + + /* Clock Source Selection*/ + SOC_ENUM_EXT("DA STO Clk Sel", rt5645_da_sto_asrc_enum, + snd_soc_get_enum_double, rt5645_clk_sel_put), + SOC_ENUM_EXT("DA MONOL Clk Sel", rt5645_da_monol_asrc_enum, + snd_soc_get_enum_double, rt5645_clk_sel_put), + SOC_ENUM_EXT("DA MONOR Clk Sel", rt5645_da_monor_asrc_enum, + snd_soc_get_enum_double, rt5645_clk_sel_put), + SOC_ENUM_EXT("AD STO1 Clk Sel", rt5645_ad_sto1_asrc_enum, + snd_soc_get_enum_double, rt5645_clk_sel_put), + SOC_ENUM_EXT("AD MONOL Clk Sel", rt5645_ad_monol_asrc_enum, + snd_soc_get_enum_double, rt5645_clk_sel_put), + SOC_ENUM_EXT("AD MONOR Clk Sel", rt5645_ad_monor_asrc_enum, + snd_soc_get_enum_double, rt5645_clk_sel_put), };
/**
On Thu, Jul 17, 2014 at 05:09:23PM +0800, bardliao@realtek.com wrote:
From: Bard Liao bardliao@realtek.com
We can select the clock source of some digital widgets in rt5645. This patch adds the controls of those selections.
This is exposing the clocking configuration directly to userspace. I'm really not sure we should be doing this, it's not how we typically handle clocking in ASoC - usually the clock management is done in the kernel as it typically needs to be coordinated with other things such as clock API operations. Userspace control tends to be a system level thing offered by the machine driver.
It's possible that there's a case for doing this directly in userspace but you need to make it in the changelog.
participants (2)
-
bardliao@realtek.com
-
Mark Brown