[PATCH] ASoC: tlv320aic3x: add dmic widget support
This patch allows to use dmic to record sound.
This is a port from a variscite patch written by Eran Matityahu eran.m@variscite.com.
Signed-off-by: Gregory CLEMENT gregory.clement@bootlin.com --- sound/soc/codecs/tlv320aic3x.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index d53037b1509d..426f92cc44da 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -296,6 +296,11 @@ static SOC_ENUM_SINGLE_DECL(aic3x_poweron_time_enum, HPOUT_POP_REDUCTION, 4, static const char * const aic3x_rampup_step[] = { "0ms", "1ms", "2ms", "4ms" }; static SOC_ENUM_SINGLE_DECL(aic3x_rampup_step_enum, HPOUT_POP_REDUCTION, 2, aic3x_rampup_step); +static const char * const aic3x_dmic_rates[] = { "off", "128x", "64x", "32x" }; +static SOC_ENUM_SINGLE_DECL(aic3x_dmic_rates_enum, AIC3X_ASD_INTF_CTRLA, 0, + aic3x_dmic_rates); +static const struct snd_kcontrol_new aic3x_dmic_rates_controls = + SOC_DAPM_ENUM("Route", aic3x_dmic_rates_enum);
/* * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps @@ -751,6 +756,9 @@ static const struct snd_soc_dapm_widget aic3x_extra_dapm_widgets[] = { SND_SOC_DAPM_INPUT("MIC3R"), SND_SOC_DAPM_INPUT("LINE2L"), SND_SOC_DAPM_INPUT("LINE2R"), + + SND_SOC_DAPM_MUX("DMic Rate", SND_SOC_NOPM, 0, 0, &aic3x_dmic_rates_controls), + SND_SOC_DAPM_INPUT("DMIC"), };
/* For tlv320aic3104 */ @@ -939,6 +947,12 @@ static const struct snd_soc_dapm_route intercon_extra[] = { {"GPIO1 dmic modclk", NULL, "DMic Rate 64"}, {"GPIO1 dmic modclk", NULL, "DMic Rate 32"},
+ {"GPIO1 dmic modclk", NULL, "DMic Rate"}, + {"DMic Rate", "128x", "DMIC"}, + {"DMic Rate", "64x", "DMIC"}, + {"DMic Rate", "32x", "DMIC"}, + {"DMic Rate", "off", "DMIC"}, + /* Left Line Output */ {"Left Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"}, {"Left Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
On Fri, Mar 11, 2022 at 11:06:27AM +0100, Gregory CLEMENT wrote:
+static const char * const aic3x_dmic_rates[] = { "off", "128x", "64x", "32x" }; +static SOC_ENUM_SINGLE_DECL(aic3x_dmic_rates_enum, AIC3X_ASD_INTF_CTRLA, 0,
aic3x_dmic_rates);
+static const struct snd_kcontrol_new aic3x_dmic_rates_controls =
- SOC_DAPM_ENUM("Route", aic3x_dmic_rates_enum);
...
- {"GPIO1 dmic modclk", NULL, "DMic Rate"},
- {"DMic Rate", "128x", "DMIC"},
- {"DMic Rate", "64x", "DMIC"},
- {"DMic Rate", "32x", "DMIC"},
- {"DMic Rate", "off", "DMIC"},
This isn't really idiomatic and won't be power efficient since we don't automatically manage the power so we'll have the DMIC clock running even when no recording is in progress. What would be better would be to have an enum equivalent of the _AUTODISABLE() controls, providing an enum with the clock rates backed by a field in the driver data and then a DAPM widget which writes the value to the hardware when the widget is enabled and sets it back to off on disable. It'd be fine to open code that in the driver for now rather than actually implementing a generic thing if that's too much hassle.
Hello Mark,
On Fri, Mar 11, 2022 at 11:06:27AM +0100, Gregory CLEMENT wrote:
+static const char * const aic3x_dmic_rates[] = { "off", "128x", "64x", "32x" }; +static SOC_ENUM_SINGLE_DECL(aic3x_dmic_rates_enum, AIC3X_ASD_INTF_CTRLA, 0,
aic3x_dmic_rates);
+static const struct snd_kcontrol_new aic3x_dmic_rates_controls =
- SOC_DAPM_ENUM("Route", aic3x_dmic_rates_enum);
...
- {"GPIO1 dmic modclk", NULL, "DMic Rate"},
- {"DMic Rate", "128x", "DMIC"},
- {"DMic Rate", "64x", "DMIC"},
- {"DMic Rate", "32x", "DMIC"},
- {"DMic Rate", "off", "DMIC"},
This isn't really idiomatic and won't be power efficient since we don't automatically manage the power so we'll have the DMIC clock running even when no recording is in progress. What would be better would be to have an enum equivalent of the _AUTODISABLE() controls, providing an enum with the clock rates backed by a field in the driver data and then a DAPM widget which writes the value to the hardware when the widget is enabled and sets it back to off on disable. It'd be fine to open code that in the driver for now rather than actually implementing a generic thing if that's too much hassle.
Thanks for tour feedback, I will work on a second version based on this.
Gregory
participants (2)
-
Gregory CLEMENT
-
Mark Brown