#define CS47L15_NUM_ADSP 1
#define CS47L15_MONO_OUTPUTS 1
+/* Mid-mode registers */
+#define CS47L15_ADC_INT_BIAS_MASK 0x3800
+#define CS47L15_ADC_INT_BIAS_SHIFT 11
+#define CS47L15_PGA_BIAS_SEL_MASK 0x03
+#define CS47L15_PGA_BIAS_SEL_SHIFT 0
+
struct cs47l15 {
struct madera_priv core;
struct madera_fll fll[2];
+
+ bool in1_lp_mode;
};
static const struct wm_adsp_region cs47l15_dsp1_regions[] = {
SOC_SINGLE(name " NG SPKDAT1L Switch", base, 8, 1, 0), \
SOC_SINGLE(name " NG SPKDAT1R Switch", base, 9, 1, 0)
+static int cs47l15_in1_adc_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct cs47l15 *cs47l15 = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = cs47l15->in1_lp_mode ? 1 : 0;
+
+ return 0;
+}
+
+static int cs47l15_in1_adc_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct cs47l15 *cs47l15 = snd_soc_codec_get_drvdata(codec);
+
+ switch (ucontrol->value.integer.value[0]) {
+ case 0:
+ /* Set IN1 to normal mode */
+ snd_soc_update_bits(codec, MADERA_DMIC1L_CONTROL,
+ MADERA_IN1_OSR_MASK,
+ 5 << MADERA_IN1_OSR_SHIFT);
+ snd_soc_update_bits(codec, CS47L15_ADC_INT_BIAS,
+ CS47L15_ADC_INT_BIAS_MASK,
+ 4 << CS47L15_ADC_INT_BIAS_SHIFT);
+ snd_soc_update_bits(codec, CS47L15_PGA_BIAS_SEL,
+ CS47L15_PGA_BIAS_SEL_MASK,
+ 0);
+ cs47l15->in1_lp_mode = false;
+ break;
+ default:
+ /* Set IN1 to LP mode */
+ snd_soc_update_bits(codec, MADERA_DMIC1L_CONTROL,
+ MADERA_IN1_OSR_MASK,
+ 4 << MADERA_IN1_OSR_SHIFT);
+ snd_soc_update_bits(codec, CS47L15_ADC_INT_BIAS,
+ CS47L15_ADC_INT_BIAS_MASK,
+ 1 << CS47L15_ADC_INT_BIAS_SHIFT);
+ snd_soc_update_bits(codec, CS47L15_PGA_BIAS_SEL,
+ CS47L15_PGA_BIAS_SEL_MASK,
+ 3 << CS47L15_PGA_BIAS_SEL_SHIFT);
+ cs47l15->in1_lp_mode = true;
+ break;
+ }
+
+ return 0;
+}
+
static const struct snd_kcontrol_new cs47l15_snd_controls[] = {
SOC_ENUM("IN1 OSR", madera_in_dmic_osr[0]),
SOC_ENUM("IN2 OSR", madera_in_dmic_osr[1]),
SOC_ENUM_EXT("IN1R Rate", madera_input_rate[1],
snd_soc_get_enum_double, madera_in_rate_put),
+SOC_SINGLE_BOOL_EXT("IN1 LP Mode Switch", 0,
+ cs47l15_in1_adc_get, cs47l15_in1_adc_put),
+
SOC_ENUM_EXT("IN2L Rate", madera_input_rate[2],
snd_soc_get_enum_double, madera_in_rate_put),
SOC_ENUM_EXT("IN2R Rate", madera_input_rate[3],