summaryrefslogtreecommitdiff
path: root/Documentation
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-03-16 04:13:07 +0300
committerMark Brown <broonie@kernel.org>2026-03-16 04:13:07 +0300
commit706d2dc0269e695979943f27b03389007e034db7 (patch)
tree7c5096a4f53a584fa3cf03f5901dafc62e6de8bf /Documentation
parent3e9cda2f4a33c6becc99f8a78946cbd02983852f (diff)
parentaf176d0787d219d9e07272988079ebb9be8efe6a (diff)
downloadlinux-706d2dc0269e695979943f27b03389007e034db7.tar.xz
ASoC: basic support for configuring bus keepers
James Calligeros <jcalligeros99@gmail.com> says: This series introduces some infrastructure to allow platform drivers to specify what a DAI should be doing when it is not active on the bus. The primary use case for this is configuring bus keepers which may be integrated into various codecs. The instigating use case for this functionality is an interesting bus topology on Apple Silicon laptops with multiple codecs. Most Apple Silicon laptops have six codecs split into groups of three, driving a pair of dual opposed woofers and a tweeter for L/R stereo sound. These codecs report the voltage and current across their connected voice coils back to the SoC via the SDOUT pin, represented as PCM data sent via configurable TDM slots. This data is used in conjunction with the connected speaker's Thiele/Small Parameters to ensure that the speaker is not being driven to levels that would permanently damage them. This is integrated into CoreAudio on macOS. speakersafetyd[1] handles this for Linux. All of the codec SDOUT pins are attached to a single receiver port on the SoC's I2S peripheral, however are split across two physical data lines (one each for the left and right codec groups). The receiver has an OR gate in front of it, which is used to sum the two lines. If at any point a codec is trying to transmit data, and the "opposite" line ends up floating high, the transmitting codec's data will be corrupted. We need to guarantee that the idle line stays idle. In the downstream Asahi Linux kernel[2], we set up one codec in each group to zero-fill or pull down its line while a codec on the opposite line is actively transmitting. This is done entirely in the codec driver, however this approach is over-fit for this one use case. This sort of functionality may also be of use for other hardware, so following previous mailing list discussions[3], I have tried to expose the functionality in a more configurable and generic way. I have integrated this approach into our downstream platform driver and select Devicetrees as an example of how this mechanism is intended to be used[4]. [1] https://github.com/AsahiLinux/speakersafetyd [2] https://github.com/AsahiLinux/linux/tree/bits/070-audio [3] https://lore.kernel.org/asahi/20250227-apple-codec-changes-v3-17-cbb130030acf@gmail.com/ [4] https://github.com/chadmed/tree/tdm-revised2 Link: https://patch.msgid.link/20260301-tdm-idle-slots-v3-0-c6ac5351489a@gmail.com
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-card.yaml9
-rw-r--r--Documentation/devicetree/bindings/sound/simple-card.yaml14
-rw-r--r--Documentation/devicetree/bindings/sound/tdm-slot.txt29
-rw-r--r--Documentation/devicetree/bindings/sound/tdm-slot.yaml52
4 files changed, 57 insertions, 47 deletions
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-card.yaml b/Documentation/devicetree/bindings/sound/imx-audio-card.yaml
index 3c75c8c78987..5424d4f16f52 100644
--- a/Documentation/devicetree/bindings/sound/imx-audio-card.yaml
+++ b/Documentation/devicetree/bindings/sound/imx-audio-card.yaml
@@ -24,6 +24,7 @@ patternProperties:
cpu/codec dais.
type: object
+ $ref: tdm-slot.yaml#
properties:
link-name:
@@ -38,13 +39,9 @@ patternProperties:
- i2s
- dsp_b
- dai-tdm-slot-num:
- description: see tdm-slot.txt.
- $ref: /schemas/types.yaml#/definitions/uint32
+ dai-tdm-slot-num: true
- dai-tdm-slot-width:
- description: see tdm-slot.txt.
- $ref: /schemas/types.yaml#/definitions/uint32
+ dai-tdm-slot-width: true
playback-only:
description: link is used only for playback
diff --git a/Documentation/devicetree/bindings/sound/simple-card.yaml b/Documentation/devicetree/bindings/sound/simple-card.yaml
index 533d0a1da56e..a14716b2732f 100644
--- a/Documentation/devicetree/bindings/sound/simple-card.yaml
+++ b/Documentation/devicetree/bindings/sound/simple-card.yaml
@@ -27,14 +27,6 @@ definitions:
description: dai-link uses bit clock inversion
$ref: /schemas/types.yaml#/definitions/flag
- dai-tdm-slot-num:
- description: see tdm-slot.txt.
- $ref: /schemas/types.yaml#/definitions/uint32
-
- dai-tdm-slot-width:
- description: see tdm-slot.txt.
- $ref: /schemas/types.yaml#/definitions/uint32
-
system-clock-frequency:
description: |
If a clock is specified and a multiplication factor is given with
@@ -115,6 +107,8 @@ definitions:
dai:
type: object
+ $ref: tdm-slot.yaml#
+
properties:
sound-dai:
maxItems: 1
@@ -133,10 +127,6 @@ definitions:
bitclock-master:
$ref: /schemas/types.yaml#/definitions/flag
- dai-tdm-slot-num:
- $ref: "#/definitions/dai-tdm-slot-num"
- dai-tdm-slot-width:
- $ref: "#/definitions/dai-tdm-slot-width"
clocks:
maxItems: 1
system-clock-frequency:
diff --git a/Documentation/devicetree/bindings/sound/tdm-slot.txt b/Documentation/devicetree/bindings/sound/tdm-slot.txt
deleted file mode 100644
index 4bb513ae62fc..000000000000
--- a/Documentation/devicetree/bindings/sound/tdm-slot.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-TDM slot:
-
-This specifies audio DAI's TDM slot.
-
-TDM slot properties:
-dai-tdm-slot-num : Number of slots in use.
-dai-tdm-slot-width : Width in bits for each slot.
-dai-tdm-slot-tx-mask : Transmit direction slot mask, optional
-dai-tdm-slot-rx-mask : Receive direction slot mask, optional
-
-For instance:
- dai-tdm-slot-num = <2>;
- dai-tdm-slot-width = <8>;
- dai-tdm-slot-tx-mask = <0 1>;
- dai-tdm-slot-rx-mask = <1 0>;
-
-And for each specified driver, there could be one .of_xlate_tdm_slot_mask()
-to specify an explicit mapping of the channels and the slots. If it's absent
-the default snd_soc_of_xlate_tdm_slot_mask() will be used to generating the
-tx and rx masks.
-
-For snd_soc_of_xlate_tdm_slot_mask(), the tx and rx masks will use a 1 bit
-for an active slot as default, and the default active bits are at the LSB of
-the masks.
-
-The explicit masks are given as array of integers, where the first
-number presents bit-0 (LSB), second presents bit-1, etc. Any non zero
-number is considered 1 and 0 is 0. snd_soc_of_xlate_tdm_slot_mask()
-does not do anything, if either mask is set non zero value.
diff --git a/Documentation/devicetree/bindings/sound/tdm-slot.yaml b/Documentation/devicetree/bindings/sound/tdm-slot.yaml
new file mode 100644
index 000000000000..457a899e8872
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/tdm-slot.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/tdm-slot.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Time Division Multiplexing (TDM) Slot Parameters
+
+maintainers:
+ - Liam Girdwood <lgirdwood@gmail.com>
+
+select: false
+
+properties:
+ dai-tdm-slot-num:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Number of slots in use
+
+ dai-tdm-slot-width:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Width, in bits, of each slot
+
+ dai-tdm-idle-mode:
+ $ref: /schemas/types.yaml#/definitions/string
+ enum:
+ - none
+ - off
+ - zero
+ - pulldown
+ - hiz
+ - pullup
+ - drivehigh
+ description: Drive mode for inactive/idle TDM slots. For hardware that
+ implements .set_tdm_idle(). Optional. "None" represents undefined
+ behaviour and is the same as not setting this property.
+
+patternProperties:
+ '^dai-tdm-slot-[rt]x-mask$':
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ description: Slot mask for active TDM slots. Optional. Drivers may
+ specify .xlate_tdm_slot_mask() to generate a slot mask dynamically. If
+ neither this property nor a driver-specific function are specified, the
+ default snd_soc_xlate_tdm_slot_mask() function will be used to generate
+ a mask. The first element of the array is slot 0 (LSB). Any nonzero
+ value will be treated as 1.
+
+ '^dai-tdm-slot-[rt]x-idle-mask$':
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Idle slot mask. Optional. A bit being set to 1 indicates
+ that the corresponding TDM slot is inactive/idle.
+
+additionalProperties: true