Re: [PATCH 2/4] ASoC: dt-bindings: Add support for the GPIOs driven amplifier

Rob Herring
2026-04-08T12:29:03Z

On Mon, Mar 30, 2026 at 12:16:06PM +0200, Herve Codina wrote:
> Some amplifiers based on analog switches and op-amps can be present in
> the audio path and can be driven by GPIOs in order to control their gain
> value, their mute and/or bypass functions.
>
> Those components needs to be viewed as audio components in order to be
> fully integrated in the audio path.
>
> audio-gpio-amplifier allows to consider these GPIO driven amplifiers as
> auxiliary audio devices.
>
> Signed-off-by: Herve Codina <herve.codina@bootlin.com>
> ---
> .../bindings/sound/audio-gpio-amp.yaml | 309 ++++++++++++++++++
> 1 file changed, 309 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/sound/audio-gpio-amp.yaml
>
> diff --git a/Documentation/devicetree/bindings/sound/audio-gpio-amp.yaml b/Documentation/devicetree/bindings/sound/audio-gpio-amp.yaml
> new file mode 100644
> index 000000000000..15dc898f8574
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/audio-gpio-amp.yaml
> @@ -0,0 +1,309 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/audio-gpio-amp.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Audio amplifier driven by GPIOs
> +
> +maintainers:
> + - Herve Codina <herve.codina@bootlin.com>
> +
> +description: |
> + Audio GPIO amplifiers are driven by GPIO in order to control the gain value
> + of the amplifier, its mute function and/or its bypass function.
> +
> + Those amplifiers are based on discrete components (analog switches, op-amps
> + and more) where some of them, mostly analog switches, are controlled by GPIOs
> + to adjust the gain value of the whole amplifier and/or to control
> + the mute and/or bypass function.
> +
> + For instance, the following piece of hardware is a GPIO amplifier
> +
> + +5VA
> + ^
> + |\ |
> + | \
> + Vin >---------------------------|+ \
> + | +-------+-----> Vout
> + .--\/\/\/--+------------|- / |
> + | | | / |
> + v | |/ | |
> + GND o v |
> + \ GND |
> + gpio >-----------> \ |
> + o o |
> + | | |
> + | '--\/\/\/--. |
> + | +--\/\/\/--'
> + '---------------'
> +
> + A GPIO driven amplifier can work in several mode depending on the electronic
> + design.
> + - points defined:
> + The values of GPIOs used to control gain set a specific gain value
> + without any specific relationship between each value. For instance,
> + using 2 GPIOS:
> + 0b00 <-> -10.0 dB
> + 0b01 <-> +3.0 dB
> + 0b10 <-> 0 dB
> + 0b11 <-> +6.0 dB
> +
> + This can be described using the gain-points property.
> +
> + - range defined:
> + The values of GPIOs used to control gain set a specific gain value
> + following a linear dB range from a minimum dB value to a maximum dB
> + value. For instance, using 2 GPIOS:
> + 0b00 <-> -3.0 dB
> + 0b01 <-> 0 db
> + 0b10 <-> +3.0 dB
> + 0b11 <-> +6.0 dB
> +
> + This can be described using the gain-range property.
> +
> + - labels defined:
> + Some electronic design are not meant to a specific dB gain value. In
> + that case it is relevant to use labels to describe them. For instance,
> + using 2 GPIOS:
> + 0b00 <-> Low boost
> + 0b01 <-> Middle boost
> + 0b10 <-> High boost
> + 0b11 <-> Max boost
> +
> + This can be described using the gain-labels property
> +
> +properties:
> + compatible:
> + const: audio-gpio-amp

To be consistent with other GPIO controlled devices: gpio-audio-amp

> +
> + vdd-supply:
> + description: Main power supply of the amplifier
> +
> + vddio-supply:
> + description: Power supply related to the control path
> +
> + vdda1-supply:
> + description: Analog power supply
> +
> + vdda2-supply:
> + description: Additional analog power supply
> +
> + mute-gpios:
> + description: GPIO to control the mute function
> + maxItems: 1
> +
> + bypass-gpios:
> + description: GPIO to control the bypass function
> + maxItems: 1
> +
> + gain-gpios:
> + description: |
> + GPIOs to control the amplifier gain
> +
> + The gain value is computed from GPIOs value from 0 to 2^N-1 with N the
> + number of GPIO described. The first GPIO described is the lsb of the gain
> + value.
> +
> + For instance assuming 2 gpios
> + gain-gpios = <&gpio1 GPIO_ACTIVE_HIGH> <&gpio2 GPIO_ACTIVE_HIGH>;
> + The gain value will be the following:
> +
> + gpio1 | gpio2 | gain
> + ------+-------+-----
> + 0 | 0 | 0b00 -> 0
> + 1 | 0 | 0b01 -> 1
> + 0 | 1 | 0b10 -> 2
> + 1 | 1 | 0b11 -> 3
> + ------+-------+-----
> +
> + Note: The gain value, bits set to 1 or 0, indicate the state active (bit
> + set) or the state inactive (bit unset) of the related GPIO. The
> + physical voltage corresponding to this active/inactive state is
> + given by the GPIO_ACTIVE_HIGH and GPIO_ACTIVE_LOW flags.
> +
> + minItems: 1
> + maxItems: 32

2^32 levels? Seems like a bit much. Also, unless you can change the
values of all the GPIOs atomically, aren't you going to get some
artifacts while the gain is being changed? Unless you mute I guess.

> +
> + gain-points:
> + $ref: /schemas/types.yaml#/definitions/int32-matrix
> + items:
> + items:
> + - description: The GPIOs value

Can't this just be the index?

If not, then gain-range could be expressed using gain-points instead.

> + - description: The related amplifier gain in 0.01 dB unit
> + minItems: 2
> + description: |
> + List of the GPIOs value / Gain value in dB pair defining the gain
> + set on each GPIOs value.
> +
> + With 2 GPIOs controlling the gain, GPIOs value can be 0, 1, 2 and 3.
> + Assuming that GPIOs values set the hardware gains according to the
> + following table:
> +
> + GPIOs | Hardware
> + value | amplification
> + ------+--------------
> + 0 | -10.0 dB
> + 1 | +3.0 dB
> + 2 | 0 dB
> + 3 | +6.0 dB
> + ------+--------------
> +
> + The description using gain points can be:
> + gain-points = <0 (-1000)>, <1 300>, <2 0>, <3 600>;
> +
> + gain-range:
> + $ref: /schemas/types.yaml#/definitions/int32-array
> + items:
> + - description: Gain in 0.01 dB unit when all GPIOs are inactive
> + - description: Gain in 0.01 dB unit when all GPIOs are active
> + description: |
> + Gains (in 0.01 dB unit) set by the extremum (minimal and maximum) value
> + of GPIOs. The following formula must be satisfied.
> +
> + gain-range[1] - gain-range[0]
> + Gain = ------------------------------- x GPIO_value + gain-range[0]
> + 2^N - 1
> +
> + With N, the number of GPIOs used to control the gain and Gain computed in
> + 0.01 dB unit.
> +
> + With 2 GPIOs controlling the gain, GPIOs value can be 0, 1, 2 and 3.
> + Assuming that gain value set the hardware according to the following
> + table:
> +
> + GPIOs | Hardware 1 | Hardware 2
> + value | amplification | amplification
> + ------+---------------+---------------
> + 0 | -3.0 dB | +10.0 dB
> + 1 | 0 dB | +5.0 dB
> + 2 | +3.0 dB | 0 dB
> + 3 | +6.0 dB | -5.0 dB
> + ------+---------------+---------------
> +
> + The description for hardware 1 using a gain range can be:
> + gain-range = <(-300) 600>;
> +
> + The description for hardware 2 using a gain range can be:
> + gain-range = <1000 (-500)>;
> +
> + gain-labels:
> + $ref: /schemas/types.yaml#/definitions/string-array

minItems: 2
maxItems: 0x100000000

> + description: |
> + List of the gain labels attached to the combination of GPIOs controlling
> + the gain. The first label is related to the gain value 0, the second label
> + is related to the gain value 1 and so on.
> +
> + With 2 GPIOs controlling the gain, GPIOs value can be 0, 1, 2 and 3.
> + Assuming that gain value set the hardware according to the following
> + table:
> +
> + GPIOs | Hardware
> + value | amplification
> + ------+--------------
> + 0 | Low
> + 1 | Middle
> + 2 | High
> + 3 | Max
> + ------+--------------
> +
> + The description using gain labels can be:
> + gain-labels = "Low", "Middle", "High", "Max";

Do we need to allow these to be anything? It's going to get hard to come
up with 2^32 names.

> +
> +dependencies:
> + gain-points: [ gain-gpios ]
> + gain-range: [ gain-gpios ]
> + gain-labels: [ gain-gpios ]

gain-gpios is really optional?

> +
> +required:
> + - compatible
> + - vdd-supply
> +
> +anyOf:
> + - required:
> + - gain-gpios
> + - required:
> + - mute-gpios
> + - required:
> + - bypass-gpios
> +
> +allOf:
> + - $ref: dai-common.yaml#
> + - if:
> + required:
> + - gain-points
> + then:
> + properties:
> + gain-range: false
> + gain-labels: false
> + - if:
> + required:
> + - gain-range
> + then:
> + properties:
> + gain-points: false
> + gain-labels: false
> + - if:
> + required:
> + - gain-labels
> + then:
> + properties:
> + gain-points: false
> + gain-range: false
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> +
> + /* Gain controlled by gpios */
> + amplifier0 {

amplifier-0

> + compatible = "audio-gpio-amp";
> + vdd-supply = <&regulator>;
> + gain-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>, <&gpio 1 GPIO_ACTIVE_HIGH>;
> + };
> +
> + /* Gain controlled by gpio using range */
> + amplifier1 {
> + compatible = "audio-gpio-amp";
> + vdd-supply = <&regulator>;
> + gain-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>, <&gpio 1 GPIO_ACTIVE_HIGH>;
> + gain-range = <(-300) 600>;
> + };
> +
> + /* Gain controlled by gpio using points */
> + amplifier2 {
> + compatible = "audio-gpio-amp";
> + vdd-supply = <&regulator>;
> + gain-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>, <&gpio 1 GPIO_ACTIVE_HIGH>;
> + gain-points = <0 (-1000)>, <1 300>, <2 0>, <3 600>;
> + };
> +
> + /* Gain controlled by gpio with labels */
> + amplifier3 {
> + compatible = "audio-gpio-amp";
> + vdd-supply = <&regulator>;
> + gain-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
> + gain-labels = "Low", "High";
> + };
> +
> + /* A mutable amplifier without any gain control */
> + amplifier4 {
> + compatible = "audio-gpio-amp";
> + vdd-supply = <&regulator>;
> + mute-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;

This case is just simple-amplifier...

> + };
> +
> + /* Several supplies, gain controlled using range, mute and bypass */
> + amplifier5 {
> + compatible = "audio-gpio-amp";
> + vdd-supply = <&regulator>;
> + vddio-supply = <&regulator1>;
> + vdda1-supply = <&regulator2>;
> + gain-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>, <&gpio 1 GPIO_ACTIVE_HIGH>;
> + gain-range = <(-300) 600>;
> + mute-gpios = <&gpio 2 GPIO_ACTIVE_HIGH>;
> + bypass-gpios = <&gpio 3 GPIO_ACTIVE_HIGH>;
> + };
> +...
> --
> 2.53.0
>