diff mbox series

ASoC: tlv320adcx140: Add controls for PDM clk and edge

Message ID 20200513144746.14337-1-dmurphy@ti.com (mailing list archive)
State New, archived
Headers show
Series ASoC: tlv320adcx140: Add controls for PDM clk and edge | expand

Commit Message

Dan Murphy May 13, 2020, 2:47 p.m. UTC
Add ALSA controls to configure the PDM clock and PDM input edges for the
4 digital mic inputs.

Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
 sound/soc/codecs/tlv320adcx140.c | 74 +++++++++++++++++++++++++++++---
 1 file changed, 69 insertions(+), 5 deletions(-)

Comments

Mark Brown May 13, 2020, 3:32 p.m. UTC | #1
On Wed, May 13, 2020 at 09:47:46AM -0500, Dan Murphy wrote:

> +static const char * const pdmclk_text[] = {
> +	"2.8224 MHz", "1.4112 MHz", "705.6 kHz", "5.6448 MHz"
> +};
> +
> +static SOC_ENUM_SINGLE_DECL(pdmclk_select_enum, ADCX140_PDMCLK_CFG, 0,
> +			    pdmclk_text);
> +
> +static const struct snd_kcontrol_new pdmclk_div_controls[] = {
> +	SOC_DAPM_ENUM("PDM Clk Divider Select", pdmclk_select_enum),
> +};
> +
> +static const char * const pdm_edge_text[] = {
> +	"Negative", "Positive"
> +};

Are these (especially the clock and polarity) things that are going to
vary at runtime?  I'd have expected these to come from the hardware
rather than being something that could usefully change.
Dan Murphy May 13, 2020, 5:16 p.m. UTC | #2
Mark

On 5/13/20 10:32 AM, Mark Brown wrote:
> On Wed, May 13, 2020 at 09:47:46AM -0500, Dan Murphy wrote:
>
>> +static const char * const pdmclk_text[] = {
>> +	"2.8224 MHz", "1.4112 MHz", "705.6 kHz", "5.6448 MHz"
>> +};
>> +
>> +static SOC_ENUM_SINGLE_DECL(pdmclk_select_enum, ADCX140_PDMCLK_CFG, 0,
>> +			    pdmclk_text);
>> +
>> +static const struct snd_kcontrol_new pdmclk_div_controls[] = {
>> +	SOC_DAPM_ENUM("PDM Clk Divider Select", pdmclk_select_enum),
>> +};
>> +
>> +static const char * const pdm_edge_text[] = {
>> +	"Negative", "Positive"
>> +};
> Are these (especially the clock and polarity) things that are going to
> vary at runtime?  I'd have expected these to come from the hardware
> rather than being something that could usefully change.
Some microphone support low power modes that use a slower clock.
Polarity will probably not change at run-time, but clock speed can 
change to move mics from low power/low-resolution to higher 
power/high-resolution mode.

So polarity can be made hardware specific but clocks should be configurable.

I can break these out into separate patches if you want.

Dan
Mark Brown May 13, 2020, 5:32 p.m. UTC | #3
On Wed, May 13, 2020 at 12:16:03PM -0500, Dan Murphy wrote:
> On 5/13/20 10:32 AM, Mark Brown wrote:

> > Are these (especially the clock and polarity) things that are going to
> > vary at runtime?  I'd have expected these to come from the hardware
> > rather than being something that could usefully change.

> Some microphone support low power modes that use a slower clock.
> Polarity will probably not change at run-time, but clock speed can change to
> move mics from low power/low-resolution to higher power/high-resolution
> mode.

> So polarity can be made hardware specific but clocks should be configurable.

> I can break these out into separate patches if you want.

Please, and make the bits that can't usefully vary DT properties.
diff mbox series

Patch

diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c
index 0f713efde046..e860d3c62d64 100644
--- a/sound/soc/codecs/tlv320adcx140.c
+++ b/sound/soc/codecs/tlv320adcx140.c
@@ -180,6 +180,49 @@  static const struct snd_kcontrol_new decimation_filter_controls[] = {
 	SOC_DAPM_ENUM("Decimation Filter", decimation_filter_enum),
 };
 
+static const char * const pdmclk_text[] = {
+	"2.8224 MHz", "1.4112 MHz", "705.6 kHz", "5.6448 MHz"
+};
+
+static SOC_ENUM_SINGLE_DECL(pdmclk_select_enum, ADCX140_PDMCLK_CFG, 0,
+			    pdmclk_text);
+
+static const struct snd_kcontrol_new pdmclk_div_controls[] = {
+	SOC_DAPM_ENUM("PDM Clk Divider Select", pdmclk_select_enum),
+};
+
+static const char * const pdm_edge_text[] = {
+	"Negative", "Positive"
+};
+
+static SOC_ENUM_SINGLE_DECL(pdm1edge_select_enum, ADCX140_PDM_CFG, 7,
+			    pdm_edge_text);
+
+static SOC_ENUM_SINGLE_DECL(pdm2edge_select_enum, ADCX140_PDM_CFG, 6,
+			    pdm_edge_text);
+
+static SOC_ENUM_SINGLE_DECL(pdm3edge_select_enum, ADCX140_PDM_CFG, 5,
+			    pdm_edge_text);
+
+static SOC_ENUM_SINGLE_DECL(pdm4edge_select_enum, ADCX140_PDM_CFG, 4,
+			    pdm_edge_text);
+
+static const struct snd_kcontrol_new pdmin1_edge_controls[] = {
+	SOC_DAPM_ENUM("PDMIN1 Edge Select", pdm1edge_select_enum),
+};
+
+static const struct snd_kcontrol_new pdmin2_edge_controls[] = {
+	SOC_DAPM_ENUM("PDMIN2 Edge Select", pdm2edge_select_enum),
+};
+
+static const struct snd_kcontrol_new pdmin3_edge_controls[] = {
+	SOC_DAPM_ENUM("PDMIN3 Edge Select", pdm3edge_select_enum),
+};
+
+static const struct snd_kcontrol_new pdmin4_edge_controls[] = {
+	SOC_DAPM_ENUM("PDMIN4 Edge Select", pdm4edge_select_enum),
+};
+
 static const char * const resistor_text[] = {
 	"2.5 kOhm", "10 kOhm", "20 kOhm"
 };
@@ -416,6 +459,18 @@  static const struct snd_soc_dapm_widget adcx140_dapm_widgets[] = {
 	SND_SOC_DAPM_MUX("IN4 Analog Mic Resistor", SND_SOC_NOPM, 0, 0,
 			in4_resistor_controls),
 
+	SND_SOC_DAPM_MUX("PDM Clk Div Select", SND_SOC_NOPM, 0, 0,
+			pdmclk_div_controls),
+
+	SND_SOC_DAPM_MUX("PDMIN1 Edge Select", SND_SOC_NOPM, 0, 0,
+			pdmin1_edge_controls),
+	SND_SOC_DAPM_MUX("PDMIN2 Edge Select", SND_SOC_NOPM, 0, 0,
+			pdmin2_edge_controls),
+	SND_SOC_DAPM_MUX("PDMIN3 Edge Select", SND_SOC_NOPM, 0, 0,
+			pdmin3_edge_controls),
+	SND_SOC_DAPM_MUX("PDMIN4 Edge Select", SND_SOC_NOPM, 0, 0,
+			pdmin4_edge_controls),
+
 	SND_SOC_DAPM_MUX("Decimation Filter", SND_SOC_NOPM, 0, 0,
 			decimation_filter_controls),
 };
@@ -493,6 +548,20 @@  static const struct snd_soc_dapm_route adcx140_audio_map[] = {
 	{"IN4 Analog Mic Resistor", "10 kOhm", "MIC4M Input Mux"},
 	{"IN4 Analog Mic Resistor", "20 kOhm", "MIC4M Input Mux"},
 
+	{"PDM Clk Div Select", "2.8224 MHz", "MIC1P Input Mux"},
+	{"PDM Clk Div Select", "1.4112 MHz", "MIC1P Input Mux"},
+	{"PDM Clk Div Select", "705.6 kHz", "MIC1P Input Mux"},
+	{"PDM Clk Div Select", "5.6448 MHz", "MIC1P Input Mux"},
+
+	{"PDMIN1 Edge Select", "Negative", "MIC1P Input Mux"},
+	{"PDMIN1 Edge Select", "Positive", "MIC1P Input Mux"},
+	{"PDMIN2 Edge Select", "Negative", "MIC2P Input Mux"},
+	{"PDMIN2 Edge Select", "Positive", "MIC2P Input Mux"},
+	{"PDMIN3 Edge Select", "Negative", "MIC3P Input Mux"},
+	{"PDMIN3 Edge Select", "Positive", "MIC3P Input Mux"},
+	{"PDMIN4 Edge Select", "Negative", "MIC4P Input Mux"},
+	{"PDMIN4 Edge Select", "Positive", "MIC4P Input Mux"},
+
 	{"MIC1 Analog Mux", "Line In", "MIC1P"},
 	{"MIC2 Analog Mux", "Line In", "MIC2P"},
 	{"MIC3 Analog Mux", "Line In", "MIC3P"},
@@ -675,11 +744,6 @@  static int adcx140_set_dai_tdm_slot(struct snd_soc_dai *codec_dai,
 	struct adcx140_priv *adcx140 = snd_soc_component_get_drvdata(component);
 	unsigned int lsb;
 
-	if (tx_mask != rx_mask) {
-		dev_err(component->dev, "tx and rx masks must be symmetric\n");
-		return -EINVAL;
-	}
-
 	/* TDM based on DSP mode requires slots to be adjacent */
 	lsb = __ffs(tx_mask);
 	if ((lsb + 1) != __fls(tx_mask)) {