devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/5] ASoC: wm8904: Add DMIC and DRC support
@ 2025-03-07 13:52 Francesco Dolcini
  2025-03-07 13:52 ` [PATCH v3 1/5] of: Add of_property_read_u16_index Francesco Dolcini
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Francesco Dolcini @ 2025-03-07 13:52 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, Jaroslav Kysela, Takashi Iwai,
	patches
  Cc: Francesco Dolcini, linux-sound, devicetree, linux-kernel

From: Francesco Dolcini <francesco.dolcini@toradex.com>

This patch series adds DMIC and DRC support to the WM8904 driver, a new
of_ helper is added to simplify the driver code.

DRC functionality is added in the same patch series to provide the
necessary dynamic range control to make DMIC support useful.

The WM8904 supports digital microphones on two of its inputs:
IN1L/DMICDAT1 and IN1R/DMICDAT2. These two inputs can either be
connected to an ADC or to the DMIC system. There is an ADC for each
line, and only one DMIC block. This DMIC block is either connected to
DMICDAT1 or to DMICDAT2. One DMIC data line supports two digital
microphones via time multiplexing.

The pin's functionality is decided during hardware design (IN1L vs
DMICDAT1 and IN1R vs DMICDAT2). This is reflected in the Device Tree.

If one line is analog and one is DMIC, we need to be able to switch
between ADC and DMIC at runtime. The DMIC source is known from the
Device Tree. If both are DMIC inputs, we need to be able to switch the
DMIC source. There is no need to switch between ADC and DMIC at runtime.

Therefore, kcontrols are dynamically added by the driver depending on
its Device Tree configuration.

This is a heavy rework of a previous patch series provided by Alifer
Moraes and Pierluigi Passaro,
https://lore.kernel.org/lkml/20220307141041.27538-1-alifer.m@variscite.com.

v3:
 * Fixed DT binding to conform to the DT schema properly.
 * Renamed "wlf,retune-mobile-cfg-rates" to "wlf,retune-mobile-cfg-hz", it is now a standard unit suffix property.

v2: https://lore.kernel.org/all/20250224155500.52462-1-francesco@dolcini.it/
 * Fixed a bug in wm8904_parse_retune_cfg_from_of()
 * Added full usage example of the three ReTune Mobile config properties in the
   DT binding.
 * Improved the DAPM routing:
   * Only add IN1L/IN1R routes to ADCL/ADCR conditionally depending on which
     DMIC is in use.
   * Do not connect PGAs to ADC when they are not needed.
   * Keep the mux between ADC/DMIC even when two DMICs are used, as the IN1
     pins share a mux with IN2 and IN3 and the ADC could still be used for
     them.

v1: https://lore.kernel.org/all/20250206163152.423199-1-francesco@dolcini.it/

Ernest Van Hoecke (5):
  of: Add of_property_read_u16_index
  ASoC: wm8904: Don't touch GPIO configs set to 0xFFFF
  ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support
  ASoC: wm8904: get platform data from DT
  ASoC: wm8904: add DMIC support

 .../devicetree/bindings/sound/wlf,wm8904.yaml | 116 +++++++
 drivers/of/property.c                         |  33 ++
 include/linux/of.h                            |   9 +
 include/sound/wm8904.h                        |   3 +
 sound/soc/codecs/wm8904.c                     | 317 +++++++++++++++++-
 5 files changed, 471 insertions(+), 7 deletions(-)

-- 
2.39.5


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 1/5] of: Add of_property_read_u16_index
  2025-03-07 13:52 [PATCH v3 0/5] ASoC: wm8904: Add DMIC and DRC support Francesco Dolcini
@ 2025-03-07 13:52 ` Francesco Dolcini
  2025-03-07 13:52 ` [PATCH v3 2/5] ASoC: wm8904: Don't touch GPIO configs set to 0xFFFF Francesco Dolcini
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Francesco Dolcini @ 2025-03-07 13:52 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, Jaroslav Kysela, Takashi Iwai,
	patches
  Cc: Ernest Van Hoecke, linux-sound, devicetree, linux-kernel,
	Francesco Dolcini, Charles Keepax

From: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>

There is an of_property_read_u32_index and of_property_read_u64_index.
This patch adds a similar helper for u16.

Signed-off-by: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>
Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
v3: no changes
v2: no changes
v1: https://lore.kernel.org/lkml/20250206163152.423199-2-francesco@dolcini.it/
---
 drivers/of/property.c | 33 +++++++++++++++++++++++++++++++++
 include/linux/of.h    |  9 +++++++++
 2 files changed, 42 insertions(+)

diff --git a/drivers/of/property.c b/drivers/of/property.c
index 208d922cc24c..c1feb631e383 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -147,6 +147,39 @@ static void *of_find_property_value_of_size(const struct device_node *np,
 	return prop->value;
 }
 
+/**
+ * of_property_read_u16_index - Find and read a u16 from a multi-value property.
+ *
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @index:	index of the u16 in the list of values
+ * @out_value:	pointer to return value, modified only if no error.
+ *
+ * Search for a property in a device node and read nth 16-bit value from
+ * it.
+ *
+ * Return: 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * property data isn't large enough.
+ *
+ * The out_value is modified only if a valid u16 value can be decoded.
+ */
+int of_property_read_u16_index(const struct device_node *np,
+				       const char *propname,
+				       u32 index, u16 *out_value)
+{
+	const u16 *val = of_find_property_value_of_size(np, propname,
+					((index + 1) * sizeof(*out_value)),
+					0, NULL);
+
+	if (IS_ERR(val))
+		return PTR_ERR(val);
+
+	*out_value = be16_to_cpup(((__be16 *)val) + index);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_property_read_u16_index);
+
 /**
  * of_property_read_u32_index - Find and read a u32 from a multi-value property.
  *
diff --git a/include/linux/of.h b/include/linux/of.h
index eaf0e2a2b75c..5e52d90f6408 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -314,6 +314,9 @@ extern struct property *of_find_property(const struct device_node *np,
 extern bool of_property_read_bool(const struct device_node *np, const char *propname);
 extern int of_property_count_elems_of_size(const struct device_node *np,
 				const char *propname, int elem_size);
+extern int of_property_read_u16_index(const struct device_node *np,
+				       const char *propname,
+				       u32 index, u16 *out_value);
 extern int of_property_read_u32_index(const struct device_node *np,
 				       const char *propname,
 				       u32 index, u32 *out_value);
@@ -627,6 +630,12 @@ static inline int of_property_count_elems_of_size(const struct device_node *np,
 	return -ENOSYS;
 }
 
+static inline int of_property_read_u16_index(const struct device_node *np,
+			const char *propname, u32 index, u16 *out_value)
+{
+	return -ENOSYS;
+}
+
 static inline int of_property_read_u32_index(const struct device_node *np,
 			const char *propname, u32 index, u32 *out_value)
 {
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 2/5] ASoC: wm8904: Don't touch GPIO configs set to 0xFFFF
  2025-03-07 13:52 [PATCH v3 0/5] ASoC: wm8904: Add DMIC and DRC support Francesco Dolcini
  2025-03-07 13:52 ` [PATCH v3 1/5] of: Add of_property_read_u16_index Francesco Dolcini
@ 2025-03-07 13:52 ` Francesco Dolcini
  2025-03-07 13:52 ` [PATCH v3 3/5] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support Francesco Dolcini
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Francesco Dolcini @ 2025-03-07 13:52 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, Jaroslav Kysela, Takashi Iwai,
	patches
  Cc: Ernest Van Hoecke, linux-sound, devicetree, linux-kernel,
	Francesco Dolcini, Charles Keepax

From: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>

When updating the GPIO registers, do nothing for all fields of gpio_cfg
that are "0xFFFF".

This "do nothing" flag used to be 0 to easily check whether the gpio_cfg
field was actually set inside pdata or left empty (default).

However, 0 is a valid configuration for these registers, while 0xFFFF is
not.

With this change, users can explicitly set them to 0.
Not setting gpio_cfg in the platform data will now lead to setting all
GPIO registers to 0 instead of leaving them unset.

No one is using this platform data with this codec.

The change gets the driver ready to properly set gpio_cfg from the DT.

Datasheet: https://statics.cirrus.com/pubs/proDatasheet/WM8904_Rev4.1.pdf
Signed-off-by: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>
Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
v3: no changes
v2: no changes
v1: https://lore.kernel.org/lkml/20250206163152.423199-3-francesco@dolcini.it/
---
 sound/soc/codecs/wm8904.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index aef82532f8cf..2082ff12d336 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -2270,7 +2270,8 @@ static int wm8904_i2c_probe(struct i2c_client *i2c)
 	/* Apply configuration from the platform data. */
 	if (wm8904->pdata) {
 		for (i = 0; i < WM8904_GPIO_REGS; i++) {
-			if (!wm8904->pdata->gpio_cfg[i])
+			/* 0xFFFF in this config means "don't touch" */
+			if (wm8904->pdata->gpio_cfg[i] == 0xffff)
 				continue;
 
 			regmap_update_bits(wm8904->regmap,
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 3/5] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support
  2025-03-07 13:52 [PATCH v3 0/5] ASoC: wm8904: Add DMIC and DRC support Francesco Dolcini
  2025-03-07 13:52 ` [PATCH v3 1/5] of: Add of_property_read_u16_index Francesco Dolcini
  2025-03-07 13:52 ` [PATCH v3 2/5] ASoC: wm8904: Don't touch GPIO configs set to 0xFFFF Francesco Dolcini
@ 2025-03-07 13:52 ` Francesco Dolcini
  2025-03-11  8:42   ` Krzysztof Kozlowski
  2025-03-12  8:41   ` Krzysztof Kozlowski
  2025-03-07 13:52 ` [PATCH v3 4/5] ASoC: wm8904: get platform data from DT Francesco Dolcini
  2025-03-07 13:52 ` [PATCH v3 5/5] ASoC: wm8904: add DMIC support Francesco Dolcini
  4 siblings, 2 replies; 12+ messages in thread
From: Francesco Dolcini @ 2025-03-07 13:52 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, Jaroslav Kysela, Takashi Iwai,
	patches
  Cc: Ernest Van Hoecke, linux-sound, devicetree, linux-kernel,
	Francesco Dolcini, Charles Keepax

From: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>

Add two properties to select the IN1L/DMICDAT1 and IN2R/DMICDAT2
functionality:
- wlf,in1l-as-dmicdat1
- wlf,in1r-as-dmicdat2

Add a property to describe the GPIO configuration registers, that can be
used to set the four multifunction pins:
- wlf,gpio-cfg

Add a property to describe the mic bias control registers:
- wlf,mic-cfg

Add two properties to describe the Dynamic Range Controller (DRC),
allowing multiple named configurations where each config sets the 4 DRC
registers (R40-R43):
- wlf,drc-cfg-regs
- wlf,drc-cfg-names

Add three properties to describe the equalizer (ReTune Mobile), allowing
multiple named configurations (associated with a samplerate) that set
the 24 (R134-R157) EQ registers:
- wlf,retune-mobile-cfg-regs
- wlf,retune-mobile-cfg-hz
- wlf,retune-mobile-cfg-rates

Datasheet: https://statics.cirrus.com/pubs/proDatasheet/WM8904_Rev4.1.pdf
Signed-off-by: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>
Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
v3: v2 did not pass dt_binding_check, this is now fixed.
    Fixed a DT compilation error by moving a misplaced closing bracket.
    Changed 'retune-mobile-cfg-names' to be a nonunique-string-array.
    Renamed 'retune-mobile-cfg-rates' to 'retune-mobile-cfg-hz',
        dropped the 'ref' because it is now a standard unit suffix prop.
    Redid line wrapping to be compliant with the DTS style guidelines.
v2: Added an example of how to use the ReTune Mobile config properties
v1: https://lore.kernel.org/lkml/20250206163152.423199-4-francesco@dolcini.it/
---
 .../devicetree/bindings/sound/wlf,wm8904.yaml | 116 ++++++++++++++++++
 1 file changed, 116 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8904.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8904.yaml
index 329260cf0fa0..4ad8681cb266 100644
--- a/Documentation/devicetree/bindings/sound/wlf,wm8904.yaml
+++ b/Documentation/devicetree/bindings/sound/wlf,wm8904.yaml
@@ -38,6 +38,72 @@ properties:
   DCVDD-supply: true
   MICVDD-supply: true
 
+  wlf,in1l-as-dmicdat1:
+    type: boolean
+    description:
+      Use IN1L/DMICDAT1 as DMICDAT1, enabling the DMIC input path.
+
+  wlf,in1r-as-dmicdat2:
+    type: boolean
+    description:
+      Use IN1R/DMICDAT2 as DMICDAT2, enabling the DMIC input path.
+
+  wlf,gpio-cfg:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    minItems: 4
+    maxItems: 4
+    description:
+      Default register values for R121/122/123/124 (GPIO Control).
+      If any entry has the value 0xFFFF, the related register won't be set.
+    default: [0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF]
+
+  wlf,mic-cfg:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    minItems: 2
+    maxItems: 2
+    description:
+      Default register values for R6/R7 (Mic Bias Control).
+    default: [0, 0]
+
+  wlf,drc-cfg-names:
+    $ref: /schemas/types.yaml#/definitions/string-array
+    description:
+      List of strings for the available DRC modes.
+      If absent, DRC is disabled.
+
+  wlf,drc-cfg-regs:
+    $ref: /schemas/types.yaml#/definitions/uint16-array
+    description:
+      Default register values for R40/41/42/43 (DRC).
+      The list must be 4 times the length of wlf,drc-cfg-names.
+      If absent, DRC is disabled.
+
+  wlf,retune-mobile-cfg-names:
+    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+    description:
+      List of strings for the available retune modes.
+      If absent, retune is disabled.
+
+  wlf,retune-mobile-cfg-hz:
+    description:
+      The list must be the same length as wlf,retune-mobile-cfg-names.
+      If absent, retune is disabled.
+
+  wlf,retune-mobile-cfg-regs:
+    $ref: /schemas/types.yaml#/definitions/uint16-array
+    description:
+      Default register values for R134/.../157 (EQ).
+      The list must be 24 times the length of wlf,retune-mobile-cfg-names.
+      If absent, retune is disabled.
+
+dependencies:
+  wlf,drc-cfg-names: [ 'wlf,drc-cfg-regs' ]
+  wlf,drc-cfg-regs: [ 'wlf,drc-cfg-names' ]
+
+  wlf,retune-mobile-cfg-names: [ 'wlf,retune-mobile-cfg-hz', 'wlf,retune-mobile-cfg-regs' ]
+  wlf,retune-mobile-cfg-regs: [ 'wlf,retune-mobile-cfg-names', 'wlf,retune-mobile-cfg-hz' ]
+  wlf,retune-mobile-cfg-hz: [ 'wlf,retune-mobile-cfg-names', 'wlf,retune-mobile-cfg-regs' ]
+
 required:
   - compatible
   - reg
@@ -70,5 +136,55 @@ examples:
             DBVDD-supply = <&reg_1p8v>;
             DCVDD-supply = <&reg_1p8v>;
             MICVDD-supply = <&reg_1p8v>;
+
+            wlf,drc-cfg-names = "default", "peaklimiter", "tradition", "soft",
+                                "music";
+            /*
+             * Config registers per name, respectively:
+             * KNEE_IP = 0,   KNEE_OP = 0,     HI_COMP = 1,   LO_COMP = 1
+             * KNEE_IP = -24, KNEE_OP = -6,    HI_COMP = 1/4, LO_COMP = 1
+             * KNEE_IP = -42, KNEE_OP = -3,    HI_COMP = 0,   LO_COMP = 1
+             * KNEE_IP = -45, KNEE_OP = -9,    HI_COMP = 1/8, LO_COMP = 1
+             * KNEE_IP = -30, KNEE_OP = -10.5, HI_COMP = 1/4, LO_COMP = 1
+             */
+            wlf,drc-cfg-regs = /bits/ 16 <0x01af 0x3248 0x0000 0x0000>,
+                               /bits/ 16 <0x04af 0x324b 0x0010 0x0408>,
+                               /bits/ 16 <0x04af 0x324b 0x0028 0x0704>,
+                               /bits/ 16 <0x04af 0x324b 0x0018 0x078c>,
+                               /bits/ 16 <0x04af 0x324b 0x0010 0x050e>;
+
+            /* GPIO1 = DMIC_CLK, don't touch others */
+            wlf,gpio-cfg = <0x0018 0xffff 0xffff 0xffff>;
+
+            wlf,retune-mobile-cfg-names = "bassboost", "bassboost", "treble";
+            wlf,retune-mobile-cfg-hz = <48000 44100 48000>;
+            /*
+             * Config registers per name, respectively:
+             * EQ_ENA,  100 Hz,  300 Hz,  875 Hz, 2400 Hz, 6900 Hz
+             *      1,   +6 dB,   +3 dB,    0 dB,    0 dB,    0 dB
+             *      1,   +6 dB,   +3 dB,    0 dB,    0 dB,    0 dB
+             *      1,   -2 dB,   -2 dB,    0 dB,    0 dB,   +3 dB
+             * Each one uses the defaults for ReTune Mobile registers 140-157
+             */
+            wlf,retune-mobile-cfg-regs = /bits/ 16 <0x1 0x12 0xf 0xc 0xc 0xc>,
+                                         /bits/ 16 <0x0fca 0x0400 0x00d8 0x1eb5
+                                                    0xf145 0x0bd5 0x0075 0x1c58
+                                                    0xf3d3 0x0a54 0x0568 0x168e
+                                                    0xf829 0x07ad 0x1103 0x0564
+                                                    0x0559 0x4000>,
+
+                                         /bits/ 16 <0x1 0x12 0xf 0xc 0xc 0xc>,
+                                         /bits/ 16 <0x0fca 0x0400 0x00d8 0x1eb5
+                                                    0xf145 0x0bd5 0x0075 0x1c58
+                                                    0xf3d3 0x0a54 0x0568 0x168e
+                                                    0xf829 0x07ad 0x1103 0x0564
+                                                    0x0559 0x4000>,
+
+                                         /bits/ 16 <0x1 0xa 0xa 0xc 0xc 0xf>,
+                                         /bits/ 16 <0x0fca 0x0400 0x00d8 0x1eb5
+                                                    0xf145 0x0bd5 0x0075 0x1c58
+                                                    0xf3d3 0x0a54 0x0568 0x168e
+                                                    0xf829 0x07ad 0x1103 0x0564
+                                                    0x0559 0x4000>;
         };
     };
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 4/5] ASoC: wm8904: get platform data from DT
  2025-03-07 13:52 [PATCH v3 0/5] ASoC: wm8904: Add DMIC and DRC support Francesco Dolcini
                   ` (2 preceding siblings ...)
  2025-03-07 13:52 ` [PATCH v3 3/5] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support Francesco Dolcini
@ 2025-03-07 13:52 ` Francesco Dolcini
  2025-03-07 13:52 ` [PATCH v3 5/5] ASoC: wm8904: add DMIC support Francesco Dolcini
  4 siblings, 0 replies; 12+ messages in thread
From: Francesco Dolcini @ 2025-03-07 13:52 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, Jaroslav Kysela, Takashi Iwai,
	patches
  Cc: Ernest Van Hoecke, linux-sound, devicetree, linux-kernel,
	Francesco Dolcini, Charles Keepax

From: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>

Read in optional codec-specific properties from the device tree.

The platform_data structure is not populated when using device trees.
This change parses optional dts properties to populate it.

- wlf,in1l-as-dmicdat1
- wlf,in1r-as-dmicdat2
- wlf,gpio-cfg
- wlf,mic-cfg
- wlf,drc-cfg-regs
- wlf,drc-cfg-names
- wlf,retune-mobile-cfg-regs
- wlf,retune-mobile-cfg-names
- wlf,retune-mobile-cfg-hz

Datasheet: https://statics.cirrus.com/pubs/proDatasheet/WM8904_Rev4.1.pdf
Signed-off-by: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>
Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
v3: Renamed "wlf,retune-mobile-cfg-rates" to "wlf,retune-mobile-cfg-hz"
v2: Fixed wm8904_parse_retune_cfg_from_of: refer to
    pdata->retune_mobile_cfgs[i].name instead of pdata->drc_cfgs[i].name
v1: https://lore.kernel.org/lkml/20250206163152.423199-5-francesco@dolcini.it/
---
 include/sound/wm8904.h    |   3 +
 sound/soc/codecs/wm8904.c | 189 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 191 insertions(+), 1 deletion(-)

diff --git a/include/sound/wm8904.h b/include/sound/wm8904.h
index 88ac1870510e..8b2c16b524f7 100644
--- a/include/sound/wm8904.h
+++ b/include/sound/wm8904.h
@@ -151,6 +151,9 @@ struct wm8904_pdata {
 	int num_retune_mobile_cfgs;
 	struct wm8904_retune_mobile_cfg *retune_mobile_cfgs;
 
+	bool in1l_as_dmicdat1;
+	bool in1r_as_dmicdat2;
+
 	u32 gpio_cfg[WM8904_GPIO_REGS];
 	u32 mic_cfg[WM8904_MIC_REGS];
 };
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 2082ff12d336..8a2b98745964 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -2168,6 +2168,184 @@ static const struct of_device_id wm8904_of_match[] = {
 MODULE_DEVICE_TABLE(of, wm8904_of_match);
 #endif
 
+/**
+ * wm8904_read_cfg_reg_arr() - Reads a subarray from a DT u16 array
+ *
+ * @np: pointer to the device_node struct
+ * @regs_property: DT property of interest
+ * @size: size of subarrays within the array
+ * @idx: index of the subarray of interest
+ * @out: output
+ *
+ * Helper to read a subarray from a DT uint16-array,
+ *  divided into equally sized arrays of size `size`
+ *
+ * Subset starts at `idx * size` and is of size `size`
+ *
+ * Return: 0 on success, negative error code otherwise
+ */
+static int wm8904_read_cfg_reg_arr(const struct device_node *np,
+				   const char * const regs_property,
+				   int size, int idx,
+				   u16 * const out)
+{
+	int i, offset, ret;
+
+	offset = idx * size;
+
+	for (i = 0; i < size; i++) {
+		ret = of_property_read_u16_index(np, regs_property, i + offset, &out[i]);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
+static int wm8904_parse_retune_cfg_regs(const struct device_node *np,
+					struct wm8904_pdata *pdata, int cfg_idx)
+{
+	return wm8904_read_cfg_reg_arr(np, "wlf,retune-mobile-cfg-regs",
+				       WM8904_EQ_REGS, cfg_idx,
+				       &pdata->retune_mobile_cfgs[cfg_idx].regs[0]);
+}
+
+static int wm8904_parse_drc_cfg_regs(const struct device_node *np,
+				     struct wm8904_pdata *pdata, int cfg_idx)
+{
+	return wm8904_read_cfg_reg_arr(np, "wlf,drc-cfg-regs",
+				       WM8904_DRC_REGS, cfg_idx,
+				       &pdata->drc_cfgs[cfg_idx].regs[0]);
+}
+
+static int wm8904_parse_drc_cfg_from_of(struct i2c_client *i2c,
+					struct wm8904_pdata *pdata)
+{
+	const struct device_node *np = i2c->dev.of_node;
+	int i, n_cfgs;
+
+	n_cfgs = of_property_count_strings(np, "wlf,drc-cfg-names");
+	if (n_cfgs == -EINVAL)
+		return 0;
+
+	if (n_cfgs <= 0) {
+		dev_err(&i2c->dev, "Could not get wlf,drc-cfg-names length: %d",
+			n_cfgs);
+		return n_cfgs;
+	}
+
+	pdata->drc_cfgs = devm_kzalloc(&i2c->dev,
+				       n_cfgs * sizeof(struct wm8904_drc_cfg),
+				       GFP_KERNEL);
+	if (!pdata->drc_cfgs)
+		return -ENOMEM;
+
+	for (i = 0; i < n_cfgs; i++) {
+		if (wm8904_parse_drc_cfg_regs(np, pdata, i)) {
+			dev_err(&i2c->dev,
+				"Invalid 'wlf,drc-cfg-regs[%i,:]'\n", i);
+			return -EINVAL;
+		}
+
+		if (of_property_read_string_index(np, "wlf,drc-cfg-names", i,
+						  &pdata->drc_cfgs[i].name)) {
+			dev_err(&i2c->dev,
+				"Invalid 'wlf,drc-cfg-names[%i]'\n", i);
+			return -EINVAL;
+		}
+	}
+
+	pdata->num_drc_cfgs = n_cfgs;
+	return 0;
+}
+
+static int wm8904_parse_retune_cfg_from_of(struct i2c_client *i2c,
+					   struct wm8904_pdata *pdata)
+{
+	const struct device_node *np = i2c->dev.of_node;
+	int i, n_cfgs;
+
+	n_cfgs = of_property_count_strings(np, "wlf,retune-mobile-cfg-names");
+	if (n_cfgs == -EINVAL)
+		return 0;
+
+	if (n_cfgs <= 0) {
+		dev_err(&i2c->dev,
+			"Could not get wlf,retune-mobile-cfg-names length: %d",
+			n_cfgs);
+		return n_cfgs;
+	}
+
+	pdata->retune_mobile_cfgs = devm_kzalloc(&i2c->dev,
+						 n_cfgs * sizeof(struct wm8904_retune_mobile_cfg),
+						 GFP_KERNEL);
+	if (!pdata->retune_mobile_cfgs)
+		return -ENOMEM;
+
+	for (i = 0; i < n_cfgs; i++) {
+		if (wm8904_parse_retune_cfg_regs(np, pdata, i)) {
+			dev_err(&i2c->dev,
+				"Invalid 'wlf,retune-mobile-cfg-regs[%i,:]'\n", i);
+			return -EINVAL;
+		}
+
+		if (of_property_read_u32_index(np, "wlf,retune-mobile-cfg-hz", i,
+					       &pdata->retune_mobile_cfgs[i].rate)) {
+			dev_err(&i2c->dev,
+				"Invalid 'wlf,retune-mobile-cfg-hz[%i]'\n", i);
+			return -EINVAL;
+		}
+
+		if (of_property_read_string_index(np, "wlf,retune-mobile-cfg-names", i,
+						  &pdata->retune_mobile_cfgs[i].name)) {
+			dev_err(&i2c->dev,
+				"Invalid 'wlf,retune-mobile-cfg-names[%i]'\n", i);
+			return -EINVAL;
+		}
+	}
+
+	pdata->num_retune_mobile_cfgs = n_cfgs;
+	return 0;
+}
+
+static int wm8904_set_pdata_from_of(struct i2c_client *i2c,
+				    struct wm8904_priv *wm8904)
+{
+	const struct device_node *np = i2c->dev.of_node;
+	struct wm8904_pdata *pdata;
+	int ret, i;
+
+	pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	pdata->in1l_as_dmicdat1 =
+		of_property_read_bool(np, "wlf,in1l-as-dmicdat1");
+
+	pdata->in1r_as_dmicdat2 =
+		of_property_read_bool(np, "wlf,in1r-as-dmicdat2");
+
+	/* If absent, default to 0xFFFF for GPIO config (i.e.: don't set) */
+	for (i = 0; i < WM8904_GPIO_REGS; i++)
+		pdata->gpio_cfg[i] = 0xFFFF;
+
+	of_property_read_u32_array(np, "wlf,gpio-cfg", pdata->gpio_cfg,
+				   ARRAY_SIZE(pdata->gpio_cfg));
+
+	of_property_read_u32_array(np, "wlf,mic-cfg", pdata->mic_cfg,
+				   ARRAY_SIZE(pdata->mic_cfg));
+
+	ret = wm8904_parse_drc_cfg_from_of(i2c, pdata);
+	if (ret)
+		return ret;
+
+	ret = wm8904_parse_retune_cfg_from_of(i2c, pdata);
+	if (ret)
+		return ret;
+
+	wm8904->pdata = pdata;
+	return 0;
+}
+
 static const struct i2c_device_id wm8904_i2c_id[];
 
 static int wm8904_i2c_probe(struct i2c_client *i2c)
@@ -2199,7 +2377,16 @@ static int wm8904_i2c_probe(struct i2c_client *i2c)
 	wm8904->devtype = (uintptr_t)i2c_get_match_data(i2c);
 
 	i2c_set_clientdata(i2c, wm8904);
-	wm8904->pdata = i2c->dev.platform_data;
+
+	if (i2c->dev.of_node) {
+		ret = wm8904_set_pdata_from_of(i2c, wm8904);
+		if (ret) {
+			dev_err(&i2c->dev, "Failed to set platform data from of: %d\n", ret);
+			return ret;
+		}
+	} else {
+		wm8904->pdata = i2c->dev.platform_data;
+	}
 
 	for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
 		wm8904->supplies[i].supply = wm8904_supply_names[i];
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 5/5] ASoC: wm8904: add DMIC support
  2025-03-07 13:52 [PATCH v3 0/5] ASoC: wm8904: Add DMIC and DRC support Francesco Dolcini
                   ` (3 preceding siblings ...)
  2025-03-07 13:52 ` [PATCH v3 4/5] ASoC: wm8904: get platform data from DT Francesco Dolcini
@ 2025-03-07 13:52 ` Francesco Dolcini
  4 siblings, 0 replies; 12+ messages in thread
From: Francesco Dolcini @ 2025-03-07 13:52 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, Jaroslav Kysela, Takashi Iwai,
	patches
  Cc: Ernest Van Hoecke, linux-sound, devicetree, linux-kernel,
	Francesco Dolcini, Charles Keepax

From: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>

The WM8904 codec supports both ADC and DMIC inputs.

Get input pin functionality from the platform data and add the necessary
controls depending on the possible additional routing.

The ADC and DMIC share the IN1L/DMICDAT1 and IN1R/DMICDAT2 pins.

This leads to a few scenarios requiring different DAPM routing:
- When both are connected to an analog input, only the ADC is used.
- When one line is a DMIC and the other an analog input, the DMIC source
  is set from the platform data and a mux is added to select whether to
  use the ADC or DMIC.
- When both are connected to a DMIC, another mux is added to this to
  select the DMIC source. Note that we still need to be able to select
  the ADC system for use with the IN2L, IN2R, IN3L and IN3R pins.

Signed-off-by: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>
Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
v3: no changes
v2: DAPM routes have been reworked, please see the commit message body.
    The previous approach forgot that the ADC is still needed for the
    IN2L/R and IN3L/R pins, and did not properly disconnect the PGAs
    from the ADC when only the DMIC was in use.
v1: https://lore.kernel.org/lkml/20250206163152.423199-6-francesco@dolcini.it/

Cc: ckeepax@opensource.cirrus.com
---
 sound/soc/codecs/wm8904.c | 125 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 120 insertions(+), 5 deletions(-)

diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 8a2b98745964..b85872a373c1 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -844,6 +844,26 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
+static const char * const dmic_text[] = {
+	"DMIC1", "DMIC2"
+};
+
+static SOC_ENUM_SINGLE_DECL(dmic_enum, WM8904_DIGITAL_MICROPHONE_0,
+			    WM8904_DMIC_SRC_SHIFT, dmic_text);
+
+static const struct snd_kcontrol_new dmic_mux =
+	SOC_DAPM_ENUM("DMIC Mux", dmic_enum);
+
+static const char * const cin_text[] = {
+	"ADC", "DMIC"
+};
+
+static SOC_ENUM_SINGLE_DECL(cin_enum, WM8904_DIGITAL_MICROPHONE_0,
+			    WM8904_DMIC_ENA_SHIFT, cin_text);
+
+static const struct snd_kcontrol_new cin_mux =
+	SOC_DAPM_ENUM("Capture Input", cin_enum);
+
 static const char *input_mode_text[] = {
 	"Single-Ended", "Differential Line", "Differential Mic"
 };
@@ -963,6 +983,15 @@ SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
 SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
 };
 
+static const struct snd_soc_dapm_widget wm8904_dmic_dapm_widgets[] = {
+SND_SOC_DAPM_MUX("DMIC Mux", SND_SOC_NOPM, 0, 0, &dmic_mux),
+};
+
+static const struct snd_soc_dapm_widget wm8904_cin_dapm_widgets[] = {
+SND_SOC_DAPM_MUX("Left Capture Input", SND_SOC_NOPM, 0, 0, &cin_mux),
+SND_SOC_DAPM_MUX("Right Capture Input", SND_SOC_NOPM, 0, 0, &cin_mux),
+};
+
 static const struct snd_soc_dapm_widget wm8904_dac_dapm_widgets[] = {
 SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
 SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
@@ -1101,12 +1130,45 @@ static const struct snd_soc_dapm_route adc_intercon[] = {
 	{ "AIFOUTR", NULL, "AIFOUTR Mux" },
 
 	{ "ADCL", NULL, "CLK_DSP" },
-	{ "ADCL", NULL, "Left Capture PGA" },
-
 	{ "ADCR", NULL, "CLK_DSP" },
+};
+
+/* No DMICs, always connect PGAs */
+static const struct snd_soc_dapm_route cin_nodmic_con[] = {
+	{ "ADCL", NULL, "Left Capture PGA" },
 	{ "ADCR", NULL, "Right Capture PGA" },
 };
 
+/* DMIC system in use: mux between ADC and DMICDAT1, 2 or both */
+static const struct snd_soc_dapm_route cin_adc_dmic_con[] = {
+	{ "Left Capture Input", "ADC", "Left Capture PGA" },
+	{ "Right Capture Input", "ADC", "Right Capture PGA" },
+
+	{ "ADCL", NULL, "Left Capture Input" },
+	{ "ADCR", NULL, "Right Capture Input" },
+};
+
+/*  IN1L as DMICDAT1 */
+static const struct snd_soc_dapm_route cin_dmic1_con[] = {
+	{ "Left Capture Input", "DMIC", "IN1L" },
+	{ "Right Capture Input", "DMIC", "IN1L" },
+};
+
+/* IN1R as DMICDAT2 */
+static const struct snd_soc_dapm_route cin_dmic2_con[] = {
+	{ "Left Capture Input", "DMIC", "IN1R" },
+	{ "Right Capture Input", "DMIC", "IN1R" },
+};
+
+/* DMICDAT1 and DMICDAT2: mux between them, ADC still used for IN2 and IN3 */
+static const struct snd_soc_dapm_route cin_2dmics_con[] = {
+	{ "DMIC Mux", "DMIC1", "IN1L" },
+	{ "DMIC Mux", "DMIC2", "IN1R" },
+
+	{ "Left Capture Input", "DMIC", "DMIC Mux" },
+	{ "Right Capture Input", "DMIC", "DMIC Mux" },
+};
+
 static const struct snd_soc_dapm_route dac_intercon[] = {
 	{ "DACL Mux", "Left", "AIFINL" },
 	{ "DACL Mux", "Right", "AIFINR" },
@@ -2050,18 +2112,70 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_component *componen
 			"Failed to add ReTune Mobile control: %d\n", ret);
 }
 
+static void wm8904_handle_dmic_pdata(struct snd_soc_component *component)
+{
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
+	struct wm8904_pdata *pdata = wm8904->pdata;
+	unsigned int dmic_src;
+
+	if (!pdata->in1l_as_dmicdat1 && !pdata->in1r_as_dmicdat2) {
+		snd_soc_dapm_add_routes(dapm, cin_nodmic_con,
+					ARRAY_SIZE(cin_nodmic_con));
+		snd_soc_component_update_bits(component, WM8904_DIGITAL_MICROPHONE_0,
+					      WM8904_DMIC_ENA_MASK, 0);
+		return;
+	}
+
+	/* Need a control and routing to switch between DMIC and ADC */
+	snd_soc_dapm_new_controls(dapm, wm8904_cin_dapm_widgets,
+				  ARRAY_SIZE(wm8904_cin_dapm_widgets));
+	snd_soc_dapm_add_routes(dapm, cin_adc_dmic_con,
+				ARRAY_SIZE(cin_adc_dmic_con));
+
+	if (pdata->in1l_as_dmicdat1 && pdata->in1r_as_dmicdat2) {
+		/* Need a control and routing to mux between DMICDAT1 and 2 */
+		dev_dbg(component->dev, "DMICDAT1 and DMICDAT2 in use\n");
+		snd_soc_dapm_new_controls(dapm, wm8904_dmic_dapm_widgets,
+					  ARRAY_SIZE(wm8904_dmic_dapm_widgets));
+		snd_soc_dapm_add_routes(dapm, cin_2dmics_con,
+					ARRAY_SIZE(cin_2dmics_con));
+		return;
+	}
+
+	/* Either DMICDAT1 or DMICDAT2 is in use, not both */
+	if (pdata->in1l_as_dmicdat1) {
+		dmic_src = 0;
+		snd_soc_dapm_add_routes(dapm, cin_dmic1_con,
+					ARRAY_SIZE(cin_dmic1_con));
+	} else {
+		dmic_src = 1;
+		snd_soc_dapm_add_routes(dapm, cin_dmic2_con,
+					ARRAY_SIZE(cin_dmic2_con));
+	}
+	dev_dbg(component->dev, "DMIC_SRC (0 or 1): %d\n", dmic_src);
+	snd_soc_component_update_bits(component, WM8904_DIGITAL_MICROPHONE_0,
+				      WM8904_DMIC_SRC_MASK,
+				      dmic_src << WM8904_DMIC_SRC_SHIFT);
+}
+
 static void wm8904_handle_pdata(struct snd_soc_component *component)
 {
+	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 	struct wm8904_priv *wm8904 = snd_soc_component_get_drvdata(component);
 	struct wm8904_pdata *pdata = wm8904->pdata;
 	int ret, i;
 
 	if (!pdata) {
+		snd_soc_dapm_add_routes(dapm, cin_nodmic_con,
+					ARRAY_SIZE(cin_nodmic_con));
 		snd_soc_add_component_controls(component, wm8904_eq_controls,
-				     ARRAY_SIZE(wm8904_eq_controls));
+					       ARRAY_SIZE(wm8904_eq_controls));
 		return;
 	}
 
+	wm8904_handle_dmic_pdata(component);
+
 	dev_dbg(component->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
 
 	if (pdata->num_drc_cfgs) {
@@ -2117,10 +2231,11 @@ static int wm8904_probe(struct snd_soc_component *component)
 		return -EINVAL;
 	}
 
-	wm8904_handle_pdata(component);
-
 	wm8904_add_widgets(component);
 
+	/* This can add dependent widgets, so it is done after add_widgets */
+	wm8904_handle_pdata(component);
+
 	return 0;
 }
 
-- 
2.39.5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/5] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support
  2025-03-07 13:52 ` [PATCH v3 3/5] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support Francesco Dolcini
@ 2025-03-11  8:42   ` Krzysztof Kozlowski
  2025-03-11 13:46     ` Mark Brown
  2025-03-11 17:59     ` Rob Herring
  2025-03-12  8:41   ` Krzysztof Kozlowski
  1 sibling, 2 replies; 12+ messages in thread
From: Krzysztof Kozlowski @ 2025-03-11  8:42 UTC (permalink / raw)
  To: Francesco Dolcini
  Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, Jaroslav Kysela, Takashi Iwai,
	patches, Ernest Van Hoecke, linux-sound, devicetree, linux-kernel,
	Francesco Dolcini, Charles Keepax

On Fri, Mar 07, 2025 at 02:52:42PM +0100, Francesco Dolcini wrote:
> From: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>
> 
> Add two properties to select the IN1L/DMICDAT1 and IN2R/DMICDAT2
> functionality:
> - wlf,in1l-as-dmicdat1
> - wlf,in1r-as-dmicdat2
> 
> Add a property to describe the GPIO configuration registers, that can be
> used to set the four multifunction pins:
> - wlf,gpio-cfg
> 
> Add a property to describe the mic bias control registers:
> - wlf,mic-cfg
> 
> Add two properties to describe the Dynamic Range Controller (DRC),
> allowing multiple named configurations where each config sets the 4 DRC
> registers (R40-R43):
> - wlf,drc-cfg-regs
> - wlf,drc-cfg-names
> 
> Add three properties to describe the equalizer (ReTune Mobile), allowing
> multiple named configurations (associated with a samplerate) that set
> the 24 (R134-R157) EQ registers:
> - wlf,retune-mobile-cfg-regs
> - wlf,retune-mobile-cfg-hz
> - wlf,retune-mobile-cfg-rates
> 
> Datasheet: https://statics.cirrus.com/pubs/proDatasheet/WM8904_Rev4.1.pdf
> Signed-off-by: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>
> Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
> Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
> ---
> v3: v2 did not pass dt_binding_check, this is now fixed.
>     Fixed a DT compilation error by moving a misplaced closing bracket.
>     Changed 'retune-mobile-cfg-names' to be a nonunique-string-array.
>     Renamed 'retune-mobile-cfg-rates' to 'retune-mobile-cfg-hz',
>         dropped the 'ref' because it is now a standard unit suffix prop.
>     Redid line wrapping to be compliant with the DTS style guidelines.
> v2: Added an example of how to use the ReTune Mobile config properties
> v1: https://lore.kernel.org/lkml/20250206163152.423199-4-francesco@dolcini.it/
> ---
>  .../devicetree/bindings/sound/wlf,wm8904.yaml | 116 ++++++++++++++++++
>  1 file changed, 116 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/sound/wlf,wm8904.yaml b/Documentation/devicetree/bindings/sound/wlf,wm8904.yaml
> index 329260cf0fa0..4ad8681cb266 100644
> --- a/Documentation/devicetree/bindings/sound/wlf,wm8904.yaml
> +++ b/Documentation/devicetree/bindings/sound/wlf,wm8904.yaml
> @@ -38,6 +38,72 @@ properties:
>    DCVDD-supply: true
>    MICVDD-supply: true
>  
> +  wlf,in1l-as-dmicdat1:
> +    type: boolean
> +    description:
> +      Use IN1L/DMICDAT1 as DMICDAT1, enabling the DMIC input path.
> +
> +  wlf,in1r-as-dmicdat2:
> +    type: boolean
> +    description:
> +      Use IN1R/DMICDAT2 as DMICDAT2, enabling the DMIC input path.

Are these two properties mutually exclusive?

> +
> +  wlf,gpio-cfg:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    minItems: 4
> +    maxItems: 4
> +    description:
> +      Default register values for R121/122/123/124 (GPIO Control).
> +      If any entry has the value 0xFFFF, the related register won't be set.
> +    default: [0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF]
> +
> +  wlf,mic-cfg:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    minItems: 2
> +    maxItems: 2
> +    description:
> +      Default register values for R6/R7 (Mic Bias Control).
> +    default: [0, 0]
> +
> +  wlf,drc-cfg-names:
> +    $ref: /schemas/types.yaml#/definitions/string-array

No constraints, so I assume you can have here any number of items?

> +    description:
> +      List of strings for the available DRC modes.

Why the actual names are not defined? Why do you need this property if
they are not defined (thus driver does not request this by the name)?

> +      If absent, DRC is disabled.
> +
> +  wlf,drc-cfg-regs:
> +    $ref: /schemas/types.yaml#/definitions/uint16-array
> +    description:
> +      Default register values for R40/41/42/43 (DRC).
> +      The list must be 4 times the length of wlf,drc-cfg-names.
> +      If absent, DRC is disabled.
> +
> +  wlf,retune-mobile-cfg-names:
> +    $ref: /schemas/types.yaml#/definitions/non-unique-string-array
> +    description:
> +      List of strings for the available retune modes.
> +      If absent, retune is disabled.
> +
> +  wlf,retune-mobile-cfg-hz:
> +    description:
> +      The list must be the same length as wlf,retune-mobile-cfg-names.
> +      If absent, retune is disabled.
> +
> +  wlf,retune-mobile-cfg-regs:
> +    $ref: /schemas/types.yaml#/definitions/uint16-array
> +    description:
> +      Default register values for R134/.../157 (EQ).
> +      The list must be 24 times the length of wlf,retune-mobile-cfg-names.
> +      If absent, retune is disabled.
> +
> +dependencies:
> +  wlf,drc-cfg-names: [ 'wlf,drc-cfg-regs' ]
> +  wlf,drc-cfg-regs: [ 'wlf,drc-cfg-names' ]
> +
> +  wlf,retune-mobile-cfg-names: [ 'wlf,retune-mobile-cfg-hz', 'wlf,retune-mobile-cfg-regs' ]
> +  wlf,retune-mobile-cfg-regs: [ 'wlf,retune-mobile-cfg-names', 'wlf,retune-mobile-cfg-hz' ]
> +  wlf,retune-mobile-cfg-hz: [ 'wlf,retune-mobile-cfg-names', 'wlf,retune-mobile-cfg-regs' ]
> +
>  required:
>    - compatible
>    - reg
> @@ -70,5 +136,55 @@ examples:
>              DBVDD-supply = <&reg_1p8v>;
>              DCVDD-supply = <&reg_1p8v>;
>              MICVDD-supply = <&reg_1p8v>;
> +
> +            wlf,drc-cfg-names = "default", "peaklimiter", "tradition", "soft",
> +                                "music";
> +            /*
> +             * Config registers per name, respectively:
> +             * KNEE_IP = 0,   KNEE_OP = 0,     HI_COMP = 1,   LO_COMP = 1
> +             * KNEE_IP = -24, KNEE_OP = -6,    HI_COMP = 1/4, LO_COMP = 1
> +             * KNEE_IP = -42, KNEE_OP = -3,    HI_COMP = 0,   LO_COMP = 1
> +             * KNEE_IP = -45, KNEE_OP = -9,    HI_COMP = 1/8, LO_COMP = 1
> +             * KNEE_IP = -30, KNEE_OP = -10.5, HI_COMP = 1/4, LO_COMP = 1
> +             */
> +            wlf,drc-cfg-regs = /bits/ 16 <0x01af 0x3248 0x0000 0x0000>,

<number>, <number>, <number> ...

unless you wanted 64-bit?

> +                               /bits/ 16 <0x04af 0x324b 0x0010 0x0408>,
> +                               /bits/ 16 <0x04af 0x324b 0x0028 0x0704>,
> +                               /bits/ 16 <0x04af 0x324b 0x0018 0x078c>,
> +                               /bits/ 16 <0x04af 0x324b 0x0010 0x050e>;
> +
> +            /* GPIO1 = DMIC_CLK, don't touch others */
> +            wlf,gpio-cfg = <0x0018 0xffff 0xffff 0xffff>;

So how many items here?

> +
> +            wlf,retune-mobile-cfg-names = "bassboost", "bassboost", "treble";
> +            wlf,retune-mobile-cfg-hz = <48000 44100 48000>;
> +            /*
> +             * Config registers per name, respectively:
> +             * EQ_ENA,  100 Hz,  300 Hz,  875 Hz, 2400 Hz, 6900 Hz
> +             *      1,   +6 dB,   +3 dB,    0 dB,    0 dB,    0 dB
> +             *      1,   +6 dB,   +3 dB,    0 dB,    0 dB,    0 dB
> +             *      1,   -2 dB,   -2 dB,    0 dB,    0 dB,   +3 dB
> +             * Each one uses the defaults for ReTune Mobile registers 140-157
> +             */
> +            wlf,retune-mobile-cfg-regs = /bits/ 16 <0x1 0x12 0xf 0xc 0xc 0xc>,
> +                                         /bits/ 16 <0x0fca 0x0400 0x00d8 0x1eb5
> +                                                    0xf145 0x0bd5 0x0075 0x1c58
> +                                                    0xf3d3 0x0a54 0x0568 0x168e
> +                                                    0xf829 0x07ad 0x1103 0x0564
> +                                                    0x0559 0x4000>,

I am really confused what are the matrix bounds here.

> +
> +                                         /bits/ 16 <0x1 0x12 0xf 0xc 0xc 0xc>,
> +                                         /bits/ 16 <0x0fca 0x0400 0x00d8 0x1eb5
> +                                                    0xf145 0x0bd5 0x0075 0x1c58
> +                                                    0xf3d3 0x0a54 0x0568 0x168e
> +                                                    0xf829 0x07ad 0x1103 0x0564
> +                                                    0x0559 0x4000>,

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/5] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support
  2025-03-11  8:42   ` Krzysztof Kozlowski
@ 2025-03-11 13:46     ` Mark Brown
  2025-03-11 17:59     ` Rob Herring
  1 sibling, 0 replies; 12+ messages in thread
From: Mark Brown @ 2025-03-11 13:46 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Francesco Dolcini, Liam Girdwood, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Jaroslav Kysela, Takashi Iwai, patches, Ernest Van Hoecke,
	linux-sound, devicetree, linux-kernel, Francesco Dolcini,
	Charles Keepax

[-- Attachment #1: Type: text/plain, Size: 1013 bytes --]

On Tue, Mar 11, 2025 at 09:42:45AM +0100, Krzysztof Kozlowski wrote:
> On Fri, Mar 07, 2025 at 02:52:42PM +0100, Francesco Dolcini wrote:

> > +  wlf,in1l-as-dmicdat1:
> > +    type: boolean
> > +    description:
> > +      Use IN1L/DMICDAT1 as DMICDAT1, enabling the DMIC input path.

> > +  wlf,in1r-as-dmicdat2:
> > +    type: boolean
> > +    description:
> > +      Use IN1R/DMICDAT2 as DMICDAT2, enabling the DMIC input path.

> Are these two properties mutually exclusive?

No, it's one property each for the left and right channels.

> > +  wlf,drc-cfg-names:
> > +    $ref: /schemas/types.yaml#/definitions/string-array

> No constraints, so I assume you can have here any number of items?

Yes.

> > +    description:
> > +      List of strings for the available DRC modes.

> Why the actual names are not defined? Why do you need this property if
> they are not defined (thus driver does not request this by the name)?

The driver displays the list of names to the end user for them to choose
between.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/5] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support
  2025-03-11  8:42   ` Krzysztof Kozlowski
  2025-03-11 13:46     ` Mark Brown
@ 2025-03-11 17:59     ` Rob Herring
  2025-03-12  8:39       ` Krzysztof Kozlowski
  1 sibling, 1 reply; 12+ messages in thread
From: Rob Herring @ 2025-03-11 17:59 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Francesco Dolcini, Liam Girdwood, Mark Brown, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, Jaroslav Kysela, Takashi Iwai,
	patches, Ernest Van Hoecke, linux-sound, devicetree, linux-kernel,
	Francesco Dolcini, Charles Keepax

On Tue, Mar 11, 2025 at 09:42:45AM +0100, Krzysztof Kozlowski wrote:
> On Fri, Mar 07, 2025 at 02:52:42PM +0100, Francesco Dolcini wrote:
> > From: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>
> > 
> > Add two properties to select the IN1L/DMICDAT1 and IN2R/DMICDAT2
> > functionality:
> > - wlf,in1l-as-dmicdat1
> > - wlf,in1r-as-dmicdat2
> > 
> > Add a property to describe the GPIO configuration registers, that can be
> > used to set the four multifunction pins:
> > - wlf,gpio-cfg
> > 
> > Add a property to describe the mic bias control registers:
> > - wlf,mic-cfg
> > 
> > Add two properties to describe the Dynamic Range Controller (DRC),
> > allowing multiple named configurations where each config sets the 4 DRC
> > registers (R40-R43):
> > - wlf,drc-cfg-regs
> > - wlf,drc-cfg-names
> > 
> > Add three properties to describe the equalizer (ReTune Mobile), allowing
> > multiple named configurations (associated with a samplerate) that set
> > the 24 (R134-R157) EQ registers:
> > - wlf,retune-mobile-cfg-regs
> > - wlf,retune-mobile-cfg-hz
> > - wlf,retune-mobile-cfg-rates


> > +             * Config registers per name, respectively:
> > +             * KNEE_IP = 0,   KNEE_OP = 0,     HI_COMP = 1,   LO_COMP = 1
> > +             * KNEE_IP = -24, KNEE_OP = -6,    HI_COMP = 1/4, LO_COMP = 1
> > +             * KNEE_IP = -42, KNEE_OP = -3,    HI_COMP = 0,   LO_COMP = 1
> > +             * KNEE_IP = -45, KNEE_OP = -9,    HI_COMP = 1/8, LO_COMP = 1
> > +             * KNEE_IP = -30, KNEE_OP = -10.5, HI_COMP = 1/4, LO_COMP = 1
> > +             */
> > +            wlf,drc-cfg-regs = /bits/ 16 <0x01af 0x3248 0x0000 0x0000>,
> 
> <number>, <number>, <number> ...
> 
> unless you wanted 64-bit?

Why? You would need "/bits/ 16 <number>, /bits/ 16 <number>, ..."

Rob

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/5] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support
  2025-03-11 17:59     ` Rob Herring
@ 2025-03-12  8:39       ` Krzysztof Kozlowski
  2025-03-12  8:48         ` Ernest Van Hoecke
  0 siblings, 1 reply; 12+ messages in thread
From: Krzysztof Kozlowski @ 2025-03-12  8:39 UTC (permalink / raw)
  To: Rob Herring
  Cc: Francesco Dolcini, Liam Girdwood, Mark Brown, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, Jaroslav Kysela, Takashi Iwai,
	patches, Ernest Van Hoecke, linux-sound, devicetree, linux-kernel,
	Francesco Dolcini, Charles Keepax

On 11/03/2025 18:59, Rob Herring wrote:
> On Tue, Mar 11, 2025 at 09:42:45AM +0100, Krzysztof Kozlowski wrote:
>> On Fri, Mar 07, 2025 at 02:52:42PM +0100, Francesco Dolcini wrote:
>>> From: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>
>>>
>>> Add two properties to select the IN1L/DMICDAT1 and IN2R/DMICDAT2
>>> functionality:
>>> - wlf,in1l-as-dmicdat1
>>> - wlf,in1r-as-dmicdat2
>>>
>>> Add a property to describe the GPIO configuration registers, that can be
>>> used to set the four multifunction pins:
>>> - wlf,gpio-cfg
>>>
>>> Add a property to describe the mic bias control registers:
>>> - wlf,mic-cfg
>>>
>>> Add two properties to describe the Dynamic Range Controller (DRC),
>>> allowing multiple named configurations where each config sets the 4 DRC
>>> registers (R40-R43):
>>> - wlf,drc-cfg-regs
>>> - wlf,drc-cfg-names
>>>
>>> Add three properties to describe the equalizer (ReTune Mobile), allowing
>>> multiple named configurations (associated with a samplerate) that set
>>> the 24 (R134-R157) EQ registers:
>>> - wlf,retune-mobile-cfg-regs
>>> - wlf,retune-mobile-cfg-hz
>>> - wlf,retune-mobile-cfg-rates
> 
> 
>>> +             * Config registers per name, respectively:
>>> +             * KNEE_IP = 0,   KNEE_OP = 0,     HI_COMP = 1,   LO_COMP = 1
>>> +             * KNEE_IP = -24, KNEE_OP = -6,    HI_COMP = 1/4, LO_COMP = 1
>>> +             * KNEE_IP = -42, KNEE_OP = -3,    HI_COMP = 0,   LO_COMP = 1
>>> +             * KNEE_IP = -45, KNEE_OP = -9,    HI_COMP = 1/8, LO_COMP = 1
>>> +             * KNEE_IP = -30, KNEE_OP = -10.5, HI_COMP = 1/4, LO_COMP = 1
>>> +             */
>>> +            wlf,drc-cfg-regs = /bits/ 16 <0x01af 0x3248 0x0000 0x0000>,
>>
>> <number>, <number>, <number> ...
>>
>> unless you wanted 64-bit?
> 
> Why? You would need "/bits/ 16 <number>, /bits/ 16 <number>, ..."
Uh, right.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/5] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support
  2025-03-07 13:52 ` [PATCH v3 3/5] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support Francesco Dolcini
  2025-03-11  8:42   ` Krzysztof Kozlowski
@ 2025-03-12  8:41   ` Krzysztof Kozlowski
  1 sibling, 0 replies; 12+ messages in thread
From: Krzysztof Kozlowski @ 2025-03-12  8:41 UTC (permalink / raw)
  To: Francesco Dolcini, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Jaroslav Kysela, Takashi Iwai, patches
  Cc: Ernest Van Hoecke, linux-sound, devicetree, linux-kernel,
	Francesco Dolcini, Charles Keepax

On 07/03/2025 14:52, Francesco Dolcini wrote:
> +  wlf,in1l-as-dmicdat1:
> +    type: boolean
> +    description:
> +      Use IN1L/DMICDAT1 as DMICDAT1, enabling the DMIC input path.
> +
> +  wlf,in1r-as-dmicdat2:
> +    type: boolean
> +    description:
> +      Use IN1R/DMICDAT2 as DMICDAT2, enabling the DMIC input path.
> +
> +  wlf,gpio-cfg:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    minItems: 4
> +    maxItems: 4
> +    description:
> +      Default register values for R121/122/123/124 (GPIO Control).
> +      If any entry has the value 0xFFFF, the related register won't be set.
> +    default: [0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF]
> +
> +  wlf,mic-cfg:


Isn't this the same as wlf,micbias-cfg from wm8994? If property matches,
just use the same.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 3/5] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support
  2025-03-12  8:39       ` Krzysztof Kozlowski
@ 2025-03-12  8:48         ` Ernest Van Hoecke
  0 siblings, 0 replies; 12+ messages in thread
From: Ernest Van Hoecke @ 2025-03-12  8:48 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Rob Herring, Francesco Dolcini, Liam Girdwood, Mark Brown,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Jaroslav Kysela, Takashi Iwai, patches, Ernest Van Hoecke,
	linux-sound, devicetree, linux-kernel, Francesco Dolcini,
	Charles Keepax

On Wed, Mar 12, 2025 at 09:39:59AM +0100, Krzysztof Kozlowski wrote:
> On 11/03/2025 18:59, Rob Herring wrote:
> > On Tue, Mar 11, 2025 at 09:42:45AM +0100, Krzysztof Kozlowski wrote:
> >> On Fri, Mar 07, 2025 at 02:52:42PM +0100, Francesco Dolcini wrote:
> >>> From: Ernest Van Hoecke <ernest.vanhoecke@toradex.com>
> >>>
> >>> Add two properties to select the IN1L/DMICDAT1 and IN2R/DMICDAT2
> >>> functionality:
> >>> - wlf,in1l-as-dmicdat1
> >>> - wlf,in1r-as-dmicdat2
> >>>
> >>> Add a property to describe the GPIO configuration registers, that can be
> >>> used to set the four multifunction pins:
> >>> - wlf,gpio-cfg
> >>>
> >>> Add a property to describe the mic bias control registers:
> >>> - wlf,mic-cfg
> >>>
> >>> Add two properties to describe the Dynamic Range Controller (DRC),
> >>> allowing multiple named configurations where each config sets the 4 DRC
> >>> registers (R40-R43):
> >>> - wlf,drc-cfg-regs
> >>> - wlf,drc-cfg-names
> >>>
> >>> Add three properties to describe the equalizer (ReTune Mobile), allowing
> >>> multiple named configurations (associated with a samplerate) that set
> >>> the 24 (R134-R157) EQ registers:
> >>> - wlf,retune-mobile-cfg-regs
> >>> - wlf,retune-mobile-cfg-hz
> >>> - wlf,retune-mobile-cfg-rates
> > 
> > 
> >>> +             * Config registers per name, respectively:
> >>> +             * KNEE_IP = 0,   KNEE_OP = 0,     HI_COMP = 1,   LO_COMP = 1
> >>> +             * KNEE_IP = -24, KNEE_OP = -6,    HI_COMP = 1/4, LO_COMP = 1
> >>> +             * KNEE_IP = -42, KNEE_OP = -3,    HI_COMP = 0,   LO_COMP = 1
> >>> +             * KNEE_IP = -45, KNEE_OP = -9,    HI_COMP = 1/8, LO_COMP = 1
> >>> +             * KNEE_IP = -30, KNEE_OP = -10.5, HI_COMP = 1/4, LO_COMP = 1
> >>> +             */
> >>> +            wlf,drc-cfg-regs = /bits/ 16 <0x01af 0x3248 0x0000 0x0000>,
> >>
> >> <number>, <number>, <number> ...
> >>
> >> unless you wanted 64-bit?
> > 
> > Why? You would need "/bits/ 16 <number>, /bits/ 16 <number>, ..."
> Uh, right.

After some investigation I realized I could use a "matrix" type instead
of an "array" for "drc-cfg-regs" and "retune-mobile-cfg-regs". In that
case, an item of the matrix is an array, and this split should be fine.

This is also how "adi,ltc2983.yaml" and "mediatek,mt76.yaml" handle
similarly long matrices. My bad for missing the matrix type.

Kind regards,
Ernest

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-03-12  8:48 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-07 13:52 [PATCH v3 0/5] ASoC: wm8904: Add DMIC and DRC support Francesco Dolcini
2025-03-07 13:52 ` [PATCH v3 1/5] of: Add of_property_read_u16_index Francesco Dolcini
2025-03-07 13:52 ` [PATCH v3 2/5] ASoC: wm8904: Don't touch GPIO configs set to 0xFFFF Francesco Dolcini
2025-03-07 13:52 ` [PATCH v3 3/5] ASoC: dt-bindings: wm8904: Add DMIC, GPIO, MIC and EQ support Francesco Dolcini
2025-03-11  8:42   ` Krzysztof Kozlowski
2025-03-11 13:46     ` Mark Brown
2025-03-11 17:59     ` Rob Herring
2025-03-12  8:39       ` Krzysztof Kozlowski
2025-03-12  8:48         ` Ernest Van Hoecke
2025-03-12  8:41   ` Krzysztof Kozlowski
2025-03-07 13:52 ` [PATCH v3 4/5] ASoC: wm8904: get platform data from DT Francesco Dolcini
2025-03-07 13:52 ` [PATCH v3 5/5] ASoC: wm8904: add DMIC support Francesco Dolcini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).