mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
ASoC: rk3308_codec: add supports Mute/Work switches for ADC MICs
Change-Id: If8714a3182cded36bfc1d36d1d29493f2e51cccf Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
This commit is contained in:
@@ -169,6 +169,10 @@ struct rk3308_codec_priv {
|
||||
unsigned int agc_asr_l[ADC_LR_GROUP_MAX];
|
||||
unsigned int agc_asr_r[ADC_LR_GROUP_MAX];
|
||||
|
||||
/* ADC MIC Mute/Work */
|
||||
unsigned int mic_mute_l[ADC_LR_GROUP_MAX];
|
||||
unsigned int mic_mute_r[ADC_LR_GROUP_MAX];
|
||||
|
||||
/* For the high pass filter */
|
||||
unsigned int hpf_cutoff[ADC_LR_GROUP_MAX];
|
||||
|
||||
@@ -236,12 +240,21 @@ static int rk3308_codec_agc_asr_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
static int rk3308_codec_agc_asr_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
static int rk3308_codec_mic_mute_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
static int rk3308_codec_mic_mute_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
static const char *offon_text[2] = {
|
||||
[0] = "Off",
|
||||
[1] = "On",
|
||||
};
|
||||
|
||||
static const char *mute_text[2] = {
|
||||
[0] = "Work",
|
||||
[1] = "Mute",
|
||||
};
|
||||
|
||||
#define HPF_NUM 4
|
||||
|
||||
#define HPF_CUTOFF_20HZ 0
|
||||
@@ -275,6 +288,18 @@ static const struct soc_enum rk3308_agc_enum_array[] = {
|
||||
SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(offon_text), offon_text),
|
||||
};
|
||||
|
||||
/* ADC MIC Mute/Work Switch */
|
||||
static const struct soc_enum rk3308_mic_mute_enum_array[] = {
|
||||
SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(mute_text), mute_text),
|
||||
SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(mute_text), mute_text),
|
||||
SOC_ENUM_SINGLE(1, 0, ARRAY_SIZE(mute_text), mute_text),
|
||||
SOC_ENUM_SINGLE(1, 1, ARRAY_SIZE(mute_text), mute_text),
|
||||
SOC_ENUM_SINGLE(2, 0, ARRAY_SIZE(mute_text), mute_text),
|
||||
SOC_ENUM_SINGLE(2, 1, ARRAY_SIZE(mute_text), mute_text),
|
||||
SOC_ENUM_SINGLE(3, 0, ARRAY_SIZE(mute_text), mute_text),
|
||||
SOC_ENUM_SINGLE(3, 1, ARRAY_SIZE(mute_text), mute_text),
|
||||
};
|
||||
|
||||
/* ALC AGC Approximate Sample Rate */
|
||||
#define AGC_ASR_NUM 8
|
||||
|
||||
@@ -505,6 +530,24 @@ static const struct snd_kcontrol_new rk3308_codec_dapm_controls[] = {
|
||||
SOC_ENUM_EXT("AGC Group 3 Right Approximate Sample Rate", rk3308_agc_asr_enum_array[7],
|
||||
rk3308_codec_agc_asr_get, rk3308_codec_agc_asr_put),
|
||||
|
||||
/* ADC MIC Mute/Work Switch */
|
||||
SOC_ENUM_EXT("ADC MIC Group 0 Left Switch", rk3308_mic_mute_enum_array[0],
|
||||
rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put),
|
||||
SOC_ENUM_EXT("ADC MIC Group 0 Right Switch", rk3308_mic_mute_enum_array[1],
|
||||
rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put),
|
||||
SOC_ENUM_EXT("ADC MIC Group 1 Left Switch", rk3308_mic_mute_enum_array[2],
|
||||
rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put),
|
||||
SOC_ENUM_EXT("ADC MIC Group 1 Right Switch", rk3308_mic_mute_enum_array[3],
|
||||
rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put),
|
||||
SOC_ENUM_EXT("ADC MIC Group 2 Left Switch", rk3308_mic_mute_enum_array[4],
|
||||
rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put),
|
||||
SOC_ENUM_EXT("ADC MIC Group 2 Right Switch", rk3308_mic_mute_enum_array[5],
|
||||
rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put),
|
||||
SOC_ENUM_EXT("ADC MIC Group 3 Left Switch", rk3308_mic_mute_enum_array[6],
|
||||
rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put),
|
||||
SOC_ENUM_EXT("ADC MIC Group 3 Right Switch", rk3308_mic_mute_enum_array[7],
|
||||
rk3308_codec_mic_mute_get, rk3308_codec_mic_mute_put),
|
||||
|
||||
/* ADC MIC */
|
||||
SOC_SINGLE_RANGE_TLV("ADC MIC Group 0 Left Volume",
|
||||
RK3308_ADC_ANA_CON01(0),
|
||||
@@ -809,6 +852,72 @@ static int rk3308_codec_agc_asr_put(struct snd_kcontrol *kcontrol,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk3308_codec_mic_mute_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||
struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
|
||||
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
|
||||
unsigned int value;
|
||||
int grp = e->reg;
|
||||
|
||||
if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) {
|
||||
dev_err(rk3308->plat_dev,
|
||||
"%s: Invalid ADC grp: %d\n", __func__, e->reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (e->shift_l) {
|
||||
/* ADC MIC Right Mute/Work Infos */
|
||||
regmap_read(rk3308->regmap, RK3308_ADC_DIG_CON03(grp), &value);
|
||||
rk3308->mic_mute_r[e->reg] = (value & RK3308_ADC_R_CH_BIST_SINE) >>
|
||||
RK3308_ADC_R_CH_BIST_SFT;
|
||||
ucontrol->value.integer.value[0] = rk3308->mic_mute_r[e->reg];
|
||||
} else {
|
||||
/* ADC MIC Left Mute/Work Infos */
|
||||
regmap_read(rk3308->regmap, RK3308_ADC_DIG_CON03(grp), &value);
|
||||
rk3308->mic_mute_l[e->reg] = (value & RK3308_ADC_L_CH_BIST_SINE) >>
|
||||
RK3308_ADC_L_CH_BIST_SFT;
|
||||
ucontrol->value.integer.value[0] = rk3308->mic_mute_l[e->reg];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk3308_codec_mic_mute_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||
struct rk3308_codec_priv *rk3308 = snd_soc_codec_get_drvdata(codec);
|
||||
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
|
||||
unsigned int value;
|
||||
int grp = e->reg;
|
||||
|
||||
if (e->reg < 0 || e->reg > ADC_LR_GROUP_MAX - 1) {
|
||||
dev_err(rk3308->plat_dev,
|
||||
"%s: Invalid ADC grp: %d\n", __func__, e->reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (e->shift_l) {
|
||||
/* ADC MIC Right Mute/Work Configuration */
|
||||
value = ucontrol->value.integer.value[0] << RK3308_ADC_R_CH_BIST_SFT;
|
||||
regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON03(grp),
|
||||
RK3308_ADC_R_CH_BIST_SINE,
|
||||
value);
|
||||
rk3308->mic_mute_r[e->reg] = ucontrol->value.integer.value[0];
|
||||
} else {
|
||||
/* ADC MIC Left Mute/Work Configuration */
|
||||
value = ucontrol->value.integer.value[0] << RK3308_ADC_L_CH_BIST_SFT;
|
||||
regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON03(grp),
|
||||
RK3308_ADC_L_CH_BIST_SINE,
|
||||
value);
|
||||
rk3308->mic_mute_l[e->reg] = ucontrol->value.integer.value[0];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk3308_codec_hpf_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user