aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/da7213.txt45
-rw-r--r--Documentation/devicetree/bindings/sound/dlg,da7213.yaml103
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,imx-audio-es8328.yaml111
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audio-es8328.txt60
-rw-r--r--Documentation/devicetree/bindings/sound/pcm512x.txt53
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,apq8016-sbc-sndcard.yaml205
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,sm8250.yaml137
-rw-r--r--Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml4
-rw-r--r--Documentation/devicetree/bindings/sound/ti,pcm512x.yaml101
-rw-r--r--MAINTAINERS1
-rw-r--r--include/sound/soc-acpi-intel-match.h2
-rw-r--r--include/sound/soc-acpi.h2
-rw-r--r--include/sound/soc-dai.h5
-rw-r--r--include/sound/soc-dpcm.h1
-rw-r--r--include/sound/soc.h3
-rw-r--r--include/sound/soc_sdw_utils.h216
-rw-r--r--include/sound/tas2563-tlv.h279
-rw-r--r--include/sound/tas2781-tlv.h260
-rw-r--r--sound/soc/Kconfig2
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/amd/acp/Kconfig22
-rw-r--r--sound/soc/amd/acp/Makefile4
-rw-r--r--sound/soc/amd/acp/acp-sdw-sof-mach.c742
-rw-r--r--sound/soc/amd/acp/amd-acp63-acpi-match.c90
-rw-r--r--sound/soc/amd/acp/soc_amd_sdw_common.h44
-rw-r--r--sound/soc/amd/mach-config.h1
-rw-r--r--sound/soc/codecs/ak4613.c4
-rw-r--r--sound/soc/codecs/cs42l42-sdw.c12
-rw-r--r--sound/soc/codecs/cs43130.c73
-rw-r--r--sound/soc/codecs/es8326.c4
-rw-r--r--sound/soc/codecs/lpass-wsa-macro.c25
-rw-r--r--sound/soc/codecs/rt5682s.c4
-rw-r--r--sound/soc/codecs/sti-sas.c21
-rw-r--r--sound/soc/codecs/tas2781-comlib.c6
-rw-r--r--sound/soc/codecs/tas2781-i2c.c1
-rw-r--r--sound/soc/codecs/wcd937x.h34
-rw-r--r--sound/soc/codecs/wcd938x.c18
-rw-r--r--sound/soc/codecs/wcd938x.h4
-rw-r--r--sound/soc/codecs/wcd939x.h6
-rw-r--r--sound/soc/codecs/wsa881x.c44
-rw-r--r--sound/soc/codecs/wsa883x.c75
-rw-r--r--sound/soc/codecs/wsa884x.c39
-rw-r--r--sound/soc/fsl/lpc3xxx-i2s.c11
-rw-r--r--sound/soc/fsl/lpc3xxx-pcm.c2
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c2
-rw-r--r--sound/soc/generic/test-component.c9
-rw-r--r--sound/soc/intel/boards/Kconfig1
-rw-r--r--sound/soc/intel/boards/Makefile9
-rw-r--r--sound/soc/intel/boards/sof_sdw.c1142
-rw-r--r--sound/soc/intel/boards/sof_sdw_common.h166
-rw-r--r--sound/soc/intel/boards/sof_sdw_hdmi.c14
-rw-r--r--sound/soc/intel/common/Makefile1
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-ptl-match.c145
-rw-r--r--sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c4
-rw-r--r--sound/soc/sdw_utils/Kconfig6
-rw-r--r--sound/soc/sdw_utils/Makefile11
-rw-r--r--sound/soc/sdw_utils/soc_sdw_bridge_cs35l56.c (renamed from sound/soc/intel/boards/bridge_cs35l56.c)56
-rw-r--r--sound/soc/sdw_utils/soc_sdw_cs42l42.c (renamed from sound/soc/intel/boards/sof_sdw_cs42l42.c)13
-rw-r--r--sound/soc/sdw_utils/soc_sdw_cs42l43.c (renamed from sound/soc/intel/boards/sof_sdw_cs42l43.c)38
-rw-r--r--sound/soc/sdw_utils/soc_sdw_cs_amp.c (renamed from sound/soc/intel/boards/sof_sdw_cs_amp.c)18
-rw-r--r--sound/soc/sdw_utils/soc_sdw_dmic.c (renamed from sound/soc/intel/boards/sof_sdw_dmic.c)10
-rw-r--r--sound/soc/sdw_utils/soc_sdw_maxim.c (renamed from sound/soc/intel/boards/sof_sdw_maxim.c)56
-rw-r--r--sound/soc/sdw_utils/soc_sdw_rt5682.c (renamed from sound/soc/intel/boards/sof_sdw_rt5682.c)12
-rw-r--r--sound/soc/sdw_utils/soc_sdw_rt700.c (renamed from sound/soc/intel/boards/sof_sdw_rt700.c)12
-rw-r--r--sound/soc/sdw_utils/soc_sdw_rt711.c (renamed from sound/soc/intel/boards/sof_sdw_rt711.c)38
-rw-r--r--sound/soc/sdw_utils/soc_sdw_rt712_sdca.c (renamed from sound/soc/intel/boards/sof_sdw_rt712_sdca.c)10
-rw-r--r--sound/soc/sdw_utils/soc_sdw_rt722_sdca.c (renamed from sound/soc/intel/boards/sof_sdw_rt722_sdca.c)10
-rw-r--r--sound/soc/sdw_utils/soc_sdw_rt_amp.c (renamed from sound/soc/intel/boards/sof_sdw_rt_amp.c)32
-rw-r--r--sound/soc/sdw_utils/soc_sdw_rt_amp_coeff_tables.h (renamed from sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h)6
-rw-r--r--sound/soc/sdw_utils/soc_sdw_rt_dmic.c (renamed from sound/soc/intel/boards/sof_sdw_rt_dmic.c)11
-rw-r--r--sound/soc/sdw_utils/soc_sdw_rt_sdca_jack_common.c (renamed from sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c)40
-rw-r--r--sound/soc/sdw_utils/soc_sdw_utils.c990
-rw-r--r--sound/soc/sh/Kconfig1
-rw-r--r--sound/soc/sh/rcar/adg.c4
-rw-r--r--sound/soc/sh/rcar/core.c17
-rw-r--r--sound/soc/sh/rcar/dma.c75
-rw-r--r--sound/soc/sh/rcar/rsnd.h10
-rw-r--r--sound/soc/sh/rcar/ssi.c2
-rw-r--r--sound/soc/sh/rz-ssi.c257
-rw-r--r--sound/soc/soc-core.c21
-rw-r--r--sound/soc/soc-dai.c20
-rw-r--r--sound/soc/soc-dapm.c3
-rw-r--r--sound/soc/soc-pcm.c77
-rw-r--r--sound/soc/sof/amd/Kconfig1
-rw-r--r--sound/soc/sof/amd/acp-common.c3
-rw-r--r--sound/soc/sof/amd/acp.c1
-rw-r--r--sound/soc/sof/amd/acp.h1
-rw-r--r--sound/soc/sof/amd/pci-acp63.c1
-rw-r--r--sound/soc/sof/intel/Kconfig17
-rw-r--r--sound/soc/sof/intel/Makefile2
-rw-r--r--sound/soc/sof/intel/hda-dsp.c1
-rw-r--r--sound/soc/sof/intel/hda-stream.c4
-rw-r--r--sound/soc/sof/intel/hda.h1
-rw-r--r--sound/soc/sof/intel/lnl.c27
-rw-r--r--sound/soc/sof/intel/mtl.c16
-rw-r--r--sound/soc/sof/intel/mtl.h2
-rw-r--r--sound/soc/sof/intel/pci-ptl.c77
-rw-r--r--sound/soc/sof/intel/shim.h1
-rw-r--r--sound/soc/sof/pcm.c2
-rw-r--r--sound/soc/sof/sof-audio.h4
-rw-r--r--sound/soc/sof/sof-priv.h16
-rw-r--r--sound/soc/stm/stm32_i2s.c4
-rw-r--r--sound/soc/tegra/tegra210_i2s.c16
-rw-r--r--sound/soc/tegra/tegra_pcm.c2
104 files changed, 4002 insertions, 2423 deletions
diff --git a/Documentation/devicetree/bindings/sound/da7213.txt b/Documentation/devicetree/bindings/sound/da7213.txt
deleted file mode 100644
index 94584c96c4ae..000000000000
--- a/Documentation/devicetree/bindings/sound/da7213.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-Dialog Semiconductor DA7212/DA7213 Audio Codec bindings
-
-======
-
-Required properties:
-- compatible : Should be "dlg,da7212" or "dlg,da7213"
-- reg: Specifies the I2C slave address
-
-Optional properties:
-- clocks : phandle and clock specifier for codec MCLK.
-- clock-names : Clock name string for 'clocks' attribute, should be "mclk".
-
-- dlg,micbias1-lvl : Voltage (mV) for Mic Bias 1
- [<1600>, <2200>, <2500>, <3000>]
-- dlg,micbias2-lvl : Voltage (mV) for Mic Bias 2
- [<1600>, <2200>, <2500>, <3000>]
-- dlg,dmic-data-sel : DMIC channel select based on clock edge.
- ["lrise_rfall", "lfall_rrise"]
-- dlg,dmic-samplephase : When to sample audio from DMIC.
- ["on_clkedge", "between_clkedge"]
-- dlg,dmic-clkrate : DMIC clock frequency (Hz).
- [<1500000>, <3000000>]
-
- - VDDA-supply : Regulator phandle for Analogue power supply
- - VDDMIC-supply : Regulator phandle for Mic Bias
- - VDDIO-supply : Regulator phandle for I/O power supply
-
-======
-
-Example:
-
- codec_i2c: da7213@1a {
- compatible = "dlg,da7213";
- reg = <0x1a>;
-
- clocks = <&clks 201>;
- clock-names = "mclk";
-
- dlg,micbias1-lvl = <2500>;
- dlg,micbias2-lvl = <2500>;
-
- dlg,dmic-data-sel = "lrise_rfall";
- dlg,dmic-samplephase = "between_clkedge";
- dlg,dmic-clkrate = <3000000>;
- };
diff --git a/Documentation/devicetree/bindings/sound/dlg,da7213.yaml b/Documentation/devicetree/bindings/sound/dlg,da7213.yaml
new file mode 100644
index 000000000000..c2dede1e82ff
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/dlg,da7213.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/dlg,da7213.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Dialog Semiconductor DA7212/DA7213 Audio Codec
+
+maintainers:
+ - Support Opensource <[email protected]>
+
+allOf:
+ - $ref: dai-common.yaml#
+
+properties:
+ compatible:
+ enum:
+ - dlg,da7212
+ - dlg,da7213
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ const: mclk
+
+ "#sound-dai-cells":
+ const: 0
+
+ dlg,micbias1-lvl:
+ description: Voltage (mV) for Mic Bias 1
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 1600, 2200, 2500, 3000 ]
+
+ dlg,micbias2-lvl:
+ description: Voltage (mV) for Mic Bias 2
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 1600, 2200, 2500, 3000 ]
+
+ dlg,dmic-data-sel:
+ description: DMIC channel select based on clock edge
+ enum: [ lrise_rfall, lfall_rrise ]
+
+ dlg,dmic-samplephase:
+ description: When to sample audio from DMIC
+ enum: [ on_clkedge, between_clkedge ]
+
+ dlg,dmic-clkrate:
+ description: DMIC clock frequency (Hz)
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [ 1500000, 3000000 ]
+
+ VDDA-supply:
+ description: Analogue power supply
+
+ VDDIO-supply:
+ description: I/O power supply
+
+ VDDMIC-supply:
+ description: Mic Bias
+
+ VDDSP-supply:
+ description: Speaker supply
+
+ ports:
+ $ref: audio-graph-port.yaml#/definitions/ports
+
+ port:
+ $ref: audio-graph-port.yaml#
+ unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ codec@1a {
+ compatible = "dlg,da7213";
+ reg = <0x1a>;
+
+ clocks = <&clks 201>;
+ clock-names = "mclk";
+
+ #sound-dai-cells = <0>;
+
+ dlg,micbias1-lvl = <2500>;
+ dlg,micbias2-lvl = <2500>;
+
+ dlg,dmic-data-sel = "lrise_rfall";
+ dlg,dmic-samplephase = "between_clkedge";
+ dlg,dmic-clkrate = <3000000>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/sound/fsl,imx-audio-es8328.yaml b/Documentation/devicetree/bindings/sound/fsl,imx-audio-es8328.yaml
new file mode 100644
index 000000000000..5eb6f5812cf2
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,imx-audio-es8328.yaml
@@ -0,0 +1,111 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl,imx-audio-es8328.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX audio complex with ES8328 codec
+
+maintainers:
+ - Shawn Guo <[email protected]>
+ - Sascha Hauer <[email protected]>
+
+allOf:
+ - $ref: sound-card-common.yaml#
+
+properties:
+ compatible:
+ const: fsl,imx-audio-es8328
+
+ model:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: The user-visible name of this sound complex
+
+ ssi-controller:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: The phandle of the i.MX SSI controller
+
+ jack-gpio:
+ description: Optional GPIO for headphone jack
+ maxItems: 1
+
+ audio-amp-supply:
+ description: Power regulator for speaker amps
+
+ audio-codec:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: The phandle to the ES8328 audio codec
+
+ audio-routing:
+ $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+ description: |
+ A list of the connections between audio components. Each entry
+ is a pair of strings, the first being the connection's sink, the second
+ being the connection's source. Valid names could be power supplies,
+ ES8328 pins, and the jacks on the board:
+
+ Power supplies:
+ * audio-amp
+
+ ES8328 pins:
+ * LOUT1
+ * LOUT2
+ * ROUT1
+ * ROUT2
+ * LINPUT1
+ * LINPUT2
+ * RINPUT1
+ * RINPUT2
+ * Mic PGA
+
+ Board connectors:
+ * Headphone
+ * Speaker
+ * Mic Jack
+
+ mux-int-port:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: The internal port of the i.MX audio muxer (AUDMUX)
+ enum: [1, 2, 7]
+ default: 1
+
+ mux-ext-port:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: The external port of the i.MX audio muxer (AUDMIX)
+ enum: [3, 4, 5, 6]
+ default: 3
+
+required:
+ - compatible
+ - model
+ - ssi-controller
+ - jack-gpio
+ - audio-amp-supply
+ - audio-codec
+ - audio-routing
+ - mux-int-port
+ - mux-ext-port
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ sound {
+ compatible = "fsl,imx-audio-es8328";
+ model = "imx-audio-es8328";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ jack-gpio = <&gpio5 15 0>;
+ audio-amp-supply = <&reg_audio_amp>;
+ audio-routing =
+ "Speaker", "LOUT2",
+ "Speaker", "ROUT2",
+ "Speaker", "audio-amp",
+ "Headphone", "ROUT1",
+ "Headphone", "LOUT1",
+ "LINPUT1", "Mic Jack",
+ "RINPUT1", "Mic Jack",
+ "Mic Jack", "Mic Bias";
+ mux-int-port = <1>;
+ mux-ext-port = <3>;
+ };
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-es8328.txt b/Documentation/devicetree/bindings/sound/imx-audio-es8328.txt
deleted file mode 100644
index 07b68ab206fb..000000000000
--- a/Documentation/devicetree/bindings/sound/imx-audio-es8328.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-Freescale i.MX audio complex with ES8328 codec
-
-Required properties:
-- compatible : "fsl,imx-audio-es8328"
-- model : The user-visible name of this sound complex
-- ssi-controller : The phandle of the i.MX SSI controller
-- jack-gpio : Optional GPIO for headphone jack
-- audio-amp-supply : Power regulator for speaker amps
-- audio-codec : The phandle of the ES8328 audio codec
-- audio-routing : A list of the connections between audio components.
- Each entry is a pair of strings, the first being the
- connection's sink, the second being the connection's
- source. Valid names could be power supplies, ES8328
- pins, and the jacks on the board:
-
- Power supplies:
- * audio-amp
-
- ES8328 pins:
- * LOUT1
- * LOUT2
- * ROUT1
- * ROUT2
- * LINPUT1
- * LINPUT2
- * RINPUT1
- * RINPUT2
- * Mic PGA
-
- Board connectors:
- * Headphone
- * Speaker
- * Mic Jack
-- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
-- mux-ext-port : The external port of the i.MX audio muxer (AUDMIX)
-
-Note: The AUDMUX port numbering should start at 1, which is consistent with
-hardware manual.
-
-Example:
-
-sound {
- compatible = "fsl,imx-audio-es8328";
- model = "imx-audio-es8328";
- ssi-controller = <&ssi1>;
- audio-codec = <&codec>;
- jack-gpio = <&gpio5 15 0>;
- audio-amp-supply = <&reg_audio_amp>;
- audio-routing =
- "Speaker", "LOUT2",
- "Speaker", "ROUT2",
- "Speaker", "audio-amp",
- "Headphone", "ROUT1",
- "Headphone", "LOUT1",
- "LINPUT1", "Mic Jack",
- "RINPUT1", "Mic Jack",
- "Mic Jack", "Mic Bias";
- mux-int-port = <1>;
- mux-ext-port = <3>;
-};
diff --git a/Documentation/devicetree/bindings/sound/pcm512x.txt b/Documentation/devicetree/bindings/sound/pcm512x.txt
deleted file mode 100644
index 47878a6df608..000000000000
--- a/Documentation/devicetree/bindings/sound/pcm512x.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-PCM512x and TAS575x audio CODECs/amplifiers
-
-These devices support both I2C and SPI (configured with pin strapping
-on the board). The TAS575x devices only support I2C.
-
-Required properties:
-
- - compatible : One of "ti,pcm5121", "ti,pcm5122", "ti,pcm5141",
- "ti,pcm5142", "ti,pcm5242", "ti,tas5754" or "ti,tas5756"
-
- - reg : the I2C address of the device for I2C, the chip select
- number for SPI.
-
- - AVDD-supply, DVDD-supply, and CPVDD-supply : power supplies for the
- device, as covered in bindings/regulator/regulator.txt
-
-Optional properties:
-
- - clocks : A clock specifier for the clock connected as SCLK. If this
- is absent the device will be configured to clock from BCLK. If pll-in
- and pll-out are specified in addition to a clock, the device is
- configured to accept clock input on a specified gpio pin.
-
- - pll-in, pll-out : gpio pins used to connect the pll using <1>
- through <6>. The device will be configured for clock input on the
- given pll-in pin and PLL output on the given pll-out pin. An
- external connection from the pll-out pin to the SCLK pin is assumed.
- Caution: the TAS-desvices only support gpios 1,2 and 3
-
-Examples:
-
- pcm5122: pcm5122@4c {
- compatible = "ti,pcm5122";
- reg = <0x4c>;
-
- AVDD-supply = <&reg_3v3_analog>;
- DVDD-supply = <&reg_1v8>;
- CPVDD-supply = <&reg_3v3>;
- };
-
-
- pcm5142: pcm5142@4c {
- compatible = "ti,pcm5142";
- reg = <0x4c>;
-
- AVDD-supply = <&reg_3v3_analog>;
- DVDD-supply = <&reg_1v8>;
- CPVDD-supply = <&reg_3v3>;
-
- clocks = <&sck>;
- pll-in = <3>;
- pll-out = <6>;
- };
diff --git a/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc-sndcard.yaml b/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc-sndcard.yaml
new file mode 100644
index 000000000000..6ad451549036
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/qcom,apq8016-sbc-sndcard.yaml
@@ -0,0 +1,205 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/qcom,apq8016-sbc-sndcard.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm APQ8016 and similar sound cards
+
+maintainers:
+ - Srinivas Kandagatla <[email protected]>
+ - Stephan Gerhold <[email protected]>
+
+properties:
+ compatible:
+ enum:
+ - qcom,apq8016-sbc-sndcard
+ - qcom,msm8916-qdsp6-sndcard
+
+ reg:
+ items:
+ - description: Microphone I/O mux register address
+ - description: Speaker I/O mux register address
+
+ reg-names:
+ items:
+ - const: mic-iomux
+ - const: spkr-iomux
+
+ audio-routing:
+ $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+ description:
+ A list of the connections between audio components. Each entry is a
+ pair of strings, the first being the connection's sink, the second
+ being the connection's source. Valid names could be power supplies,
+ MicBias of codec and the jacks on the board.
+
+ aux-devs:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ description: |
+ List of phandles pointing to auxiliary devices, such
+ as amplifiers, to be added to the sound card.
+
+ model:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: User visible long sound card name
+
+ pin-switches:
+ description: List of widget names for which pin switches should be created.
+ $ref: /schemas/types.yaml#/definitions/string-array
+
+ widgets:
+ description: User specified audio sound widgets.
+ $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+
+patternProperties:
+ ".*-dai-link$":
+ description:
+ Each subnode represents a dai link. Subnodes of each dai links would be
+ cpu/codec dais.
+
+ type: object
+
+ properties:
+ link-name:
+ description: Indicates dai-link name and PCM stream name.
+ $ref: /schemas/types.yaml#/definitions/string
+ maxItems: 1
+
+ cpu:
+ description: Holds subnode which indicates cpu dai.
+ type: object
+ additionalProperties: false
+
+ properties:
+ sound-dai:
+ maxItems: 1
+
+ platform:
+ description: Holds subnode which indicates platform dai.
+ type: object
+ additionalProperties: false
+
+ properties:
+ sound-dai:
+ maxItems: 1
+
+ codec:
+ description: Holds subnode which indicates codec dai.
+ type: object
+ additionalProperties: false
+
+ properties:
+ sound-dai:
+ minItems: 1
+ maxItems: 8
+
+ required:
+ - link-name
+ - cpu
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - model
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/sound/qcom,lpass.h>
+ sound@7702000 {
+ compatible = "qcom,apq8016-sbc-sndcard";
+ reg = <0x07702000 0x4>, <0x07702004 0x4>;
+ reg-names = "mic-iomux", "spkr-iomux";
+
+ model = "DB410c";
+ audio-routing =
+ "AMIC2", "MIC BIAS Internal2",
+ "AMIC3", "MIC BIAS External1";
+
+ pinctrl-0 = <&cdc_pdm_lines_act &ext_sec_tlmm_lines_act &ext_mclk_tlmm_lines_act>;
+ pinctrl-1 = <&cdc_pdm_lines_sus &ext_sec_tlmm_lines_sus &ext_mclk_tlmm_lines_sus>;
+ pinctrl-names = "default", "sleep";
+
+ quaternary-dai-link {
+ link-name = "ADV7533";
+ cpu {
+ sound-dai = <&lpass MI2S_QUATERNARY>;
+ };
+ codec {
+ sound-dai = <&adv_bridge 0>;
+ };
+ };
+
+ primary-dai-link {
+ link-name = "WCD";
+ cpu {
+ sound-dai = <&lpass MI2S_PRIMARY>;
+ };
+ codec {
+ sound-dai = <&lpass_codec 0>, <&wcd_codec 0>;
+ };
+ };
+
+ tertiary-dai-link {
+ link-name = "WCD-Capture";
+ cpu {
+ sound-dai = <&lpass MI2S_TERTIARY>;
+ };
+ codec {
+ sound-dai = <&lpass_codec 1>, <&wcd_codec 1>;
+ };
+ };
+ };
+
+ - |
+ #include <dt-bindings/sound/qcom,q6afe.h>
+ #include <dt-bindings/sound/qcom,q6asm.h>
+ sound@7702000 {
+ compatible = "qcom,msm8916-qdsp6-sndcard";
+ reg = <0x07702000 0x4>, <0x07702004 0x4>;
+ reg-names = "mic-iomux", "spkr-iomux";
+
+ model = "msm8916";
+ widgets =
+ "Speaker", "Speaker",
+ "Headphone", "Headphones";
+ pin-switches = "Speaker";
+ audio-routing =
+ "Speaker", "Speaker Amp OUT",
+ "Speaker Amp IN", "HPH_R",
+ "Headphones", "HPH_L",
+ "Headphones", "HPH_R",
+ "AMIC1", "MIC BIAS Internal1",
+ "AMIC2", "MIC BIAS Internal2",
+ "AMIC3", "MIC BIAS Internal3";
+ aux-devs = <&speaker_amp>;
+
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cdc_pdm_lines_act>;
+ pinctrl-1 = <&cdc_pdm_lines_sus>;
+
+ mm1-dai-link {
+ link-name = "MultiMedia1";
+ cpu {
+ sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>;
+ };
+ };
+
+ primary-dai-link {
+ link-name = "Primary MI2S";
+ cpu {
+ sound-dai = <&q6afedai PRIMARY_MI2S_RX>;
+ };
+ platform {
+ sound-dai = <&q6routing>;
+ };
+ codec {
+ sound-dai = <&lpass_codec 0>, <&wcd_codec 0>;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
index c9076dcd44c1..1d3acdc0c733 100644
--- a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
@@ -27,9 +27,7 @@ properties:
- qcom,sm8650-sndcard
- const: qcom,sm8450-sndcard
- enum:
- - qcom,apq8016-sbc-sndcard
- qcom,apq8096-sndcard
- - qcom,msm8916-qdsp6-sndcard
- qcom,qcm6490-idp-sndcard
- qcom,qcs6490-rb3gen2-sndcard
- qcom,qrb5165-rb5-sndcard
@@ -58,18 +56,6 @@ properties:
$ref: /schemas/types.yaml#/definitions/string
description: User visible long sound card name
- pin-switches:
- description: List of widget names for which pin switches should be created.
- $ref: /schemas/types.yaml#/definitions/string-array
-
- widgets:
- description: User specified audio sound widgets.
- $ref: /schemas/types.yaml#/definitions/non-unique-string-array
-
- # Only valid for some compatibles (see allOf if below)
- reg: true
- reg-names: true
-
patternProperties:
".*-dai-link$":
description:
@@ -122,34 +108,6 @@ required:
- compatible
- model
-allOf:
- - if:
- properties:
- compatible:
- contains:
- enum:
- - qcom,apq8016-sbc-sndcard
- - qcom,msm8916-qdsp6-sndcard
- then:
- properties:
- reg:
- items:
- - description: Microphone I/O mux register address
- - description: Speaker I/O mux register address
- reg-names:
- items:
- - const: mic-iomux
- - const: spkr-iomux
- required:
- - compatible
- - model
- - reg
- - reg-names
- else:
- properties:
- reg: false
- reg-names: false
-
additionalProperties: false
examples:
@@ -231,98 +189,3 @@ examples:
};
};
};
-
- - |
- #include <dt-bindings/sound/qcom,lpass.h>
- sound@7702000 {
- compatible = "qcom,apq8016-sbc-sndcard";
- reg = <0x07702000 0x4>, <0x07702004 0x4>;
- reg-names = "mic-iomux", "spkr-iomux";
-
- model = "DB410c";
- audio-routing =
- "AMIC2", "MIC BIAS Internal2",
- "AMIC3", "MIC BIAS External1";
-
- pinctrl-0 = <&cdc_pdm_lines_act &ext_sec_tlmm_lines_act &ext_mclk_tlmm_lines_act>;
- pinctrl-1 = <&cdc_pdm_lines_sus &ext_sec_tlmm_lines_sus &ext_mclk_tlmm_lines_sus>;
- pinctrl-names = "default", "sleep";
-
- quaternary-dai-link {
- link-name = "ADV7533";
- cpu {
- sound-dai = <&lpass MI2S_QUATERNARY>;
- };
- codec {
- sound-dai = <&adv_bridge 0>;
- };
- };
-
- primary-dai-link {
- link-name = "WCD";
- cpu {
- sound-dai = <&lpass MI2S_PRIMARY>;
- };
- codec {
- sound-dai = <&lpass_codec 0>, <&wcd_codec 0>;
- };
- };
-
- tertiary-dai-link {
- link-name = "WCD-Capture";
- cpu {
- sound-dai = <&lpass MI2S_TERTIARY>;
- };
- codec {
- sound-dai = <&lpass_codec 1>, <&wcd_codec 1>;
- };
- };
- };
-
- - |
- #include <dt-bindings/sound/qcom,q6afe.h>
- #include <dt-bindings/sound/qcom,q6asm.h>
- sound@7702000 {
- compatible = "qcom,msm8916-qdsp6-sndcard";
- reg = <0x07702000 0x4>, <0x07702004 0x4>;
- reg-names = "mic-iomux", "spkr-iomux";
-
- model = "msm8916";
- widgets =
- "Speaker", "Speaker",
- "Headphone", "Headphones";
- pin-switches = "Speaker";
- audio-routing =
- "Speaker", "Speaker Amp OUT",
- "Speaker Amp IN", "HPH_R",
- "Headphones", "HPH_L",
- "Headphones", "HPH_R",
- "AMIC1", "MIC BIAS Internal1",
- "AMIC2", "MIC BIAS Internal2",
- "AMIC3", "MIC BIAS Internal3";
- aux-devs = <&speaker_amp>;
-
- pinctrl-names = "default", "sleep";
- pinctrl-0 = <&cdc_pdm_lines_act>;
- pinctrl-1 = <&cdc_pdm_lines_sus>;
-
- mm1-dai-link {
- link-name = "MultiMedia1";
- cpu {
- sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>;
- };
- };
-
- primary-dai-link {
- link-name = "Primary MI2S";
- cpu {
- sound-dai = <&q6afedai PRIMARY_MI2S_RX>;
- };
- platform {
- sound-dai = <&q6routing>;
- };
- codec {
- sound-dai = <&lpass_codec 0>, <&wcd_codec 0>;
- };
- };
- };
diff --git a/Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml b/Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml
index 8b9695f5decc..f4610eaed1e1 100644
--- a/Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml
+++ b/Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml
@@ -87,6 +87,10 @@ properties:
'#sound-dai-cells':
const: 0
+ port:
+ $ref: audio-graph-port.yaml#/definitions/port-base
+ description: Connection to controller providing I2S signals
+
required:
- compatible
- reg
diff --git a/Documentation/devicetree/bindings/sound/ti,pcm512x.yaml b/Documentation/devicetree/bindings/sound/ti,pcm512x.yaml
new file mode 100644
index 000000000000..21ea9ff5a2bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ti,pcm512x.yaml
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/ti,pcm512x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: PCM512x and TAS575x audio CODECs/amplifiers
+
+maintainers:
+ - Animesh Agarwal <[email protected]>
+
+allOf:
+ - $ref: dai-common.yaml#
+
+properties:
+ compatible:
+ enum:
+ - ti,pcm5121
+ - ti,pcm5122
+ - ti,pcm5141
+ - ti,pcm5142
+ - ti,pcm5242
+ - ti,tas5754
+ - ti,tas5756
+
+ reg:
+ maxItems: 1
+
+ AVDD-supply: true
+
+ DVDD-supply: true
+
+ CPVDD-supply: true
+
+ clocks:
+ maxItems: 1
+ description: A clock specifier for the clock connected as SCLK. If this is
+ absent the device will be configured to clock from BCLK. If pll-in and
+ pll-out are specified in addition to a clock, the device is configured to
+ accept clock input on a specified gpio pin.
+
+ '#sound-dai-cells':
+ const: 0
+
+ pll-in:
+ description: GPIO pin used to connect the pll using <1> through <6>. The
+ device will be configured for clock input on the given pll-in pin.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 1
+ maximum: 6
+
+ pll-out:
+ description: GPIO pin used to connect the pll using <1> through <6>. The
+ device will be configured for PLL output on the given pll-out pin. An
+ external connection from the pll-out pin to the SCLK pin is assumed.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 1
+ maximum: 6
+
+required:
+ - compatible
+ - reg
+ - AVDD-supply
+ - DVDD-supply
+ - CPVDD-supply
+
+if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - ti,tas5754
+ - ti,tas5756
+
+then:
+ properties:
+ pll-in:
+ maximum: 3
+
+ pll-out:
+ maximum: 3
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ codec@4c {
+ compatible = "ti,pcm5142";
+ reg = <0x4c>;
+ AVDD-supply = <&reg_3v3_analog>;
+ DVDD-supply = <&reg_1v8>;
+ CPVDD-supply = <&reg_3v3>;
+ #sound-dai-cells = <0>;
+ clocks = <&sck>;
+ pll-in = <3>;
+ pll-out = <6>;
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 42decde38320..88a40557db32 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6500,6 +6500,7 @@ F: Documentation/devicetree/bindings/regulator/da92*.txt
F: Documentation/devicetree/bindings/regulator/dlg,da9*.yaml
F: Documentation/devicetree/bindings/regulator/dlg,slg51000.yaml
F: Documentation/devicetree/bindings/sound/da[79]*.txt
+F: Documentation/devicetree/bindings/sound/dlg,da7213.yaml
F: Documentation/devicetree/bindings/thermal/dlg,da9062-thermal.yaml
F: Documentation/devicetree/bindings/watchdog/dlg,da9062-watchdog.yaml
F: Documentation/hwmon/da90??.rst
diff --git a/include/sound/soc-acpi-intel-match.h b/include/sound/soc-acpi-intel-match.h
index 4843b57798f6..daed7123df9d 100644
--- a/include/sound/soc-acpi-intel-match.h
+++ b/include/sound/soc-acpi-intel-match.h
@@ -33,6 +33,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cfl_sdw_machines[];
@@ -44,6 +45,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[];
/*
* generic table used for HDA codec-based platforms, possibly with
diff --git a/include/sound/soc-acpi.h b/include/sound/soc-acpi.h
index 38ccec4e3fcd..b6d301946244 100644
--- a/include/sound/soc-acpi.h
+++ b/include/sound/soc-acpi.h
@@ -70,6 +70,7 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
* @dai_drivers: pointer to dai_drivers, used e.g. in nocodec mode
* @subsystem_vendor: optional PCI SSID vendor value
* @subsystem_device: optional PCI SSID device value
+ * @subsystem_rev: optional PCI SSID revision value
* @subsystem_id_set: true if a value has been written to
* subsystem_vendor and subsystem_device.
*/
@@ -86,6 +87,7 @@ struct snd_soc_acpi_mach_params {
struct snd_soc_dai_driver *dai_drivers;
unsigned short subsystem_vendor;
unsigned short subsystem_device;
+ unsigned short subsystem_rev;
bool subsystem_id_set;
};
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index bbb72ad4c951..ab4e109fe71d 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -240,8 +240,6 @@ int snd_soc_pcm_dai_new(struct snd_soc_pcm_runtime *rtd);
int snd_soc_pcm_dai_prepare(struct snd_pcm_substream *substream);
int snd_soc_pcm_dai_trigger(struct snd_pcm_substream *substream, int cmd,
int rollback);
-int snd_soc_pcm_dai_bespoke_trigger(struct snd_pcm_substream *substream,
- int cmd);
void snd_soc_pcm_dai_delay(struct snd_pcm_substream *substream,
snd_pcm_sframes_t *cpu_delay, snd_pcm_sframes_t *codec_delay);
@@ -345,8 +343,7 @@ struct snd_soc_dai_ops {
*/
int (*trigger)(struct snd_pcm_substream *, int,
struct snd_soc_dai *);
- int (*bespoke_trigger)(struct snd_pcm_substream *, int,
- struct snd_soc_dai *);
+
/*
* For hardware based FIFO caused delay reporting.
* Optional.
diff --git a/include/sound/soc-dpcm.h b/include/sound/soc-dpcm.h
index ebd24753dd00..773f2db8c31c 100644
--- a/include/sound/soc-dpcm.h
+++ b/include/sound/soc-dpcm.h
@@ -58,7 +58,6 @@ enum snd_soc_dpcm_state {
enum snd_soc_dpcm_trigger {
SND_SOC_DPCM_TRIGGER_PRE = 0,
SND_SOC_DPCM_TRIGGER_POST,
- SND_SOC_DPCM_TRIGGER_BESPOKE,
};
/*
diff --git a/include/sound/soc.h b/include/sound/soc.h
index a8e66bbf932b..e844f6afc5b5 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1209,8 +1209,9 @@ struct snd_soc_pcm_runtime {
bool initialized;
+ /* CPU/Codec/Platform */
int num_components;
- struct snd_soc_component *components[]; /* CPU/Codec/Platform */
+ struct snd_soc_component *components[] __counted_by(num_components);
};
/* see soc_new_pcm_runtime() */
diff --git a/include/sound/soc_sdw_utils.h b/include/sound/soc_sdw_utils.h
new file mode 100644
index 000000000000..e366b7968c2d
--- /dev/null
+++ b/include/sound/soc_sdw_utils.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * This file incorporates work covered by the following copyright notice:
+ * Copyright (c) 2020 Intel Corporation
+ * Copyright(c) 2024 Advanced Micro Devices, Inc.
+ *
+ */
+
+#ifndef SOC_SDW_UTILS_H
+#define SOC_SDW_UTILS_H
+
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
+
+#define SOC_SDW_MAX_DAI_NUM 8
+#define SOC_SDW_MAX_NO_PROPS 2
+#define SOC_SDW_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0))
+
+/* If a CODEC has an optional speaker output, this quirk will enable it */
+#define SOC_SDW_CODEC_SPKR BIT(15)
+/*
+ * If the CODEC has additional devices attached directly to it.
+ *
+ * For the cs42l43:
+ * - 0 - No speaker output
+ * - SOC_SDW_CODEC_SPKR - CODEC internal speaker
+ * - SOC_SDW_SIDECAR_AMPS - 2x Sidecar amplifiers + CODEC internal speaker
+ * - SOC_SDW_CODEC_SPKR | SOF_SIDECAR_AMPS - Not currently supported
+ */
+#define SOC_SDW_SIDECAR_AMPS BIT(16)
+
+#define SOC_SDW_UNUSED_DAI_ID -1
+#define SOC_SDW_JACK_OUT_DAI_ID 0
+#define SOC_SDW_JACK_IN_DAI_ID 1
+#define SOC_SDW_AMP_OUT_DAI_ID 2
+#define SOC_SDW_AMP_IN_DAI_ID 3
+#define SOC_SDW_DMIC_DAI_ID 4
+
+#define SOC_SDW_DAI_TYPE_JACK 0
+#define SOC_SDW_DAI_TYPE_AMP 1
+#define SOC_SDW_DAI_TYPE_MIC 2
+
+struct asoc_sdw_codec_info;
+
+struct asoc_sdw_dai_info {
+ const bool direction[2]; /* playback & capture support */
+ const char *dai_name;
+ const int dai_type;
+ const int dailink[2]; /* dailink id for each direction */
+ const struct snd_kcontrol_new *controls;
+ const int num_controls;
+ const struct snd_soc_dapm_widget *widgets;
+ const int num_widgets;
+ int (*init)(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback);
+ int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
+ int (*rtd_init)(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+ bool rtd_init_done; /* Indicate that the rtd_init callback is done */
+ unsigned long quirk;
+};
+
+struct asoc_sdw_codec_info {
+ const int part_id;
+ const int version_id;
+ const char *codec_name;
+ int amp_num;
+ const u8 acpi_id[ACPI_ID_LEN];
+ const bool ignore_internal_dmic;
+ const struct snd_soc_ops *ops;
+ struct asoc_sdw_dai_info dais[SOC_SDW_MAX_DAI_NUM];
+ const int dai_num;
+
+ int (*codec_card_late_probe)(struct snd_soc_card *card);
+
+ int (*count_sidecar)(struct snd_soc_card *card,
+ int *num_dais, int *num_devs);
+ int (*add_sidecar)(struct snd_soc_card *card,
+ struct snd_soc_dai_link **dai_links,
+ struct snd_soc_codec_conf **codec_conf);
+};
+
+struct asoc_sdw_mc_private {
+ struct snd_soc_card card;
+ struct snd_soc_jack sdw_headset;
+ struct device *headset_codec_dev; /* only one headset per card */
+ struct device *amp_dev1, *amp_dev2;
+ bool append_dai_type;
+ bool ignore_internal_dmic;
+ void *private;
+ unsigned long mc_quirk;
+ int codec_info_list_count;
+};
+
+extern struct asoc_sdw_codec_info codec_info_list[];
+int asoc_sdw_get_codec_info_list_count(void);
+
+int asoc_sdw_startup(struct snd_pcm_substream *substream);
+int asoc_sdw_prepare(struct snd_pcm_substream *substream);
+int asoc_sdw_prepare(struct snd_pcm_substream *substream);
+int asoc_sdw_trigger(struct snd_pcm_substream *substream, int cmd);
+int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params);
+int asoc_sdw_hw_free(struct snd_pcm_substream *substream);
+void asoc_sdw_shutdown(struct snd_pcm_substream *substream);
+
+const char *asoc_sdw_get_codec_name(struct device *dev,
+ const struct asoc_sdw_codec_info *codec_info,
+ const struct snd_soc_acpi_link_adr *adr_link,
+ int adr_index);
+
+struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr);
+
+struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id);
+
+struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name,
+ int *dai_index);
+
+struct snd_soc_dai_link *asoc_sdw_mc_find_codec_dai_used(struct snd_soc_card *card,
+ const char *dai_name);
+
+void asoc_sdw_mc_dailink_exit_loop(struct snd_soc_card *card);
+
+int asoc_sdw_card_late_probe(struct snd_soc_card *card);
+
+void asoc_sdw_init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
+ int *be_id, char *name, int playback, int capture,
+ struct snd_soc_dai_link_component *cpus, int cpus_num,
+ struct snd_soc_dai_link_component *platform_component,
+ int num_platforms, struct snd_soc_dai_link_component *codecs,
+ int codecs_num, int (*init)(struct snd_soc_pcm_runtime *rtd),
+ const struct snd_soc_ops *ops);
+
+int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
+ int *be_id, char *name, int playback, int capture,
+ const char *cpu_dai_name, const char *platform_comp_name,
+ int num_platforms, const char *codec_name,
+ const char *codec_dai_name,
+ int (*init)(struct snd_soc_pcm_runtime *rtd),
+ const struct snd_soc_ops *ops);
+
+int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd);
+
+/* DMIC support */
+int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd);
+
+/* RT711 support */
+int asoc_sdw_rt711_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback);
+int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
+
+/* RT711-SDCA support */
+int asoc_sdw_rt_sdca_jack_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback);
+int asoc_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
+
+/* RT1308 I2S support */
+extern const struct snd_soc_ops soc_sdw_rt1308_i2s_ops;
+
+/* generic amp support */
+int asoc_sdw_rt_amp_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback);
+int asoc_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
+
+/* CS42L43 support */
+int asoc_sdw_cs42l43_spk_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback);
+
+/* CS AMP support */
+int asoc_sdw_bridge_cs35l56_count_sidecar(struct snd_soc_card *card,
+ int *num_dais, int *num_devs);
+int asoc_sdw_bridge_cs35l56_add_sidecar(struct snd_soc_card *card,
+ struct snd_soc_dai_link **dai_links,
+ struct snd_soc_codec_conf **codec_conf);
+int asoc_sdw_bridge_cs35l56_spk_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback);
+
+int asoc_sdw_cs_amp_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback);
+
+/* MAXIM codec support */
+int asoc_sdw_maxim_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback);
+
+/* dai_link init callbacks */
+int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_rt712_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_rt722_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
+
+#endif
diff --git a/include/sound/tas2563-tlv.h b/include/sound/tas2563-tlv.h
new file mode 100644
index 000000000000..faa3e194f73b
--- /dev/null
+++ b/include/sound/tas2563-tlv.h
@@ -0,0 +1,279 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+//
+// ALSA SoC Texas Instruments TAS2563 Audio Smart Amplifier
+//
+// Copyright (C) 2022 - 2024 Texas Instruments Incorporated
+// https://www.ti.com
+//
+// The TAS2563 driver implements a flexible and configurable
+// algo coefficient setting for one, two, or even multiple
+// TAS2563 chips.
+//
+// Author: Shenghao Ding <[email protected]>
+//
+
+#ifndef __TAS2563_TLV_H__
+#define __TAS2563_TLV_H__
+
+static const __maybe_unused DECLARE_TLV_DB_SCALE(tas2563_dvc_tlv, -12150, 50, 1);
+
+/* pow(10, db/20) * pow(2,30) */
+static const unsigned char tas2563_dvc_table[][4] = {
+ { 0X00, 0X00, 0X00, 0X00 }, /* -121.5db */
+ { 0X00, 0X00, 0X03, 0XBC }, /* -121.0db */
+ { 0X00, 0X00, 0X03, 0XF5 }, /* -120.5db */
+ { 0X00, 0X00, 0X04, 0X31 }, /* -120.0db */
+ { 0X00, 0X00, 0X04, 0X71 }, /* -119.5db */
+ { 0X00, 0X00, 0X04, 0XB4 }, /* -119.0db */
+ { 0X00, 0X00, 0X04, 0XFC }, /* -118.5db */
+ { 0X00, 0X00, 0X05, 0X47 }, /* -118.0db */
+ { 0X00, 0X00, 0X05, 0X97 }, /* -117.5db */
+ { 0X00, 0X00, 0X05, 0XEC }, /* -117.0db */
+ { 0X00, 0X00, 0X06, 0X46 }, /* -116.5db */
+ { 0X00, 0X00, 0X06, 0XA5 }, /* -116.0db */
+ { 0X00, 0X00, 0X07, 0X0A }, /* -115.5db */
+ { 0X00, 0X00, 0X07, 0X75 }, /* -115.0db */
+ { 0X00, 0X00, 0X07, 0XE6 }, /* -114.5db */
+ { 0X00, 0X00, 0X08, 0X5E }, /* -114.0db */
+ { 0X00, 0X00, 0X08, 0XDD }, /* -113.5db */
+ { 0X00, 0X00, 0X09, 0X63 }, /* -113.0db */
+ { 0X00, 0X00, 0X09, 0XF2 }, /* -112.5db */
+ { 0X00, 0X00, 0X0A, 0X89 }, /* -112.0db */
+ { 0X00, 0X00, 0X0B, 0X28 }, /* -111.5db */
+ { 0X00, 0X00, 0X0B, 0XD2 }, /* -111.0db */
+ { 0X00, 0X00, 0X0C, 0X85 }, /* -110.5db */
+ { 0X00, 0X00, 0X0D, 0X43 }, /* -110.0db */
+ { 0X00, 0X00, 0X0E, 0X0C }, /* -109.5db */
+ { 0X00, 0X00, 0X0E, 0XE1 }, /* -109.0db */
+ { 0X00, 0X00, 0X0F, 0XC3 }, /* -108.5db */
+ { 0X00, 0X00, 0X10, 0XB2 }, /* -108.0db */
+ { 0X00, 0X00, 0X11, 0XAF }, /* -107.5db */
+ { 0X00, 0X00, 0X12, 0XBC }, /* -107.0db */
+ { 0X00, 0X00, 0X13, 0XD8 }, /* -106.5db */
+ { 0X00, 0X00, 0X15, 0X05 }, /* -106.0db */
+ { 0X00, 0X00, 0X16, 0X44 }, /* -105.5db */
+ { 0X00, 0X00, 0X17, 0X96 }, /* -105.0db */
+ { 0X00, 0X00, 0X18, 0XFB }, /* -104.5db */
+ { 0X00, 0X00, 0X1A, 0X76 }, /* -104.0db */
+ { 0X00, 0X00, 0X1C, 0X08 }, /* -103.5db */
+ { 0X00, 0X00, 0X1D, 0XB1 }, /* -103.0db */
+ { 0X00, 0X00, 0X1F, 0X73 }, /* -102.5db */
+ { 0X00, 0X00, 0X21, 0X51 }, /* -102.0db */
+ { 0X00, 0X00, 0X23, 0X4A }, /* -101.5db */
+ { 0X00, 0X00, 0X25, 0X61 }, /* -101.0db */
+ { 0X00, 0X00, 0X27, 0X98 }, /* -100.5db */
+ { 0X00, 0X00, 0X29, 0XF1 }, /* -100.0db */
+ { 0X00, 0X00, 0X2C, 0X6D }, /* -99.5db */
+ { 0X00, 0X00, 0X2F, 0X0F }, /* -99.0db */
+ { 0X00, 0X00, 0X31, 0XD9 }, /* -98.5db */
+ { 0X00, 0X00, 0X34, 0XCD }, /* -98.0db */
+ { 0X00, 0X00, 0X37, 0XEE }, /* -97.5db */
+ { 0X00, 0X00, 0X3B, 0X3F }, /* -97.0db */
+ { 0X00, 0X00, 0X3E, 0XC1 }, /* -96.5db */
+ { 0X00, 0X00, 0X42, 0X79 }, /* -96.0db */
+ { 0X00, 0X00, 0X46, 0X6A }, /* -95.5db */
+ { 0X00, 0X00, 0X4A, 0X96 }, /* -95.0db */
+ { 0X00, 0X00, 0X4F, 0X01 }, /* -94.5db */
+ { 0X00, 0X00, 0X53, 0XAF }, /* -94.0db */
+ { 0X00, 0X00, 0X58, 0XA5 }, /* -93.5db */
+ { 0X00, 0X00, 0X5D, 0XE6 }, /* -93.0db */
+ { 0X00, 0X00, 0X63, 0X76 }, /* -92.5db */
+ { 0X00, 0X00, 0X69, 0X5B }, /* -92.0db */
+ { 0X00, 0X00, 0X6F, 0X99 }, /* -91.5db */
+ { 0X00, 0X00, 0X76, 0X36 }, /* -91.0db */
+ { 0X00, 0X00, 0X7D, 0X37 }, /* -90.5db */
+ { 0X00, 0X00, 0X84, 0XA2 }, /* -90.0db */
+ { 0X00, 0X00, 0X8C, 0X7E }, /* -89.5db */
+ { 0X00, 0X00, 0X94, 0XD1 }, /* -89.0db */
+ { 0X00, 0X00, 0X9D, 0XA3 }, /* -88.5db */
+ { 0X00, 0X00, 0XA6, 0XFA }, /* -88.0db */
+ { 0X00, 0X00, 0XB0, 0XDF }, /* -87.5db */
+ { 0X00, 0X00, 0XBB, 0X5A }, /* -87.0db */
+ { 0X00, 0X00, 0XC6, 0X74 }, /* -86.5db */
+ { 0X00, 0X00, 0XD2, 0X36 }, /* -86.0db */
+ { 0X00, 0X00, 0XDE, 0XAB }, /* -85.5db */
+ { 0X00, 0X00, 0XEB, 0XDC }, /* -85.0db */
+ { 0X00, 0X00, 0XF9, 0XD6 }, /* -84.5db */
+ { 0X00, 0X01, 0X08, 0XA4 }, /* -84.0db */
+ { 0X00, 0X01, 0X18, 0X52 }, /* -83.5db */
+ { 0X00, 0X01, 0X28, 0XEF }, /* -83.0db */
+ { 0X00, 0X01, 0X3A, 0X87 }, /* -82.5db */
+ { 0X00, 0X01, 0X4D, 0X2A }, /* -82.0db */
+ { 0X00, 0X01, 0X60, 0XE8 }, /* -81.5db */
+ { 0X00, 0X01, 0X75, 0XD1 }, /* -81.0db */
+ { 0X00, 0X01, 0X8B, 0XF7 }, /* -80.5db */
+ { 0X00, 0X01, 0XA3, 0X6E }, /* -80.0db */
+ { 0X00, 0X01, 0XBC, 0X48 }, /* -79.5db */
+ { 0X00, 0X01, 0XD6, 0X9B }, /* -79.0db */
+ { 0X00, 0X01, 0XF2, 0X7E }, /* -78.5db */
+ { 0X00, 0X02, 0X10, 0X08 }, /* -78.0db */
+ { 0X00, 0X02, 0X2F, 0X51 }, /* -77.5db */
+ { 0X00, 0X02, 0X50, 0X76 }, /* -77.0db */
+ { 0X00, 0X02, 0X73, 0X91 }, /* -76.5db */
+ { 0X00, 0X02, 0X98, 0XC0 }, /* -76.0db */
+ { 0X00, 0X02, 0XC0, 0X24 }, /* -75.5db */
+ { 0X00, 0X02, 0XE9, 0XDD }, /* -75.0db */
+ { 0X00, 0X03, 0X16, 0X0F }, /* -74.5db */
+ { 0X00, 0X03, 0X44, 0XDF }, /* -74.0db */
+ { 0X00, 0X03, 0X76, 0X76 }, /* -73.5db */
+ { 0X00, 0X03, 0XAA, 0XFC }, /* -73.0db */
+ { 0X00, 0X03, 0XE2, 0XA0 }, /* -72.5db */
+ { 0X00, 0X04, 0X1D, 0X8F }, /* -72.0db */
+ { 0X00, 0X04, 0X5B, 0XFD }, /* -71.5db */
+ { 0X00, 0X04, 0X9E, 0X1D }, /* -71.0db */
+ { 0X00, 0X04, 0XE4, 0X29 }, /* -70.5db */
+ { 0X00, 0X05, 0X2E, 0X5A }, /* -70.0db */
+ { 0X00, 0X05, 0X7C, 0XF2 }, /* -69.5db */
+ { 0X00, 0X05, 0XD0, 0X31 }, /* -69.0db */
+ { 0X00, 0X06, 0X28, 0X60 }, /* -68.5db */
+ { 0X00, 0X06, 0X85, 0XC8 }, /* -68.0db */
+ { 0X00, 0X06, 0XE8, 0XB9 }, /* -67.5db */
+ { 0X00, 0X07, 0X51, 0X86 }, /* -67.0db */
+ { 0X00, 0X07, 0XC0, 0X8A }, /* -66.5db */
+ { 0X00, 0X08, 0X36, 0X21 }, /* -66.0db */
+ { 0X00, 0X08, 0XB2, 0XB0 }, /* -65.5db */
+ { 0X00, 0X09, 0X36, 0XA1 }, /* -65.0db */
+ { 0X00, 0X09, 0XC2, 0X63 }, /* -64.5db */
+ { 0X00, 0X0A, 0X56, 0X6D }, /* -64.0db */
+ { 0X00, 0X0A, 0XF3, 0X3C }, /* -63.5db */
+ { 0X00, 0X0B, 0X99, 0X56 }, /* -63.0db */
+ { 0X00, 0X0C, 0X49, 0X48 }, /* -62.5db */
+ { 0X00, 0X0D, 0X03, 0XA7 }, /* -62.0db */
+ { 0X00, 0X0D, 0XC9, 0X11 }, /* -61.5db */
+ { 0X00, 0X0E, 0X9A, 0X2D }, /* -61.0db */
+ { 0X00, 0X0F, 0X77, 0XAD }, /* -60.5db */
+ { 0X00, 0X10, 0X62, 0X4D }, /* -60.0db */
+ { 0X00, 0X11, 0X5A, 0XD5 }, /* -59.5db */
+ { 0X00, 0X12, 0X62, 0X16 }, /* -59.0db */
+ { 0X00, 0X13, 0X78, 0XF0 }, /* -58.5db */
+ { 0X00, 0X14, 0XA0, 0X50 }, /* -58.0db */
+ { 0X00, 0X15, 0XD9, 0X31 }, /* -57.5db */
+ { 0X00, 0X17, 0X24, 0X9C }, /* -57.0db */
+ { 0X00, 0X18, 0X83, 0XAA }, /* -56.5db */
+ { 0X00, 0X19, 0XF7, 0X86 }, /* -56.0db */
+ { 0X00, 0X1B, 0X81, 0X6A }, /* -55.5db */
+ { 0X00, 0X1D, 0X22, 0XA4 }, /* -55.0db */
+ { 0X00, 0X1E, 0XDC, 0X98 }, /* -54.5db */
+ { 0X00, 0X20, 0XB0, 0XBC }, /* -54.0db */
+ { 0X00, 0X22, 0XA0, 0X9D }, /* -53.5db */
+ { 0X00, 0X24, 0XAD, 0XE0 }, /* -53.0db */
+ { 0X00, 0X26, 0XDA, 0X43 }, /* -52.5db */
+ { 0X00, 0X29, 0X27, 0X9D }, /* -52.0db */
+ { 0X00, 0X2B, 0X97, 0XE3 }, /* -51.5db */
+ { 0X00, 0X2E, 0X2D, 0X27 }, /* -51.0db */
+ { 0X00, 0X30, 0XE9, 0X9A }, /* -50.5db */
+ { 0X00, 0X33, 0XCF, 0X8D }, /* -50.0db */
+ { 0X00, 0X36, 0XE1, 0X78 }, /* -49.5db */
+ { 0X00, 0X3A, 0X21, 0XF3 }, /* -49.0db */
+ { 0X00, 0X3D, 0X93, 0XC3 }, /* -48.5db */
+ { 0X00, 0X41, 0X39, 0XD3 }, /* -48.0db */
+ { 0X00, 0X45, 0X17, 0X3B }, /* -47.5db */
+ { 0X00, 0X49, 0X2F, 0X44 }, /* -47.0db */
+ { 0X00, 0X4D, 0X85, 0X66 }, /* -46.5db */
+ { 0X00, 0X52, 0X1D, 0X50 }, /* -46.0db */
+ { 0X00, 0X56, 0XFA, 0XE8 }, /* -45.5db */
+ { 0X00, 0X5C, 0X22, 0X4E }, /* -45.0db */
+ { 0X00, 0X61, 0X97, 0XE1 }, /* -44.5db */
+ { 0X00, 0X67, 0X60, 0X44 }, /* -44.0db */
+ { 0X00, 0X6D, 0X80, 0X60 }, /* -43.5db */
+ { 0X00, 0X73, 0XFD, 0X65 }, /* -43.0db */
+ { 0X00, 0X7A, 0XDC, 0XD7 }, /* -42.5db */
+ { 0X00, 0X82, 0X24, 0X8A }, /* -42.0db */
+ { 0X00, 0X89, 0XDA, 0XAB }, /* -41.5db */
+ { 0X00, 0X92, 0X05, 0XC6 }, /* -41.0db */
+ { 0X00, 0X9A, 0XAC, 0XC8 }, /* -40.5db */
+ { 0X00, 0XA3, 0XD7, 0X0A }, /* -40.0db */
+ { 0X00, 0XAD, 0X8C, 0X52 }, /* -39.5db */
+ { 0X00, 0XB7, 0XD4, 0XDD }, /* -39.0db */
+ { 0X00, 0XC2, 0XB9, 0X65 }, /* -38.5db */
+ { 0X00, 0XCE, 0X43, 0X28 }, /* -38.0db */
+ { 0X00, 0XDA, 0X7B, 0XF1 }, /* -37.5db */
+ { 0X00, 0XE7, 0X6E, 0X1E }, /* -37.0db */
+ { 0X00, 0XF5, 0X24, 0XAC }, /* -36.5db */
+ { 0X01, 0X03, 0XAB, 0X3D }, /* -36.0db */
+ { 0X01, 0X13, 0X0E, 0X24 }, /* -35.5db */
+ { 0X01, 0X23, 0X5A, 0X71 }, /* -35.0db */
+ { 0X01, 0X34, 0X9D, 0XF8 }, /* -34.5db */
+ { 0X01, 0X46, 0XE7, 0X5D }, /* -34.0db */
+ { 0X01, 0X5A, 0X46, 0X27 }, /* -33.5db */
+ { 0X01, 0X6E, 0XCA, 0XC5 }, /* -33.0db */
+ { 0X01, 0X84, 0X86, 0X9F }, /* -32.5db */
+ { 0X01, 0X9B, 0X8C, 0X27 }, /* -32.0db */
+ { 0X01, 0XB3, 0XEE, 0XE5 }, /* -31.5db */
+ { 0X01, 0XCD, 0XC3, 0X8C }, /* -31.0db */
+ { 0X01, 0XE9, 0X20, 0X05 }, /* -30.5db */
+ { 0X02, 0X06, 0X1B, 0X89 }, /* -30.0db */
+ { 0X02, 0X24, 0XCE, 0XB0 }, /* -29.5db */
+ { 0X02, 0X45, 0X53, 0X85 }, /* -29.0db */
+ { 0X02, 0X67, 0XC5, 0XA2 }, /* -28.5db */
+ { 0X02, 0X8C, 0X42, 0X3F }, /* -28.0db */
+ { 0X02, 0XB2, 0XE8, 0X55 }, /* -27.5db */
+ { 0X02, 0XDB, 0XD8, 0XAD }, /* -27.0db */
+ { 0X03, 0X07, 0X36, 0X05 }, /* -26.5db */
+ { 0X03, 0X35, 0X25, 0X29 }, /* -26.0db */
+ { 0X03, 0X65, 0XCD, 0X13 }, /* -25.5db */
+ { 0X03, 0X99, 0X57, 0X0C }, /* -25.0db */
+ { 0X03, 0XCF, 0XEE, 0XCF }, /* -24.5db */
+ { 0X04, 0X09, 0XC2, 0XB0 }, /* -24.0db */
+ { 0X04, 0X47, 0X03, 0XC1 }, /* -23.5db */
+ { 0X04, 0X87, 0XE5, 0XFB }, /* -23.0db */
+ { 0X04, 0XCC, 0XA0, 0X6D }, /* -22.5db */
+ { 0X05, 0X15, 0X6D, 0X68 }, /* -22.0db */
+ { 0X05, 0X62, 0X8A, 0XB3 }, /* -21.5db */
+ { 0X05, 0XB4, 0X39, 0XBC }, /* -21.0db */
+ { 0X06, 0X0A, 0XBF, 0XD4 }, /* -20.5db */
+ { 0X06, 0X66, 0X66, 0X66 }, /* -20.0db */
+ { 0X06, 0XC7, 0X7B, 0X36 }, /* -19.5db */
+ { 0X07, 0X2E, 0X50, 0XA6 }, /* -19.0db */
+ { 0X07, 0X9B, 0X3D, 0XF6 }, /* -18.5db */
+ { 0X08, 0X0E, 0X9F, 0X96 }, /* -18.0db */
+ { 0X08, 0X88, 0XD7, 0X6D }, /* -17.5db */
+ { 0X09, 0X0A, 0X4D, 0X2F }, /* -17.0db */
+ { 0X09, 0X93, 0X6E, 0XB8 }, /* -16.5db */
+ { 0X0A, 0X24, 0XB0, 0X62 }, /* -16.0db */
+ { 0X0A, 0XBE, 0X8D, 0X70 }, /* -15.5db */
+ { 0X0B, 0X61, 0X88, 0X71 }, /* -15.0db */
+ { 0X0C, 0X0E, 0X2B, 0XB0 }, /* -14.5db */
+ { 0X0C, 0XC5, 0X09, 0XAB }, /* -14.0db */
+ { 0X0D, 0X86, 0XBD, 0X8D }, /* -13.5db */
+ { 0X0E, 0X53, 0XEB, 0XB3 }, /* -13.0db */
+ { 0X0F, 0X2D, 0X42, 0X38 }, /* -12.5db */
+ { 0X10, 0X13, 0X79, 0X87 }, /* -12.0db */
+ { 0X11, 0X07, 0X54, 0XF9 }, /* -11.5db */
+ { 0X12, 0X09, 0XA3, 0X7A }, /* -11.0db */
+ { 0X13, 0X1B, 0X40, 0X39 }, /* -10.5db */
+ { 0X14, 0X3D, 0X13, 0X62 }, /* -10.0db */
+ { 0X15, 0X70, 0X12, 0XE1 }, /* -9.5db */
+ { 0X16, 0XB5, 0X43, 0X37 }, /* -9.0db */
+ { 0X18, 0X0D, 0XB8, 0X54 }, /* -8.5db */
+ { 0X19, 0X7A, 0X96, 0X7F }, /* -8.0db */
+ { 0X1A, 0XFD, 0X13, 0X54 }, /* -7.5db */
+ { 0X1C, 0X96, 0X76, 0XC6 }, /* -7.0db */
+ { 0X1E, 0X48, 0X1C, 0X37 }, /* -6.5db */
+ { 0X20, 0X13, 0X73, 0X9E }, /* -6.0db */
+ { 0X21, 0XFA, 0X02, 0XBF }, /* -5.5db */
+ { 0X23, 0XFD, 0X66, 0X78 }, /* -5.0db */
+ { 0X26, 0X1F, 0X54, 0X1C }, /* -4.5db */
+ { 0X28, 0X61, 0X9A, 0XE9 }, /* -4.0db */
+ { 0X2A, 0XC6, 0X25, 0X91 }, /* -3.5db */
+ { 0X2D, 0X4E, 0XFB, 0XD5 }, /* -3.0db */
+ { 0X2F, 0XFE, 0X44, 0X48 }, /* -2.5db */
+ { 0X32, 0XD6, 0X46, 0X17 }, /* -2.0db */
+ { 0X35, 0XD9, 0X6B, 0X02 }, /* -1.5db */
+ { 0X39, 0X0A, 0X41, 0X5F }, /* -1.0db */
+ { 0X3C, 0X6B, 0X7E, 0X4F }, /* -0.5db */
+ { 0X40, 0X00, 0X00, 0X00 }, /* 0.0db */
+ { 0X43, 0XCA, 0XD0, 0X22 }, /* 0.5db */
+ { 0X47, 0XCF, 0X26, 0X7D }, /* 1.0db */
+ { 0X4C, 0X10, 0X6B, 0XA5 }, /* 1.5db */
+ { 0X50, 0X92, 0X3B, 0XE3 }, /* 2.0db */
+ { 0X55, 0X58, 0X6A, 0X46 }, /* 2.5db */
+ { 0X5A, 0X67, 0X03, 0XDF }, /* 3.0db */
+ { 0X5F, 0XC2, 0X53, 0X32 }, /* 3.5db */
+ { 0X65, 0X6E, 0XE3, 0XDB }, /* 4.0db */
+ { 0X6B, 0X71, 0X86, 0X68 }, /* 4.5db */
+ { 0X71, 0XCF, 0X54, 0X71 }, /* 5.0db */
+ { 0X78, 0X8D, 0XB4, 0XE9 }, /* 5.5db */
+ { 0X7F, 0XFF, 0XFF, 0XFF }, /* 6.0db */
+};
+#endif
diff --git a/include/sound/tas2781-tlv.h b/include/sound/tas2781-tlv.h
index 00fd4d449ff3..d87263e43fdb 100644
--- a/include/sound/tas2781-tlv.h
+++ b/include/sound/tas2781-tlv.h
@@ -17,265 +17,5 @@
static const __maybe_unused DECLARE_TLV_DB_SCALE(dvc_tlv, -10000, 100, 0);
static const __maybe_unused DECLARE_TLV_DB_SCALE(amp_vol_tlv, 1100, 50, 0);
-static const __maybe_unused DECLARE_TLV_DB_SCALE(tas2563_dvc_tlv, -12150, 50, 1);
-/* pow(10, db/20) * pow(2,30) */
-static const __maybe_unused unsigned char tas2563_dvc_table[][4] = {
- { 0X00, 0X00, 0X00, 0X00 }, /* -121.5db */
- { 0X00, 0X00, 0X03, 0XBC }, /* -121.0db */
- { 0X00, 0X00, 0X03, 0XF5 }, /* -120.5db */
- { 0X00, 0X00, 0X04, 0X31 }, /* -120.0db */
- { 0X00, 0X00, 0X04, 0X71 }, /* -119.5db */
- { 0X00, 0X00, 0X04, 0XB4 }, /* -119.0db */
- { 0X00, 0X00, 0X04, 0XFC }, /* -118.5db */
- { 0X00, 0X00, 0X05, 0X47 }, /* -118.0db */
- { 0X00, 0X00, 0X05, 0X97 }, /* -117.5db */
- { 0X00, 0X00, 0X05, 0XEC }, /* -117.0db */
- { 0X00, 0X00, 0X06, 0X46 }, /* -116.5db */
- { 0X00, 0X00, 0X06, 0XA5 }, /* -116.0db */
- { 0X00, 0X00, 0X07, 0X0A }, /* -115.5db */
- { 0X00, 0X00, 0X07, 0X75 }, /* -115.0db */
- { 0X00, 0X00, 0X07, 0XE6 }, /* -114.5db */
- { 0X00, 0X00, 0X08, 0X5E }, /* -114.0db */
- { 0X00, 0X00, 0X08, 0XDD }, /* -113.5db */
- { 0X00, 0X00, 0X09, 0X63 }, /* -113.0db */
- { 0X00, 0X00, 0X09, 0XF2 }, /* -112.5db */
- { 0X00, 0X00, 0X0A, 0X89 }, /* -112.0db */
- { 0X00, 0X00, 0X0B, 0X28 }, /* -111.5db */
- { 0X00, 0X00, 0X0B, 0XD2 }, /* -111.0db */
- { 0X00, 0X00, 0X0C, 0X85 }, /* -110.5db */
- { 0X00, 0X00, 0X0D, 0X43 }, /* -110.0db */
- { 0X00, 0X00, 0X0E, 0X0C }, /* -109.5db */
- { 0X00, 0X00, 0X0E, 0XE1 }, /* -109.0db */
- { 0X00, 0X00, 0X0F, 0XC3 }, /* -108.5db */
- { 0X00, 0X00, 0X10, 0XB2 }, /* -108.0db */
- { 0X00, 0X00, 0X11, 0XAF }, /* -107.5db */
- { 0X00, 0X00, 0X12, 0XBC }, /* -107.0db */
- { 0X00, 0X00, 0X13, 0XD8 }, /* -106.5db */
- { 0X00, 0X00, 0X15, 0X05 }, /* -106.0db */
- { 0X00, 0X00, 0X16, 0X44 }, /* -105.5db */
- { 0X00, 0X00, 0X17, 0X96 }, /* -105.0db */
- { 0X00, 0X00, 0X18, 0XFB }, /* -104.5db */
- { 0X00, 0X00, 0X1A, 0X76 }, /* -104.0db */
- { 0X00, 0X00, 0X1C, 0X08 }, /* -103.5db */
- { 0X00, 0X00, 0X1D, 0XB1 }, /* -103.0db */
- { 0X00, 0X00, 0X1F, 0X73 }, /* -102.5db */
- { 0X00, 0X00, 0X21, 0X51 }, /* -102.0db */
- { 0X00, 0X00, 0X23, 0X4A }, /* -101.5db */
- { 0X00, 0X00, 0X25, 0X61 }, /* -101.0db */
- { 0X00, 0X00, 0X27, 0X98 }, /* -100.5db */
- { 0X00, 0X00, 0X29, 0XF1 }, /* -100.0db */
- { 0X00, 0X00, 0X2C, 0X6D }, /* -99.5db */
- { 0X00, 0X00, 0X2F, 0X0F }, /* -99.0db */
- { 0X00, 0X00, 0X31, 0XD9 }, /* -98.5db */
- { 0X00, 0X00, 0X34, 0XCD }, /* -98.0db */
- { 0X00, 0X00, 0X37, 0XEE }, /* -97.5db */
- { 0X00, 0X00, 0X3B, 0X3F }, /* -97.0db */
- { 0X00, 0X00, 0X3E, 0XC1 }, /* -96.5db */
- { 0X00, 0X00, 0X42, 0X79 }, /* -96.0db */
- { 0X00, 0X00, 0X46, 0X6A }, /* -95.5db */
- { 0X00, 0X00, 0X4A, 0X96 }, /* -95.0db */
- { 0X00, 0X00, 0X4F, 0X01 }, /* -94.5db */
- { 0X00, 0X00, 0X53, 0XAF }, /* -94.0db */
- { 0X00, 0X00, 0X58, 0XA5 }, /* -93.5db */
- { 0X00, 0X00, 0X5D, 0XE6 }, /* -93.0db */
- { 0X00, 0X00, 0X63, 0X76 }, /* -92.5db */
- { 0X00, 0X00, 0X69, 0X5B }, /* -92.0db */
- { 0X00, 0X00, 0X6F, 0X99 }, /* -91.5db */
- { 0X00, 0X00, 0X76, 0X36 }, /* -91.0db */
- { 0X00, 0X00, 0X7D, 0X37 }, /* -90.5db */
- { 0X00, 0X00, 0X84, 0XA2 }, /* -90.0db */
- { 0X00, 0X00, 0X8C, 0X7E }, /* -89.5db */
- { 0X00, 0X00, 0X94, 0XD1 }, /* -89.0db */
- { 0X00, 0X00, 0X9D, 0XA3 }, /* -88.5db */
- { 0X00, 0X00, 0XA6, 0XFA }, /* -88.0db */
- { 0X00, 0X00, 0XB0, 0XDF }, /* -87.5db */
- { 0X00, 0X00, 0XBB, 0X5A }, /* -87.0db */
- { 0X00, 0X00, 0XC6, 0X74 }, /* -86.5db */
- { 0X00, 0X00, 0XD2, 0X36 }, /* -86.0db */
- { 0X00, 0X00, 0XDE, 0XAB }, /* -85.5db */
- { 0X00, 0X00, 0XEB, 0XDC }, /* -85.0db */
- { 0X00, 0X00, 0XF9, 0XD6 }, /* -84.5db */
- { 0X00, 0X01, 0X08, 0XA4 }, /* -84.0db */
- { 0X00, 0X01, 0X18, 0X52 }, /* -83.5db */
- { 0X00, 0X01, 0X28, 0XEF }, /* -83.0db */
- { 0X00, 0X01, 0X3A, 0X87 }, /* -82.5db */
- { 0X00, 0X01, 0X4D, 0X2A }, /* -82.0db */
- { 0X00, 0X01, 0X60, 0XE8 }, /* -81.5db */
- { 0X00, 0X01, 0X75, 0XD1 }, /* -81.0db */
- { 0X00, 0X01, 0X8B, 0XF7 }, /* -80.5db */
- { 0X00, 0X01, 0XA3, 0X6E }, /* -80.0db */
- { 0X00, 0X01, 0XBC, 0X48 }, /* -79.5db */
- { 0X00, 0X01, 0XD6, 0X9B }, /* -79.0db */
- { 0X00, 0X01, 0XF2, 0X7E }, /* -78.5db */
- { 0X00, 0X02, 0X10, 0X08 }, /* -78.0db */
- { 0X00, 0X02, 0X2F, 0X51 }, /* -77.5db */
- { 0X00, 0X02, 0X50, 0X76 }, /* -77.0db */
- { 0X00, 0X02, 0X73, 0X91 }, /* -76.5db */
- { 0X00, 0X02, 0X98, 0XC0 }, /* -76.0db */
- { 0X00, 0X02, 0XC0, 0X24 }, /* -75.5db */
- { 0X00, 0X02, 0XE9, 0XDD }, /* -75.0db */
- { 0X00, 0X03, 0X16, 0X0F }, /* -74.5db */
- { 0X00, 0X03, 0X44, 0XDF }, /* -74.0db */
- { 0X00, 0X03, 0X76, 0X76 }, /* -73.5db */
- { 0X00, 0X03, 0XAA, 0XFC }, /* -73.0db */
- { 0X00, 0X03, 0XE2, 0XA0 }, /* -72.5db */
- { 0X00, 0X04, 0X1D, 0X8F }, /* -72.0db */
- { 0X00, 0X04, 0X5B, 0XFD }, /* -71.5db */
- { 0X00, 0X04, 0X9E, 0X1D }, /* -71.0db */
- { 0X00, 0X04, 0XE4, 0X29 }, /* -70.5db */
- { 0X00, 0X05, 0X2E, 0X5A }, /* -70.0db */
- { 0X00, 0X05, 0X7C, 0XF2 }, /* -69.5db */
- { 0X00, 0X05, 0XD0, 0X31 }, /* -69.0db */
- { 0X00, 0X06, 0X28, 0X60 }, /* -68.5db */
- { 0X00, 0X06, 0X85, 0XC8 }, /* -68.0db */
- { 0X00, 0X06, 0XE8, 0XB9 }, /* -67.5db */
- { 0X00, 0X07, 0X51, 0X86 }, /* -67.0db */
- { 0X00, 0X07, 0XC0, 0X8A }, /* -66.5db */
- { 0X00, 0X08, 0X36, 0X21 }, /* -66.0db */
- { 0X00, 0X08, 0XB2, 0XB0 }, /* -65.5db */
- { 0X00, 0X09, 0X36, 0XA1 }, /* -65.0db */
- { 0X00, 0X09, 0XC2, 0X63 }, /* -64.5db */
- { 0X00, 0X0A, 0X56, 0X6D }, /* -64.0db */
- { 0X00, 0X0A, 0XF3, 0X3C }, /* -63.5db */
- { 0X00, 0X0B, 0X99, 0X56 }, /* -63.0db */
- { 0X00, 0X0C, 0X49, 0X48 }, /* -62.5db */
- { 0X00, 0X0D, 0X03, 0XA7 }, /* -62.0db */
- { 0X00, 0X0D, 0XC9, 0X11 }, /* -61.5db */
- { 0X00, 0X0E, 0X9A, 0X2D }, /* -61.0db */
- { 0X00, 0X0F, 0X77, 0XAD }, /* -60.5db */
- { 0X00, 0X10, 0X62, 0X4D }, /* -60.0db */
- { 0X00, 0X11, 0X5A, 0XD5 }, /* -59.5db */
- { 0X00, 0X12, 0X62, 0X16 }, /* -59.0db */
- { 0X00, 0X13, 0X78, 0XF0 }, /* -58.5db */
- { 0X00, 0X14, 0XA0, 0X50 }, /* -58.0db */
- { 0X00, 0X15, 0XD9, 0X31 }, /* -57.5db */
- { 0X00, 0X17, 0X24, 0X9C }, /* -57.0db */
- { 0X00, 0X18, 0X83, 0XAA }, /* -56.5db */
- { 0X00, 0X19, 0XF7, 0X86 }, /* -56.0db */
- { 0X00, 0X1B, 0X81, 0X6A }, /* -55.5db */
- { 0X00, 0X1D, 0X22, 0XA4 }, /* -55.0db */
- { 0X00, 0X1E, 0XDC, 0X98 }, /* -54.5db */
- { 0X00, 0X20, 0XB0, 0XBC }, /* -54.0db */
- { 0X00, 0X22, 0XA0, 0X9D }, /* -53.5db */
- { 0X00, 0X24, 0XAD, 0XE0 }, /* -53.0db */
- { 0X00, 0X26, 0XDA, 0X43 }, /* -52.5db */
- { 0X00, 0X29, 0X27, 0X9D }, /* -52.0db */
- { 0X00, 0X2B, 0X97, 0XE3 }, /* -51.5db */
- { 0X00, 0X2E, 0X2D, 0X27 }, /* -51.0db */
- { 0X00, 0X30, 0XE9, 0X9A }, /* -50.5db */
- { 0X00, 0X33, 0XCF, 0X8D }, /* -50.0db */
- { 0X00, 0X36, 0XE1, 0X78 }, /* -49.5db */
- { 0X00, 0X3A, 0X21, 0XF3 }, /* -49.0db */
- { 0X00, 0X3D, 0X93, 0XC3 }, /* -48.5db */
- { 0X00, 0X41, 0X39, 0XD3 }, /* -48.0db */
- { 0X00, 0X45, 0X17, 0X3B }, /* -47.5db */
- { 0X00, 0X49, 0X2F, 0X44 }, /* -47.0db */
- { 0X00, 0X4D, 0X85, 0X66 }, /* -46.5db */
- { 0X00, 0X52, 0X1D, 0X50 }, /* -46.0db */
- { 0X00, 0X56, 0XFA, 0XE8 }, /* -45.5db */
- { 0X00, 0X5C, 0X22, 0X4E }, /* -45.0db */
- { 0X00, 0X61, 0X97, 0XE1 }, /* -44.5db */
- { 0X00, 0X67, 0X60, 0X44 }, /* -44.0db */
- { 0X00, 0X6D, 0X80, 0X60 }, /* -43.5db */
- { 0X00, 0X73, 0XFD, 0X65 }, /* -43.0db */
- { 0X00, 0X7A, 0XDC, 0XD7 }, /* -42.5db */
- { 0X00, 0X82, 0X24, 0X8A }, /* -42.0db */
- { 0X00, 0X89, 0XDA, 0XAB }, /* -41.5db */
- { 0X00, 0X92, 0X05, 0XC6 }, /* -41.0db */
- { 0X00, 0X9A, 0XAC, 0XC8 }, /* -40.5db */
- { 0X00, 0XA3, 0XD7, 0X0A }, /* -40.0db */
- { 0X00, 0XAD, 0X8C, 0X52 }, /* -39.5db */
- { 0X00, 0XB7, 0XD4, 0XDD }, /* -39.0db */
- { 0X00, 0XC2, 0XB9, 0X65 }, /* -38.5db */
- { 0X00, 0XCE, 0X43, 0X28 }, /* -38.0db */
- { 0X00, 0XDA, 0X7B, 0XF1 }, /* -37.5db */
- { 0X00, 0XE7, 0X6E, 0X1E }, /* -37.0db */
- { 0X00, 0XF5, 0X24, 0XAC }, /* -36.5db */
- { 0X01, 0X03, 0XAB, 0X3D }, /* -36.0db */
- { 0X01, 0X13, 0X0E, 0X24 }, /* -35.5db */
- { 0X01, 0X23, 0X5A, 0X71 }, /* -35.0db */
- { 0X01, 0X34, 0X9D, 0XF8 }, /* -34.5db */
- { 0X01, 0X46, 0XE7, 0X5D }, /* -34.0db */
- { 0X01, 0X5A, 0X46, 0X27 }, /* -33.5db */
- { 0X01, 0X6E, 0XCA, 0XC5 }, /* -33.0db */
- { 0X01, 0X84, 0X86, 0X9F }, /* -32.5db */
- { 0X01, 0X9B, 0X8C, 0X27 }, /* -32.0db */
- { 0X01, 0XB3, 0XEE, 0XE5 }, /* -31.5db */
- { 0X01, 0XCD, 0XC3, 0X8C }, /* -31.0db */
- { 0X01, 0XE9, 0X20, 0X05 }, /* -30.5db */
- { 0X02, 0X06, 0X1B, 0X89 }, /* -30.0db */
- { 0X02, 0X24, 0XCE, 0XB0 }, /* -29.5db */
- { 0X02, 0X45, 0X53, 0X85 }, /* -29.0db */
- { 0X02, 0X67, 0XC5, 0XA2 }, /* -28.5db */
- { 0X02, 0X8C, 0X42, 0X3F }, /* -28.0db */
- { 0X02, 0XB2, 0XE8, 0X55 }, /* -27.5db */
- { 0X02, 0XDB, 0XD8, 0XAD }, /* -27.0db */
- { 0X03, 0X07, 0X36, 0X05 }, /* -26.5db */
- { 0X03, 0X35, 0X25, 0X29 }, /* -26.0db */
- { 0X03, 0X65, 0XCD, 0X13 }, /* -25.5db */
- { 0X03, 0X99, 0X57, 0X0C }, /* -25.0db */
- { 0X03, 0XCF, 0XEE, 0XCF }, /* -24.5db */
- { 0X04, 0X09, 0XC2, 0XB0 }, /* -24.0db */
- { 0X04, 0X47, 0X03, 0XC1 }, /* -23.5db */
- { 0X04, 0X87, 0XE5, 0XFB }, /* -23.0db */
- { 0X04, 0XCC, 0XA0, 0X6D }, /* -22.5db */
- { 0X05, 0X15, 0X6D, 0X68 }, /* -22.0db */
- { 0X05, 0X62, 0X8A, 0XB3 }, /* -21.5db */
- { 0X05, 0XB4, 0X39, 0XBC }, /* -21.0db */
- { 0X06, 0X0A, 0XBF, 0XD4 }, /* -20.5db */
- { 0X06, 0X66, 0X66, 0X66 }, /* -20.0db */
- { 0X06, 0XC7, 0X7B, 0X36 }, /* -19.5db */
- { 0X07, 0X2E, 0X50, 0XA6 }, /* -19.0db */
- { 0X07, 0X9B, 0X3D, 0XF6 }, /* -18.5db */
- { 0X08, 0X0E, 0X9F, 0X96 }, /* -18.0db */
- { 0X08, 0X88, 0XD7, 0X6D }, /* -17.5db */
- { 0X09, 0X0A, 0X4D, 0X2F }, /* -17.0db */
- { 0X09, 0X93, 0X6E, 0XB8 }, /* -16.5db */
- { 0X0A, 0X24, 0XB0, 0X62 }, /* -16.0db */
- { 0X0A, 0XBE, 0X8D, 0X70 }, /* -15.5db */
- { 0X0B, 0X61, 0X88, 0X71 }, /* -15.0db */
- { 0X0C, 0X0E, 0X2B, 0XB0 }, /* -14.5db */
- { 0X0C, 0XC5, 0X09, 0XAB }, /* -14.0db */
- { 0X0D, 0X86, 0XBD, 0X8D }, /* -13.5db */
- { 0X0E, 0X53, 0XEB, 0XB3 }, /* -13.0db */
- { 0X0F, 0X2D, 0X42, 0X38 }, /* -12.5db */
- { 0X10, 0X13, 0X79, 0X87 }, /* -12.0db */
- { 0X11, 0X07, 0X54, 0XF9 }, /* -11.5db */
- { 0X12, 0X09, 0XA3, 0X7A }, /* -11.0db */
- { 0X13, 0X1B, 0X40, 0X39 }, /* -10.5db */
- { 0X14, 0X3D, 0X13, 0X62 }, /* -10.0db */
- { 0X15, 0X70, 0X12, 0XE1 }, /* -9.5db */
- { 0X16, 0XB5, 0X43, 0X37 }, /* -9.0db */
- { 0X18, 0X0D, 0XB8, 0X54 }, /* -8.5db */
- { 0X19, 0X7A, 0X96, 0X7F }, /* -8.0db */
- { 0X1A, 0XFD, 0X13, 0X54 }, /* -7.5db */
- { 0X1C, 0X96, 0X76, 0XC6 }, /* -7.0db */
- { 0X1E, 0X48, 0X1C, 0X37 }, /* -6.5db */
- { 0X20, 0X13, 0X73, 0X9E }, /* -6.0db */
- { 0X21, 0XFA, 0X02, 0XBF }, /* -5.5db */
- { 0X23, 0XFD, 0X66, 0X78 }, /* -5.0db */
- { 0X26, 0X1F, 0X54, 0X1C }, /* -4.5db */
- { 0X28, 0X61, 0X9A, 0XE9 }, /* -4.0db */
- { 0X2A, 0XC6, 0X25, 0X91 }, /* -3.5db */
- { 0X2D, 0X4E, 0XFB, 0XD5 }, /* -3.0db */
- { 0X2F, 0XFE, 0X44, 0X48 }, /* -2.5db */
- { 0X32, 0XD6, 0X46, 0X17 }, /* -2.0db */
- { 0X35, 0XD9, 0X6B, 0X02 }, /* -1.5db */
- { 0X39, 0X0A, 0X41, 0X5F }, /* -1.0db */
- { 0X3C, 0X6B, 0X7E, 0X4F }, /* -0.5db */
- { 0X40, 0X00, 0X00, 0X00 }, /* 0.0db */
- { 0X43, 0XCA, 0XD0, 0X22 }, /* 0.5db */
- { 0X47, 0XCF, 0X26, 0X7D }, /* 1.0db */
- { 0X4C, 0X10, 0X6B, 0XA5 }, /* 1.5db */
- { 0X50, 0X92, 0X3B, 0XE3 }, /* 2.0db */
- { 0X55, 0X58, 0X6A, 0X46 }, /* 2.5db */
- { 0X5A, 0X67, 0X03, 0XDF }, /* 3.0db */
- { 0X5F, 0XC2, 0X53, 0X32 }, /* 3.5db */
- { 0X65, 0X6E, 0XE3, 0XDB }, /* 4.0db */
- { 0X6B, 0X71, 0X86, 0X68 }, /* 4.5db */
- { 0X71, 0XCF, 0X54, 0X71 }, /* 5.0db */
- { 0X78, 0X8D, 0XB4, 0XE9 }, /* 5.5db */
- { 0XFF, 0XFF, 0XFF, 0XFF }, /* 6.0db */
-};
#endif
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index a52afb423b46..e87bd15a8b43 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -126,6 +126,8 @@ source "sound/soc/xtensa/Kconfig"
# Supported codecs
source "sound/soc/codecs/Kconfig"
+source "sound/soc/sdw_utils/Kconfig"
+
# generic frame-work
source "sound/soc/generic/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index fd61847dd1eb..775bb38c2ed4 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -75,3 +75,4 @@ obj-$(CONFIG_SND_SOC) += uniphier/
obj-$(CONFIG_SND_SOC) += ux500/
obj-$(CONFIG_SND_SOC) += xilinx/
obj-$(CONFIG_SND_SOC) += xtensa/
+obj-$(CONFIG_SND_SOC) += sdw_utils/
diff --git a/sound/soc/amd/acp/Kconfig b/sound/soc/amd/acp/Kconfig
index 30590a23ad63..88391e4c17e3 100644
--- a/sound/soc/amd/acp/Kconfig
+++ b/sound/soc/amd/acp/Kconfig
@@ -13,6 +13,10 @@ config SND_SOC_AMD_ACP_COMMON
This option enables common modules for Audio-Coprocessor i.e. ACP
IP block on AMD platforms.
+config SND_SOC_ACPI_AMD_MATCH
+ tristate
+ select SND_SOC_ACPI if ACPI
+
if SND_SOC_AMD_ACP_COMMON
config SND_SOC_AMD_ACP_PDM
@@ -115,6 +119,24 @@ config SND_SOC_AMD_SOF_MACH
help
This option enables SOF sound card support for ACP audio.
+config SND_SOC_AMD_SOF_SDW_MACH
+ tristate "AMD SOF Soundwire Machine Driver Support"
+ depends on X86 && PCI && ACPI
+ depends on SOUNDWIRE
+ select SND_SOC_SDW_UTILS
+ select SND_SOC_DMIC
+ select SND_SOC_RT711_SDW
+ select SND_SOC_RT711_SDCA_SDW
+ select SND_SOC_RT1316_SDW
+ select SND_SOC_RT715_SDW
+ select SND_SOC_RT715_SDCA_SDW
+ help
+ This option enables SOF sound card support for SoundWire enabled
+ AMD platforms along with ACP PDM controller.
+ Say Y if you want to enable SoundWire based machine driver support
+ on AMD platform.
+ If unsure select "N".
+
endif # SND_SOC_AMD_ACP_COMMON
config SND_AMD_SOUNDWIRE_ACPI
diff --git a/sound/soc/amd/acp/Makefile b/sound/soc/amd/acp/Makefile
index b068bf1f920e..82cf5d180b3a 100644
--- a/sound/soc/amd/acp/Makefile
+++ b/sound/soc/amd/acp/Makefile
@@ -22,6 +22,8 @@ snd-acp70-y := acp70.o
snd-acp-mach-y := acp-mach-common.o
snd-acp-legacy-mach-y := acp-legacy-mach.o acp3x-es83xx/acp3x-es83xx.o
snd-acp-sof-mach-y := acp-sof-mach.o
+snd-soc-acpi-amd-match-y := amd-acp63-acpi-match.o
+snd-acp-sdw-sof-mach-y += acp-sdw-sof-mach.o
obj-$(CONFIG_SND_SOC_AMD_ACP_PCM) += snd-acp-pcm.o
obj-$(CONFIG_SND_SOC_AMD_ACP_I2S) += snd-acp-i2s.o
@@ -38,3 +40,5 @@ obj-$(CONFIG_SND_AMD_SOUNDWIRE_ACPI) += snd-amd-sdw-acpi.o
obj-$(CONFIG_SND_SOC_AMD_MACH_COMMON) += snd-acp-mach.o
obj-$(CONFIG_SND_SOC_AMD_LEGACY_MACH) += snd-acp-legacy-mach.o
obj-$(CONFIG_SND_SOC_AMD_SOF_MACH) += snd-acp-sof-mach.o
+obj-$(CONFIG_SND_SOC_ACPI_AMD_MATCH) += snd-soc-acpi-amd-match.o
+obj-$(CONFIG_SND_SOC_AMD_SOF_SDW_MACH) += snd-acp-sdw-sof-mach.o
diff --git a/sound/soc/amd/acp/acp-sdw-sof-mach.c b/sound/soc/amd/acp/acp-sdw-sof-mach.c
new file mode 100644
index 000000000000..3419675e45a9
--- /dev/null
+++ b/sound/soc/amd/acp/acp-sdw-sof-mach.c
@@ -0,0 +1,742 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright(c) 2024 Advanced Micro Devices, Inc.
+
+/*
+ * acp-sdw-sof-mach - ASoC Machine driver for AMD SoundWire platforms
+ */
+
+#include <linux/bitmap.h>
+#include <linux/device.h>
+#include <linux/dmi.h>
+#include <linux/module.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_type.h>
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
+#include "soc_amd_sdw_common.h"
+#include "../../codecs/rt711.h"
+
+static unsigned long sof_sdw_quirk = RT711_JD1;
+static int quirk_override = -1;
+module_param_named(quirk, quirk_override, int, 0444);
+MODULE_PARM_DESC(quirk, "Board-specific quirk override");
+
+static void log_quirks(struct device *dev)
+{
+ if (SOC_JACK_JDSRC(sof_sdw_quirk))
+ dev_dbg(dev, "quirk realtek,jack-detect-source %ld\n",
+ SOC_JACK_JDSRC(sof_sdw_quirk));
+ if (sof_sdw_quirk & ASOC_SDW_ACP_DMIC)
+ dev_dbg(dev, "quirk SOC_SDW_ACP_DMIC enabled\n");
+}
+
+static int sof_sdw_quirk_cb(const struct dmi_system_id *id)
+{
+ sof_sdw_quirk = (unsigned long)id->driver_data;
+ return 1;
+}
+
+static const struct dmi_system_id sof_sdw_quirk_table[] = {
+ {
+ .callback = sof_sdw_quirk_cb,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "AMD"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Birman-PHX"),
+ },
+ .driver_data = (void *)RT711_JD2,
+ },
+ {}
+};
+
+static struct snd_soc_dai_link_component platform_component[] = {
+ {
+ /* name might be overridden during probe */
+ .name = "0000:04:00.5",
+ }
+};
+
+static const struct snd_soc_ops sdw_ops = {
+ .startup = asoc_sdw_startup,
+ .prepare = asoc_sdw_prepare,
+ .trigger = asoc_sdw_trigger,
+ .hw_params = asoc_sdw_hw_params,
+ .hw_free = asoc_sdw_hw_free,
+ .shutdown = asoc_sdw_shutdown,
+};
+
+/*
+ * get BE dailink number and CPU DAI number based on sdw link adr.
+ * Since some sdw slaves may be aggregated, the CPU DAI number
+ * may be larger than the number of BE dailinks.
+ */
+static int get_dailink_info(struct device *dev,
+ const struct snd_soc_acpi_link_adr *adr_link,
+ int *sdw_be_num, int *codecs_num)
+{
+ bool group_visited[AMD_SDW_MAX_GROUPS];
+ int i;
+ int j;
+
+ *sdw_be_num = 0;
+
+ if (!adr_link)
+ return -EINVAL;
+
+ for (i = 0; i < AMD_SDW_MAX_GROUPS; i++)
+ group_visited[i] = false;
+
+ for (; adr_link->num_adr; adr_link++) {
+ const struct snd_soc_acpi_endpoint *endpoint;
+ struct asoc_sdw_codec_info *codec_info;
+ int stream;
+ u64 adr;
+
+ /* make sure the link mask has a single bit set */
+ if (!is_power_of_2(adr_link->mask))
+ return -EINVAL;
+
+ for (i = 0; i < adr_link->num_adr; i++) {
+ adr = adr_link->adr_d[i].adr;
+ codec_info = asoc_sdw_find_codec_info_part(adr);
+ if (!codec_info)
+ return -EINVAL;
+
+ *codecs_num += codec_info->dai_num;
+
+ if (!adr_link->adr_d[i].name_prefix) {
+ dev_err(dev, "codec 0x%llx does not have a name prefix\n",
+ adr_link->adr_d[i].adr);
+ return -EINVAL;
+ }
+
+ endpoint = adr_link->adr_d[i].endpoints;
+ if (endpoint->aggregated && !endpoint->group_id) {
+ dev_err(dev, "invalid group id on link %x\n",
+ adr_link->mask);
+ return -EINVAL;
+ }
+
+ for (j = 0; j < codec_info->dai_num; j++) {
+ /* count DAI number for playback and capture */
+ for_each_pcm_streams(stream) {
+ if (!codec_info->dais[j].direction[stream])
+ continue;
+
+ /* count BE for each non-aggregated slave or group */
+ if (!endpoint->aggregated ||
+ !group_visited[endpoint->group_id])
+ (*sdw_be_num)++;
+ }
+ }
+
+ if (endpoint->aggregated)
+ group_visited[endpoint->group_id] = true;
+ }
+ }
+ return 0;
+}
+
+static int fill_sdw_codec_dlc(struct device *dev,
+ const struct snd_soc_acpi_link_adr *adr_link,
+ struct snd_soc_dai_link_component *codec,
+ int adr_index, int dai_index)
+{
+ u64 adr = adr_link->adr_d[adr_index].adr;
+ struct asoc_sdw_codec_info *codec_info;
+
+ codec_info = asoc_sdw_find_codec_info_part(adr);
+ if (!codec_info)
+ return -EINVAL;
+
+ codec->name = asoc_sdw_get_codec_name(dev, codec_info, adr_link, adr_index);
+ if (!codec->name)
+ return -ENOMEM;
+
+ codec->dai_name = codec_info->dais[dai_index].dai_name;
+ dev_err(dev, "codec->dai_name:%s\n", codec->dai_name);
+ return 0;
+}
+
+static int set_codec_init_func(struct snd_soc_card *card,
+ const struct snd_soc_acpi_link_adr *adr_link,
+ struct snd_soc_dai_link *dai_links,
+ bool playback, int group_id, int adr_index, int dai_index)
+{
+ int i = adr_index;
+
+ do {
+ /*
+ * Initialize the codec. If codec is part of an aggregated
+ * group (group_id>0), initialize all codecs belonging to
+ * same group.
+ * The first link should start with adr_link->adr_d[adr_index]
+ * because that is the device that we want to initialize and
+ * we should end immediately if it is not aggregated (group_id=0)
+ */
+ for ( ; i < adr_link->num_adr; i++) {
+ struct asoc_sdw_codec_info *codec_info;
+
+ codec_info = asoc_sdw_find_codec_info_part(adr_link->adr_d[i].adr);
+ if (!codec_info)
+ return -EINVAL;
+
+ /* The group_id is > 0 iff the codec is aggregated */
+ if (adr_link->adr_d[i].endpoints->group_id != group_id)
+ continue;
+ if (codec_info->dais[dai_index].init)
+ codec_info->dais[dai_index].init(card,
+ dai_links,
+ codec_info,
+ playback);
+
+ if (!group_id)
+ return 0;
+ }
+
+ i = 0;
+ adr_link++;
+ } while (adr_link->mask);
+
+ return 0;
+}
+
+/*
+ * check endpoint status in slaves and gather link ID for all slaves in
+ * the same group to generate different CPU DAI. Now only support
+ * one sdw link with all slaves set with only single group id.
+ *
+ * one slave on one sdw link with aggregated = 0
+ * one sdw BE DAI <---> one-cpu DAI <---> one-codec DAI
+ *
+ * two or more slaves on one sdw link with aggregated = 1
+ * one sdw BE DAI <---> one-cpu DAI <---> multi-codec DAIs
+ */
+static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link,
+ struct device *dev, int *cpu_dai_id, int *cpu_dai_num,
+ int *codec_num, unsigned int *group_id,
+ int adr_index)
+{
+ int i;
+
+ if (!adr_link->adr_d[adr_index].endpoints->aggregated) {
+ cpu_dai_id[0] = ffs(adr_link->mask) - 1;
+ *cpu_dai_num = 1;
+ *codec_num = 1;
+ *group_id = 0;
+ return 0;
+ }
+
+ *codec_num = 0;
+ *cpu_dai_num = 0;
+ *group_id = adr_link->adr_d[adr_index].endpoints->group_id;
+
+ /* Count endpoints with the same group_id in the adr_link */
+ for (; adr_link && adr_link->num_adr; adr_link++) {
+ unsigned int link_codecs = 0;
+
+ for (i = 0; i < adr_link->num_adr; i++) {
+ if (adr_link->adr_d[i].endpoints->aggregated &&
+ adr_link->adr_d[i].endpoints->group_id == *group_id)
+ link_codecs++;
+ }
+
+ if (link_codecs) {
+ *codec_num += link_codecs;
+
+ if (*cpu_dai_num >= ACP63_SDW_MAX_CPU_DAIS) {
+ dev_err(dev, "cpu_dai_id array overflowed\n");
+ return -EINVAL;
+ }
+
+ cpu_dai_id[(*cpu_dai_num)++] = ffs(adr_link->mask) - 1;
+ }
+ }
+
+ return 0;
+}
+
+static int get_acp63_cpu_pin_id(u32 sdw_link_id, int be_id, int *cpu_pin_id, struct device *dev)
+{
+ switch (sdw_link_id) {
+ case AMD_SDW0:
+ switch (be_id) {
+ case SOC_SDW_JACK_OUT_DAI_ID:
+ *cpu_pin_id = ACP63_SW0_AUDIO0_TX;
+ break;
+ case SOC_SDW_JACK_IN_DAI_ID:
+ *cpu_pin_id = ACP63_SW0_AUDIO0_RX;
+ break;
+ case SOC_SDW_AMP_OUT_DAI_ID:
+ *cpu_pin_id = ACP63_SW0_AUDIO1_TX;
+ break;
+ case SOC_SDW_AMP_IN_DAI_ID:
+ *cpu_pin_id = ACP63_SW0_AUDIO1_RX;
+ break;
+ case SOC_SDW_DMIC_DAI_ID:
+ *cpu_pin_id = ACP63_SW0_AUDIO2_RX;
+ break;
+ default:
+ dev_err(dev, "Invalid be id:%d\n", be_id);
+ return -EINVAL;
+ }
+ break;
+ case AMD_SDW1:
+ switch (be_id) {
+ case SOC_SDW_JACK_OUT_DAI_ID:
+ case SOC_SDW_AMP_OUT_DAI_ID:
+ *cpu_pin_id = ACP63_SW1_AUDIO0_TX;
+ break;
+ case SOC_SDW_JACK_IN_DAI_ID:
+ case SOC_SDW_AMP_IN_DAI_ID:
+ case SOC_SDW_DMIC_DAI_ID:
+ *cpu_pin_id = ACP63_SW1_AUDIO0_RX;
+ break;
+ default:
+ dev_err(dev, "invalid be_id:%d\n", be_id);
+ return -EINVAL;
+ }
+ break;
+ default:
+ dev_err(dev, "Invalid link id:%d\n", sdw_link_id);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"};
+
+static int create_sdw_dailink(struct snd_soc_card *card,
+ struct snd_soc_dai_link **dai_links,
+ const struct snd_soc_acpi_link_adr *adr_link,
+ struct snd_soc_codec_conf **codec_conf,
+ int *be_id, int adr_index, int dai_index)
+{
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct amd_mc_ctx *amd_ctx = (struct amd_mc_ctx *)ctx->private;
+ struct device *dev = card->dev;
+ const struct snd_soc_acpi_link_adr *adr_link_next;
+ struct snd_soc_dai_link_ch_map *sdw_codec_ch_maps;
+ struct snd_soc_dai_link_component *codecs;
+ struct snd_soc_dai_link_component *cpus;
+ struct asoc_sdw_codec_info *codec_info;
+ int cpu_dai_id[ACP63_SDW_MAX_CPU_DAIS];
+ int cpu_dai_num;
+ unsigned int group_id;
+ unsigned int sdw_link_id;
+ int codec_dlc_index = 0;
+ int codec_num;
+ int stream;
+ int i = 0;
+ int j, k;
+ int ret;
+ int cpu_pin_id;
+
+ ret = get_slave_info(adr_link, dev, cpu_dai_id, &cpu_dai_num, &codec_num,
+ &group_id, adr_index);
+ if (ret)
+ return ret;
+ codecs = devm_kcalloc(dev, codec_num, sizeof(*codecs), GFP_KERNEL);
+ if (!codecs)
+ return -ENOMEM;
+
+ sdw_codec_ch_maps = devm_kcalloc(dev, codec_num,
+ sizeof(*sdw_codec_ch_maps), GFP_KERNEL);
+ if (!sdw_codec_ch_maps)
+ return -ENOMEM;
+
+ /* generate codec name on different links in the same group */
+ j = adr_index;
+ for (adr_link_next = adr_link; adr_link_next && adr_link_next->num_adr &&
+ i < cpu_dai_num; adr_link_next++) {
+ /* skip the link excluded by this processed group */
+ if (cpu_dai_id[i] != ffs(adr_link_next->mask) - 1)
+ continue;
+
+ /* j reset after loop, adr_index only applies to first link */
+ for (k = 0 ; (j < adr_link_next->num_adr) && (k < codec_num) ; j++, k++) {
+ const struct snd_soc_acpi_endpoint *endpoints;
+
+ endpoints = adr_link_next->adr_d[j].endpoints;
+ if (group_id && (!endpoints->aggregated ||
+ endpoints->group_id != group_id))
+ continue;
+
+ /* sanity check */
+ if (*codec_conf >= card->codec_conf + card->num_configs) {
+ dev_err(dev, "codec_conf array overflowed\n");
+ return -EINVAL;
+ }
+
+ ret = fill_sdw_codec_dlc(dev, adr_link_next,
+ &codecs[codec_dlc_index],
+ j, dai_index);
+ if (ret)
+ return ret;
+ (*codec_conf)->dlc = codecs[codec_dlc_index];
+ (*codec_conf)->name_prefix = adr_link_next->adr_d[j].name_prefix;
+
+ sdw_codec_ch_maps[codec_dlc_index].cpu = i;
+ sdw_codec_ch_maps[codec_dlc_index].codec = codec_dlc_index;
+
+ codec_dlc_index++;
+ (*codec_conf)++;
+ }
+ j = 0;
+
+ /* check next link to create codec dai in the processed group */
+ i++;
+ }
+
+ /* find codec info to create BE DAI */
+ codec_info = asoc_sdw_find_codec_info_part(adr_link->adr_d[adr_index].adr);
+ if (!codec_info)
+ return -EINVAL;
+
+ ctx->ignore_internal_dmic |= codec_info->ignore_internal_dmic;
+
+ sdw_link_id = (adr_link->adr_d[adr_index].adr) >> 48;
+ for_each_pcm_streams(stream) {
+ char *name, *cpu_name;
+ int playback, capture;
+ static const char * const sdw_stream_name[] = {
+ "SDW%d-PIN%d-PLAYBACK",
+ "SDW%d-PIN%d-CAPTURE",
+ "SDW%d-PIN%d-PLAYBACK-%s",
+ "SDW%d-PIN%d-CAPTURE-%s",
+ };
+
+ if (!codec_info->dais[dai_index].direction[stream])
+ continue;
+
+ *be_id = codec_info->dais[dai_index].dailink[stream];
+ if (*be_id < 0) {
+ dev_err(dev, "Invalid dailink id %d\n", *be_id);
+ return -EINVAL;
+ }
+ switch (amd_ctx->acp_rev) {
+ case ACP63_PCI_REV:
+ ret = get_acp63_cpu_pin_id(sdw_link_id, *be_id, &cpu_pin_id, dev);
+ if (ret)
+ return ret;
+ break;
+ default:
+ return -EINVAL;
+ }
+ /* create stream name according to first link id */
+ if (ctx->append_dai_type) {
+ name = devm_kasprintf(dev, GFP_KERNEL,
+ sdw_stream_name[stream + 2], sdw_link_id, cpu_pin_id,
+ type_strings[codec_info->dais[dai_index].dai_type]);
+ } else {
+ name = devm_kasprintf(dev, GFP_KERNEL,
+ sdw_stream_name[stream], sdw_link_id, cpu_pin_id);
+ }
+ if (!name)
+ return -ENOMEM;
+
+ cpus = devm_kcalloc(dev, cpu_dai_num, sizeof(*cpus), GFP_KERNEL);
+ if (!cpus)
+ return -ENOMEM;
+ /*
+ * generate CPU DAI name base on the sdw link ID and
+ * cpu pin id according to sdw dai driver.
+ */
+ for (k = 0; k < cpu_dai_num; k++) {
+ cpu_name = devm_kasprintf(dev, GFP_KERNEL,
+ "SDW%d Pin%d", sdw_link_id, cpu_pin_id);
+ if (!cpu_name)
+ return -ENOMEM;
+
+ cpus[k].dai_name = cpu_name;
+ }
+
+ playback = (stream == SNDRV_PCM_STREAM_PLAYBACK);
+ capture = (stream == SNDRV_PCM_STREAM_CAPTURE);
+ asoc_sdw_init_dai_link(dev, *dai_links, be_id, name,
+ playback, capture,
+ cpus, cpu_dai_num,
+ platform_component, ARRAY_SIZE(platform_component),
+ codecs, codec_num,
+ asoc_sdw_rtd_init, &sdw_ops);
+ /*
+ * SoundWire DAILINKs use 'stream' functions and Bank Switch operations
+ * based on wait_for_completion(), tag them as 'nonatomic'.
+ */
+ (*dai_links)->nonatomic = true;
+ (*dai_links)->ch_maps = sdw_codec_ch_maps;
+
+ ret = set_codec_init_func(card, adr_link, *dai_links,
+ playback, group_id, adr_index, dai_index);
+ if (ret < 0) {
+ dev_err(dev, "failed to init codec 0x%x\n", codec_info->part_id);
+ return ret;
+ }
+
+ (*dai_links)++;
+ }
+ return 0;
+}
+
+static int create_dmic_dailinks(struct snd_soc_card *card,
+ struct snd_soc_dai_link **dai_links, int *be_id)
+{
+ struct device *dev = card->dev;
+ int ret;
+
+ ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, "acp-dmic-codec",
+ 0, 1, // DMIC only supports capture
+ "acp-sof-dmic", platform_component->name,
+ ARRAY_SIZE(platform_component),
+ "dmic-codec", "dmic-hifi",
+ asoc_sdw_dmic_init, NULL);
+ if (ret)
+ return ret;
+
+ (*dai_links)++;
+
+ return 0;
+}
+
+static int sof_card_dai_links_create(struct snd_soc_card *card)
+{
+ struct device *dev = card->dev;
+ struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
+ int sdw_be_num = 0, dmic_num = 0;
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
+ const struct snd_soc_acpi_link_adr *adr_link = mach_params->links;
+ struct snd_soc_codec_conf *codec_conf;
+ int codec_conf_num = 0;
+ bool group_generated[AMD_SDW_MAX_GROUPS] = { };
+ struct snd_soc_dai_link *dai_links;
+ struct asoc_sdw_codec_info *codec_info;
+ int num_links;
+ int i, j, be_id = 0;
+ int ret;
+
+ ret = get_dailink_info(dev, adr_link, &sdw_be_num, &codec_conf_num);
+ if (ret < 0) {
+ dev_err(dev, "failed to get sdw link info %d\n", ret);
+ return ret;
+ }
+
+ /* enable dmic */
+ if (sof_sdw_quirk & ASOC_SDW_ACP_DMIC || mach_params->dmic_num)
+ dmic_num = 1;
+
+ dev_dbg(dev, "sdw %d, dmic %d", sdw_be_num, dmic_num);
+
+ /* allocate BE dailinks */
+ num_links = sdw_be_num + dmic_num;
+ dai_links = devm_kcalloc(dev, num_links, sizeof(*dai_links), GFP_KERNEL);
+ if (!dai_links)
+ return -ENOMEM;
+
+ /* allocate codec conf, will be populated when dailinks are created */
+ codec_conf = devm_kcalloc(dev, codec_conf_num, sizeof(*codec_conf),
+ GFP_KERNEL);
+ if (!codec_conf)
+ return -ENOMEM;
+
+ card->dai_link = dai_links;
+ card->num_links = num_links;
+ card->codec_conf = codec_conf;
+ card->num_configs = codec_conf_num;
+
+ /* SDW */
+ if (!sdw_be_num)
+ goto DMIC;
+
+ for (; adr_link->num_adr; adr_link++) {
+ /*
+ * If there are two or more different devices on the same sdw link, we have to
+ * append the codec type to the dai link name to prevent duplicated dai link name.
+ * The same type devices on the same sdw link will be in the same
+ * snd_soc_acpi_adr_device array. They won't be described in different adr_links.
+ */
+ for (i = 0; i < adr_link->num_adr; i++) {
+ /* find codec info to get dai_num */
+ codec_info = asoc_sdw_find_codec_info_part(adr_link->adr_d[i].adr);
+ if (!codec_info)
+ return -EINVAL;
+ if (codec_info->dai_num > 1) {
+ ctx->append_dai_type = true;
+ goto out;
+ }
+ for (j = 0; j < i; j++) {
+ if ((SDW_PART_ID(adr_link->adr_d[i].adr) !=
+ SDW_PART_ID(adr_link->adr_d[j].adr)) ||
+ (SDW_MFG_ID(adr_link->adr_d[i].adr) !=
+ SDW_MFG_ID(adr_link->adr_d[j].adr))) {
+ ctx->append_dai_type = true;
+ goto out;
+ }
+ }
+ }
+ }
+out:
+
+ /* generate DAI links by each sdw link */
+ for (adr_link = mach_params->links ; adr_link->num_adr; adr_link++) {
+ for (i = 0; i < adr_link->num_adr; i++) {
+ const struct snd_soc_acpi_endpoint *endpoint;
+
+ endpoint = adr_link->adr_d[i].endpoints;
+
+ /* this group has been generated */
+ if (endpoint->aggregated &&
+ group_generated[endpoint->group_id])
+ continue;
+
+ /* find codec info to get dai_num */
+ codec_info = asoc_sdw_find_codec_info_part(adr_link->adr_d[i].adr);
+ if (!codec_info)
+ return -EINVAL;
+
+ for (j = 0; j < codec_info->dai_num ; j++) {
+ int current_be_id;
+
+ ret = create_sdw_dailink(card, &dai_links, adr_link,
+ &codec_conf, &current_be_id,
+ i, j);
+ if (ret < 0) {
+ dev_err(dev,
+ "failed to create dai link %d on 0x%x\n",
+ j, codec_info->part_id);
+ return ret;
+ }
+ /* Update the be_id to match the highest ID used for SDW link */
+ if (be_id < current_be_id)
+ be_id = current_be_id;
+ }
+
+ if (endpoint->aggregated)
+ group_generated[endpoint->group_id] = true;
+ }
+ }
+
+DMIC:
+ /* dmic */
+ if (dmic_num > 0) {
+ if (ctx->ignore_internal_dmic) {
+ dev_warn(dev, "Ignoring ACP DMIC\n");
+ } else {
+ be_id = SOC_SDW_DMIC_DAI_ID;
+ ret = create_dmic_dailinks(card, &dai_links, &be_id);
+ if (ret)
+ return ret;
+ }
+ }
+
+ WARN_ON(dai_links != card->dai_link + card->num_links);
+ return 0;
+}
+
+/* SoC card */
+static const char sdw_card_long_name[] = "AMD Soundwire SOF";
+
+static int mc_probe(struct platform_device *pdev)
+{
+ struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev);
+ struct snd_soc_card *card;
+ struct amd_mc_ctx *amd_ctx;
+ struct asoc_sdw_mc_private *ctx;
+ int amp_num = 0, i;
+ int ret;
+
+ amd_ctx = devm_kzalloc(&pdev->dev, sizeof(*amd_ctx), GFP_KERNEL);
+ if (!amd_ctx)
+ return -ENOMEM;
+
+ amd_ctx->acp_rev = mach->mach_params.subsystem_rev;
+ amd_ctx->max_sdw_links = ACP63_SDW_MAX_LINKS;
+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+ ctx->codec_info_list_count = asoc_sdw_get_codec_info_list_count();
+ ctx->private = amd_ctx;
+ card = &ctx->card;
+ card->dev = &pdev->dev;
+ card->name = "amd-soundwire",
+ card->owner = THIS_MODULE,
+ card->late_probe = asoc_sdw_card_late_probe,
+
+ snd_soc_card_set_drvdata(card, ctx);
+
+ dmi_check_system(sof_sdw_quirk_table);
+
+ if (quirk_override != -1) {
+ dev_info(card->dev, "Overriding quirk 0x%lx => 0x%x\n",
+ sof_sdw_quirk, quirk_override);
+ sof_sdw_quirk = quirk_override;
+ }
+
+ log_quirks(card->dev);
+
+ ctx->mc_quirk = sof_sdw_quirk;
+ /* reset amp_num to ensure amp_num++ starts from 0 in each probe */
+ for (i = 0; i < ctx->codec_info_list_count; i++)
+ codec_info_list[i].amp_num = 0;
+
+ ret = sof_card_dai_links_create(card);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * the default amp_num is zero for each codec and
+ * amp_num will only be increased for active amp
+ * codecs on used platform
+ */
+ for (i = 0; i < ctx->codec_info_list_count; i++)
+ amp_num += codec_info_list[i].amp_num;
+
+ card->components = devm_kasprintf(card->dev, GFP_KERNEL,
+ " cfg-amp:%d", amp_num);
+ if (!card->components)
+ return -ENOMEM;
+
+ card->long_name = sdw_card_long_name;
+
+ /* Register the card */
+ ret = devm_snd_soc_register_card(card->dev, card);
+ if (ret) {
+ dev_err_probe(card->dev, ret, "snd_soc_register_card failed %d\n", ret);
+ asoc_sdw_mc_dailink_exit_loop(card);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, card);
+
+ return ret;
+}
+
+static void mc_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+ asoc_sdw_mc_dailink_exit_loop(card);
+}
+
+static const struct platform_device_id mc_id_table[] = {
+ { "amd_sof_sdw", },
+ {}
+};
+MODULE_DEVICE_TABLE(platform, mc_id_table);
+
+static struct platform_driver sof_sdw_driver = {
+ .driver = {
+ .name = "amd_sof_sdw",
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = mc_probe,
+ .remove_new = mc_remove,
+ .id_table = mc_id_table,
+};
+
+module_platform_driver(sof_sdw_driver);
+
+MODULE_DESCRIPTION("ASoC AMD SoundWire Generic Machine driver");
+MODULE_AUTHOR("Vijendar Mukunda <[email protected]");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:amd_sof_sdw");
+MODULE_IMPORT_NS(SND_SOC_SDW_UTILS);
diff --git a/sound/soc/amd/acp/amd-acp63-acpi-match.c b/sound/soc/amd/acp/amd-acp63-acpi-match.c
new file mode 100644
index 000000000000..be9367913073
--- /dev/null
+++ b/sound/soc/amd/acp/amd-acp63-acpi-match.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * amd-acp63-acpi-match.c - tables and support for ACP 6.3 platform
+ * ACPI enumeration.
+ *
+ * Copyright 2024 Advanced Micro Devices, Inc.
+ */
+
+#include <sound/soc-acpi.h>
+#include "../mach-config.h"
+
+static const struct snd_soc_acpi_endpoint single_endpoint = {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0
+};
+
+static const struct snd_soc_acpi_endpoint spk_l_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 0,
+ .group_id = 1
+};
+
+static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
+ .num = 0,
+ .aggregated = 1,
+ .group_position = 1,
+ .group_id = 1
+};
+
+static const struct snd_soc_acpi_adr_device rt711_rt1316_group_adr[] = {
+ {
+ .adr = 0x000030025D071101ull,
+ .num_endpoints = 1,
+ .endpoints = &single_endpoint,
+ .name_prefix = "rt711"
+ },
+ {
+ .adr = 0x000030025D131601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_l_endpoint,
+ .name_prefix = "rt1316-1"
+ },
+ {
+ .adr = 0x000032025D131601ull,
+ .num_endpoints = 1,
+ .endpoints = &spk_r_endpoint,
+ .name_prefix = "rt1316-2"
+ },
+};
+
+static const struct snd_soc_acpi_adr_device rt714_adr[] = {
+ {
+ .adr = 0x130025d071401ull,
+ .num_endpoints = 1,
+ .endpoints = &single_endpoint,
+ .name_prefix = "rt714"
+ }
+};
+
+static const struct snd_soc_acpi_link_adr acp63_4_in_1_sdca[] = {
+ { .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt711_rt1316_group_adr),
+ .adr_d = rt711_rt1316_group_adr,
+ },
+ {
+ .mask = BIT(1),
+ .num_adr = ARRAY_SIZE(rt714_adr),
+ .adr_d = rt714_adr,
+ },
+ {}
+};
+
+struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sof_sdw_machines[] = {
+ {
+ .link_mask = BIT(0) | BIT(1),
+ .links = acp63_4_in_1_sdca,
+ .drv_name = "amd_sof_sdw",
+ .sof_tplg_filename = "sof-acp_6_3-rt711-l0-rt1316-l0-rt714-l1.tplg",
+ .fw_filename = "sof-acp_6_3.ri",
+ },
+ {},
+};
+EXPORT_SYMBOL(snd_soc_acpi_amd_acp63_sof_sdw_machines);
+
+MODULE_DESCRIPTION("AMD ACP6.3 tables and support for ACPI enumeration");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("[email protected]");
diff --git a/sound/soc/amd/acp/soc_amd_sdw_common.h b/sound/soc/amd/acp/soc_amd_sdw_common.h
new file mode 100644
index 000000000000..f1bd5a7afc8e
--- /dev/null
+++ b/sound/soc/amd/acp/soc_amd_sdw_common.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ * Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved
+ */
+
+/*
+ * soc_amd_sdw_common.h - prototypes for common helpers
+ */
+
+#ifndef SOC_AMD_SDW_COMMON_H
+#define SOC_AMD_SDW_COMMON_H
+
+#include <linux/bits.h>
+#include <linux/types.h>
+#include <sound/soc.h>
+#include <sound/soc_sdw_utils.h>
+
+#define ACP63_SDW_MAX_CPU_DAIS 8
+#define ACP63_SDW_MAX_LINKS 2
+
+#define AMD_SDW_MAX_GROUPS 9
+#define ACP63_PCI_REV 0x63
+#define SOC_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0))
+#define ASOC_SDW_FOUR_SPK BIT(4)
+#define ASOC_SDW_ACP_DMIC BIT(5)
+
+#define AMD_SDW0 0
+#define AMD_SDW1 1
+#define ACP63_SW0_AUDIO0_TX 0
+#define ACP63_SW0_AUDIO1_TX 1
+#define ACP63_SW0_AUDIO2_TX 2
+
+#define ACP63_SW0_AUDIO0_RX 3
+#define ACP63_SW0_AUDIO1_RX 4
+#define ACP63_SW0_AUDIO2_RX 5
+
+#define ACP63_SW1_AUDIO0_TX 0
+#define ACP63_SW1_AUDIO0_RX 1
+
+struct amd_mc_ctx {
+ unsigned int acp_rev;
+ unsigned int max_sdw_links;
+};
+
+#endif
diff --git a/sound/soc/amd/mach-config.h b/sound/soc/amd/mach-config.h
index 7af0f9cf3921..32aa8a6931f4 100644
--- a/sound/soc/amd/mach-config.h
+++ b/sound/soc/amd/mach-config.h
@@ -23,6 +23,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_amd_sof_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_amd_rmb_sof_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_amd_vangogh_sof_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sof_machines[];
+extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sof_sdw_machines[];
struct config_entry {
u32 flags;
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
index 551738abd1a5..de9e43185555 100644
--- a/sound/soc/codecs/ak4613.c
+++ b/sound/soc/codecs/ak4613.c
@@ -840,14 +840,14 @@ static void ak4613_parse_of(struct ak4613_priv *priv,
/* Input 1 - 2 */
for (i = 0; i < 2; i++) {
snprintf(prop, sizeof(prop), "asahi-kasei,in%d-single-end", i + 1);
- if (!of_get_property(np, prop, NULL))
+ if (!of_property_read_bool(np, prop))
priv->ic |= 1 << i;
}
/* Output 1 - 6 */
for (i = 0; i < 6; i++) {
snprintf(prop, sizeof(prop), "asahi-kasei,out%d-single-end", i + 1);
- if (!of_get_property(np, prop, NULL))
+ if (!of_property_read_bool(np, prop))
priv->oc |= 1 << i;
}
diff --git a/sound/soc/codecs/cs42l42-sdw.c b/sound/soc/codecs/cs42l42-sdw.c
index 94a66a325303..29891c1f6bec 100644
--- a/sound/soc/codecs/cs42l42-sdw.c
+++ b/sound/soc/codecs/cs42l42-sdw.c
@@ -323,15 +323,15 @@ static int cs42l42_sdw_read_prop(struct sdw_slave *peripheral)
prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
/* DP1 - capture */
- ports[0].num = CS42L42_SDW_CAPTURE_PORT,
- ports[0].type = SDW_DPN_FULL,
- ports[0].ch_prep_timeout = 10,
+ ports[0].num = CS42L42_SDW_CAPTURE_PORT;
+ ports[0].type = SDW_DPN_FULL;
+ ports[0].ch_prep_timeout = 10;
prop->src_dpn_prop = &ports[0];
/* DP2 - playback */
- ports[1].num = CS42L42_SDW_PLAYBACK_PORT,
- ports[1].type = SDW_DPN_FULL,
- ports[1].ch_prep_timeout = 10,
+ ports[1].num = CS42L42_SDW_PLAYBACK_PORT;
+ ports[1].type = SDW_DPN_FULL;
+ ports[1].ch_prep_timeout = 10;
prop->sink_dpn_prop = &ports[1];
return 0;
diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c
index be4037890fdb..cb4ca80f36d2 100644
--- a/sound/soc/codecs/cs43130.c
+++ b/sound/soc/codecs/cs43130.c
@@ -1415,7 +1415,7 @@ static const char * const bypass_mux_text[] = {
static SOC_ENUM_SINGLE_DECL(bypass_enum, SND_SOC_NOPM, 0, bypass_mux_text);
static const struct snd_kcontrol_new bypass_ctrl = SOC_DAPM_ENUM("Switch", bypass_enum);
-static const struct snd_soc_dapm_widget digital_hp_widgets[] = {
+static const struct snd_soc_dapm_widget hp_widgets[] = {
SND_SOC_DAPM_MUX("Bypass Switch", SND_SOC_NOPM, 0, 0, &bypass_ctrl),
SND_SOC_DAPM_OUTPUT("HPOUTA"),
SND_SOC_DAPM_OUTPUT("HPOUTB"),
@@ -1447,19 +1447,16 @@ static const struct snd_soc_dapm_widget digital_hp_widgets[] = {
CS43130_PDN_HP_SHIFT, 1, cs43130_dac_event,
(SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
SND_SOC_DAPM_POST_PMD)),
-};
-static const struct snd_soc_dapm_widget analog_hp_widgets[] = {
+/* Some devices have some extra analog widgets */
+#define NUM_ANALOG_WIDGETS 1
+
SND_SOC_DAPM_DAC_E("Analog Playback", NULL, CS43130_HP_OUT_CTL_1,
CS43130_HP_IN_EN_SHIFT, 0, cs43130_hpin_event,
(SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD)),
};
-static struct snd_soc_dapm_widget all_hp_widgets[
- ARRAY_SIZE(digital_hp_widgets) +
- ARRAY_SIZE(analog_hp_widgets)];
-
-static const struct snd_soc_dapm_route digital_hp_routes[] = {
+static const struct snd_soc_dapm_route hp_routes[] = {
{"ASPIN PCM", NULL, "ASP PCM Playback"},
{"ASPIN DoP", NULL, "ASP DoP Playback"},
{"XSPIN DoP", NULL, "XSP DoP Playback"},
@@ -1472,15 +1469,12 @@ static const struct snd_soc_dapm_route digital_hp_routes[] = {
{"Bypass Switch", "Internal", "HiFi DAC"},
{"HPOUTA", NULL, "Bypass Switch"},
{"HPOUTB", NULL, "Bypass Switch"},
-};
-static const struct snd_soc_dapm_route analog_hp_routes[] = {
+/* Some devices have some extra analog routes */
+#define NUM_ANALOG_ROUTES 1
{"Bypass Switch", "Alternative", "Analog Playback"},
};
-static struct snd_soc_dapm_route all_hp_routes[
- ARRAY_SIZE(digital_hp_routes) +
- ARRAY_SIZE(analog_hp_routes)];
static const unsigned int cs43130_asp_src_rates[] = {
32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000
@@ -2398,7 +2392,23 @@ static int cs43130_probe(struct snd_soc_component *component)
return 0;
}
-static struct snd_soc_component_driver soc_component_dev_cs43130 = {
+static const struct snd_soc_component_driver soc_component_dev_cs43130_digital = {
+ .probe = cs43130_probe,
+ .controls = cs43130_snd_controls,
+ .num_controls = ARRAY_SIZE(cs43130_snd_controls),
+ .set_sysclk = cs43130_component_set_sysclk,
+ .set_pll = cs43130_set_pll,
+ .idle_bias_on = 1,
+ .use_pmdown_time = 1,
+ .endianness = 1,
+ /* Don't take into account the ending analog widgets and routes */
+ .dapm_widgets = hp_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(hp_widgets) - NUM_ANALOG_WIDGETS,
+ .dapm_routes = hp_routes,
+ .num_dapm_routes = ARRAY_SIZE(hp_routes) - NUM_ANALOG_ROUTES,
+};
+
+static const struct snd_soc_component_driver soc_component_dev_cs43130_analog = {
.probe = cs43130_probe,
.controls = cs43130_snd_controls,
.num_controls = ARRAY_SIZE(cs43130_snd_controls),
@@ -2407,6 +2417,10 @@ static struct snd_soc_component_driver soc_component_dev_cs43130 = {
.idle_bias_on = 1,
.use_pmdown_time = 1,
.endianness = 1,
+ .dapm_widgets = hp_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(hp_widgets),
+ .dapm_routes = hp_routes,
+ .num_dapm_routes = ARRAY_SIZE(hp_routes),
};
static const struct regmap_config cs43130_regmap = {
@@ -2479,6 +2493,7 @@ static int cs43130_handle_device_data(struct cs43130_private *cs43130)
static int cs43130_i2c_probe(struct i2c_client *client)
{
+ const struct snd_soc_component_driver *component_driver;
struct cs43130_private *cs43130;
int ret;
unsigned int reg;
@@ -2596,39 +2611,15 @@ static int cs43130_i2c_probe(struct i2c_client *client)
switch (cs43130->dev_id) {
case CS43130_CHIP_ID:
case CS43131_CHIP_ID:
- memcpy(all_hp_widgets, digital_hp_widgets,
- sizeof(digital_hp_widgets));
- memcpy(all_hp_widgets + ARRAY_SIZE(digital_hp_widgets),
- analog_hp_widgets, sizeof(analog_hp_widgets));
- memcpy(all_hp_routes, digital_hp_routes,
- sizeof(digital_hp_routes));
- memcpy(all_hp_routes + ARRAY_SIZE(digital_hp_routes),
- analog_hp_routes, sizeof(analog_hp_routes));
-
- soc_component_dev_cs43130.dapm_widgets =
- all_hp_widgets;
- soc_component_dev_cs43130.num_dapm_widgets =
- ARRAY_SIZE(all_hp_widgets);
- soc_component_dev_cs43130.dapm_routes =
- all_hp_routes;
- soc_component_dev_cs43130.num_dapm_routes =
- ARRAY_SIZE(all_hp_routes);
+ component_driver = &soc_component_dev_cs43130_analog;
break;
case CS43198_CHIP_ID:
case CS4399_CHIP_ID:
- soc_component_dev_cs43130.dapm_widgets =
- digital_hp_widgets;
- soc_component_dev_cs43130.num_dapm_widgets =
- ARRAY_SIZE(digital_hp_widgets);
- soc_component_dev_cs43130.dapm_routes =
- digital_hp_routes;
- soc_component_dev_cs43130.num_dapm_routes =
- ARRAY_SIZE(digital_hp_routes);
+ component_driver = &soc_component_dev_cs43130_digital;
break;
}
- ret = devm_snd_soc_register_component(cs43130->dev,
- &soc_component_dev_cs43130,
+ ret = devm_snd_soc_register_component(cs43130->dev, component_driver,
cs43130_dai, ARRAY_SIZE(cs43130_dai));
if (ret < 0) {
dev_err(cs43130->dev,
diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c
index b246694ebb4f..60877116c0ef 100644
--- a/sound/soc/codecs/es8326.c
+++ b/sound/soc/codecs/es8326.c
@@ -805,6 +805,7 @@ static void es8326_jack_button_handler(struct work_struct *work)
SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2);
button_to_report = 0;
}
+ es8326_disable_micbias(es8326->component);
}
mutex_unlock(&es8326->lock);
}
@@ -878,7 +879,6 @@ static void es8326_jack_detect_handler(struct work_struct *work)
regmap_write(es8326->regmap, ES8326_INT_SOURCE, 0x00);
regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x01);
regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x10, 0x00);
- es8326_enable_micbias(es8326->component);
usleep_range(50000, 70000);
regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00);
regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x10, 0x10);
@@ -897,6 +897,7 @@ static void es8326_jack_detect_handler(struct work_struct *work)
dev_dbg(comp->dev, "button pressed\n");
regmap_write(es8326->regmap, ES8326_INT_SOURCE,
(ES8326_INT_SRC_PIN9 | ES8326_INT_SRC_BUTTON));
+ es8326_enable_micbias(es8326->component);
queue_delayed_work(system_wq, &es8326->button_press_work, 10);
goto exit;
}
@@ -1067,6 +1068,7 @@ static void es8326_init(struct snd_soc_component *component)
regmap_write(es8326->regmap, ES8326_ADC_MUTE, 0x0f);
regmap_write(es8326->regmap, ES8326_CLK_DIV_LRCK, 0xff);
+ es8326_disable_micbias(es8326->component);
msleep(200);
regmap_write(es8326->regmap, ES8326_INT_SOURCE, ES8326_INT_SRC_PIN9);
diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c
index 73a588289408..76900274acf3 100644
--- a/sound/soc/codecs/lpass-wsa-macro.c
+++ b/sound/soc/codecs/lpass-wsa-macro.c
@@ -2297,36 +2297,37 @@ static int wsa_macro_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
u32 enable = ucontrol->value.integer.value[0];
u32 spk_tx_id = mixer->shift;
+ u32 dai_id = widget->shift;
if (enable) {
if (spk_tx_id == WSA_MACRO_TX0 &&
!test_bit(WSA_MACRO_TX0,
- &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
+ &wsa->active_ch_mask[dai_id])) {
set_bit(WSA_MACRO_TX0,
- &wsa->active_ch_mask[WSA_MACRO_AIF_VI]);
- wsa->active_ch_cnt[WSA_MACRO_AIF_VI]++;
+ &wsa->active_ch_mask[dai_id]);
+ wsa->active_ch_cnt[dai_id]++;
}
if (spk_tx_id == WSA_MACRO_TX1 &&
!test_bit(WSA_MACRO_TX1,
- &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
+ &wsa->active_ch_mask[dai_id])) {
set_bit(WSA_MACRO_TX1,
- &wsa->active_ch_mask[WSA_MACRO_AIF_VI]);
- wsa->active_ch_cnt[WSA_MACRO_AIF_VI]++;
+ &wsa->active_ch_mask[dai_id]);
+ wsa->active_ch_cnt[dai_id]++;
}
} else {
if (spk_tx_id == WSA_MACRO_TX0 &&
test_bit(WSA_MACRO_TX0,
- &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
+ &wsa->active_ch_mask[dai_id])) {
clear_bit(WSA_MACRO_TX0,
- &wsa->active_ch_mask[WSA_MACRO_AIF_VI]);
- wsa->active_ch_cnt[WSA_MACRO_AIF_VI]--;
+ &wsa->active_ch_mask[dai_id]);
+ wsa->active_ch_cnt[dai_id]--;
}
if (spk_tx_id == WSA_MACRO_TX1 &&
test_bit(WSA_MACRO_TX1,
- &wsa->active_ch_mask[WSA_MACRO_AIF_VI])) {
+ &wsa->active_ch_mask[dai_id])) {
clear_bit(WSA_MACRO_TX1,
- &wsa->active_ch_mask[WSA_MACRO_AIF_VI]);
- wsa->active_ch_cnt[WSA_MACRO_AIF_VI]--;
+ &wsa->active_ch_mask[dai_id]);
+ wsa->active_ch_cnt[dai_id]--;
}
}
snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c
index f50f196d700d..ce2e88e066f3 100644
--- a/sound/soc/codecs/rt5682s.c
+++ b/sound/soc/codecs/rt5682s.c
@@ -2828,7 +2828,9 @@ static int rt5682s_register_dai_clks(struct snd_soc_component *component)
}
if (dev->of_node) {
- devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, dai_clk_hw);
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, dai_clk_hw);
+ if (ret)
+ return ret;
} else {
ret = devm_clk_hw_register_clkdev(dev, dai_clk_hw,
init.name, dev_name(dev));
diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c
index c421906a0694..4ab15be69f3a 100644
--- a/sound/soc/codecs/sti-sas.c
+++ b/sound/soc/codecs/sti-sas.c
@@ -63,10 +63,6 @@ struct sti_spdif_audio {
struct sti_sas_dev_data {
const struct regmap_config *regmap;
const struct snd_soc_dai_ops *dac_ops; /* DAC function callbacks */
- const struct snd_soc_dapm_widget *dapm_widgets; /* dapms declaration */
- const int num_dapm_widgets; /* dapms declaration */
- const struct snd_soc_dapm_route *dapm_routes; /* route declaration */
- const int num_dapm_routes; /* route declaration */
};
/* driver data structure */
@@ -324,10 +320,6 @@ static const struct regmap_config stih407_sas_regmap = {
static const struct sti_sas_dev_data stih407_data = {
.regmap = &stih407_sas_regmap,
.dac_ops = &stih407_dac_ops,
- .dapm_widgets = stih407_sas_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(stih407_sas_dapm_widgets),
- .dapm_routes = stih407_sas_route,
- .num_dapm_routes = ARRAY_SIZE(stih407_sas_route),
};
static struct snd_soc_dai_driver sti_sas_dai[] = {
@@ -386,12 +378,16 @@ static int sti_sas_component_probe(struct snd_soc_component *component)
return sti_sas_init_sas_registers(component, drvdata);
}
-static struct snd_soc_component_driver sti_sas_driver = {
+static const struct snd_soc_component_driver sti_sas_driver = {
.probe = sti_sas_component_probe,
.resume = sti_sas_resume,
.idle_bias_on = 1,
.use_pmdown_time = 1,
.endianness = 1,
+ .dapm_widgets = stih407_sas_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(stih407_sas_dapm_widgets),
+ .dapm_routes = stih407_sas_route,
+ .num_dapm_routes = ARRAY_SIZE(stih407_sas_route),
};
static const struct of_device_id sti_sas_dev_match[] = {
@@ -446,13 +442,6 @@ static int sti_sas_driver_probe(struct platform_device *pdev)
sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops;
- /* Set dapms*/
- sti_sas_driver.dapm_widgets = drvdata->dev_data->dapm_widgets;
- sti_sas_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets;
-
- sti_sas_driver.dapm_routes = drvdata->dev_data->dapm_routes;
- sti_sas_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes;
-
/* Store context */
dev_set_drvdata(&pdev->dev, drvdata);
diff --git a/sound/soc/codecs/tas2781-comlib.c b/sound/soc/codecs/tas2781-comlib.c
index 1fbf4560f5cc..58abbc098a91 100644
--- a/sound/soc/codecs/tas2781-comlib.c
+++ b/sound/soc/codecs/tas2781-comlib.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
//
-// TAS2781 Common functions for HDA and ASoC Audio drivers
+// TAS2563/TAS2781 Common functions for HDA and ASoC Audio drivers
//
// Copyright 2023 - 2024 Texas Instruments, Inc.
//
@@ -64,8 +64,8 @@ static int tasdevice_change_chn_book(struct tasdevice_priv *tas_priv,
*/
ret = regmap_write(map, TASDEVICE_PAGE_SELECT, 0);
if (ret < 0) {
- dev_err(tas_priv->dev, "%s, E=%d\n",
- __func__, ret);
+ dev_err(tas_priv->dev, "%s, E=%d channel:%d\n",
+ __func__, ret, chn);
goto out;
}
}
diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c
index e79d613745b4..8a57c045afdd 100644
--- a/sound/soc/codecs/tas2781-i2c.c
+++ b/sound/soc/codecs/tas2781-i2c.c
@@ -30,6 +30,7 @@
#include <sound/soc.h>
#include <sound/tas2781.h>
#include <sound/tlv.h>
+#include <sound/tas2563-tlv.h>
#include <sound/tas2781-tlv.h>
#include <asm/unaligned.h>
diff --git a/sound/soc/codecs/wcd937x.h b/sound/soc/codecs/wcd937x.h
index 37bff16e88dd..35f3d48bd7dd 100644
--- a/sound/soc/codecs/wcd937x.h
+++ b/sound/soc/codecs/wcd937x.h
@@ -484,10 +484,25 @@
#define WCD937X_MAX_MICBIAS 3
#define WCD937X_MAX_BULK_SUPPLY 4
-#define WCD937X_MAX_TX_SWR_PORTS 4
-#define WCD937X_MAX_SWR_PORTS 5
#define WCD937X_MAX_SWR_CH_IDS 15
+enum wcd937x_tx_sdw_ports {
+ WCD937X_ADC_1_PORT = 1,
+ WCD937X_ADC_2_3_PORT,
+ WCD937X_DMIC_0_3_MBHC_PORT,
+ WCD937X_DMIC_4_6_PORT,
+ WCD937X_MAX_TX_SWR_PORTS = WCD937X_DMIC_4_6_PORT,
+};
+
+enum wcd937x_rx_sdw_ports {
+ WCD937X_HPH_PORT = 1,
+ WCD937X_CLSH_PORT,
+ WCD937X_COMP_PORT,
+ WCD937X_LO_PORT,
+ WCD937X_DSD_PORT,
+ WCD937X_MAX_SWR_PORTS = WCD937X_DSD_PORT,
+};
+
struct wcd937x_sdw_ch_info {
int port_num;
unsigned int ch_mask;
@@ -581,13 +596,6 @@ enum {
WCD937X_NUM_IRQS,
};
-enum wcd937x_tx_sdw_ports {
- WCD937X_ADC_1_PORT = 1,
- WCD937X_ADC_2_3_PORT,
- WCD937X_DMIC_0_3_MBHC_PORT,
- WCD937X_DMIC_4_6_PORT,
-};
-
enum wcd937x_tx_sdw_channels {
WCD937X_ADC1,
WCD937X_ADC2,
@@ -602,14 +610,6 @@ enum wcd937x_tx_sdw_channels {
WCD937X_DMIC6,
};
-enum wcd937x_rx_sdw_ports {
- WCD937X_HPH_PORT = 1,
- WCD937X_CLSH_PORT,
- WCD937X_COMP_PORT,
- WCD937X_LO_PORT,
- WCD937X_DSD_PORT,
-};
-
enum wcd937x_rx_sdw_channels {
WCD937X_HPH_L,
WCD937X_HPH_R,
diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c
index 12b32d5dc580..aa92f1bfc921 100644
--- a/sound/soc/codecs/wcd938x.c
+++ b/sound/soc/codecs/wcd938x.c
@@ -29,7 +29,6 @@
#define WCD938X_MAX_SUPPLY (4)
#define WCD938X_MBHC_MAX_BUTTONS (8)
#define TX_ADC_MAX (4)
-#define WCD938X_TX_MAX_SWR_PORTS (5)
#define WCD938X_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
@@ -39,8 +38,6 @@
SNDRV_PCM_RATE_176400)
#define WCD938X_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE)
-/* Convert from vout ctl to micbias voltage in mV */
-#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
#define SWR_CLK_RATE_0P6MHZ (600000)
#define SWR_CLK_RATE_1P2MHZ (1200000)
#define SWR_CLK_RATE_2P4MHZ (2400000)
@@ -48,8 +45,6 @@
#define SWR_CLK_RATE_9P6MHZ (9600000)
#define SWR_CLK_RATE_11P2896MHZ (1128960)
-#define WCD938X_DRV_NAME "wcd938x_codec"
-#define WCD938X_VERSION_1_0 (1)
#define EAR_RX_PATH_AUX (1)
#define ADC_MODE_VAL_HIFI 0x01
@@ -72,7 +67,6 @@
/* Z value compared in milliOhm */
#define WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000))
#define WCD938X_MBHC_ZDET_CONST (86 * 16384)
-#define WCD938X_MBHC_MOISTURE_RREF R_24_KOHM
#define WCD_MBHC_HS_V_MAX 1600
#define WCD938X_EAR_PA_GAIN_TLV(xname, reg, shift, max, invert, tlv_array) \
@@ -90,18 +84,6 @@ enum {
};
enum {
- TX_HDR12 = 0,
- TX_HDR34,
- TX_HDR_MAX,
-};
-
-enum {
- WCD_RX1,
- WCD_RX2,
- WCD_RX3
-};
-
-enum {
/* INTR_CTRL_INT_MASK_0 */
WCD938X_IRQ_MBHC_BUTTON_PRESS_DET = 0,
WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET,
diff --git a/sound/soc/codecs/wcd938x.h b/sound/soc/codecs/wcd938x.h
index b2ad98026ae2..fb6a0e4ef337 100644
--- a/sound/soc/codecs/wcd938x.h
+++ b/sound/soc/codecs/wcd938x.h
@@ -585,8 +585,6 @@
#define WCD938X_DIGITAL_DEM_BYPASS_DATA3 (0x34D8)
#define WCD938X_MAX_REGISTER (WCD938X_DIGITAL_DEM_BYPASS_DATA3)
-#define WCD938X_MAX_SWR_PORTS 5
-#define WCD938X_MAX_TX_SWR_PORTS 4
#define WCD938X_MAX_SWR_CH_IDS 15
struct wcd938x_sdw_ch_info {
@@ -606,6 +604,7 @@ enum wcd938x_tx_sdw_ports {
/* DMIC0_0, DMIC0_1, DMIC1_0, DMIC1_1 */
WCD938X_DMIC_0_3_MBHC_PORT,
WCD938X_DMIC_4_7_PORT,
+ WCD938X_MAX_TX_SWR_PORTS = WCD938X_DMIC_4_7_PORT,
};
enum wcd938x_tx_sdw_channels {
@@ -630,6 +629,7 @@ enum wcd938x_rx_sdw_ports {
WCD938X_COMP_PORT,
WCD938X_LO_PORT,
WCD938X_DSD_PORT,
+ WCD938X_MAX_SWR_PORTS = WCD938X_DSD_PORT,
};
enum wcd938x_rx_sdw_channels {
diff --git a/sound/soc/codecs/wcd939x.h b/sound/soc/codecs/wcd939x.h
index 1571c2120cfc..3204fb10b58d 100644
--- a/sound/soc/codecs/wcd939x.h
+++ b/sound/soc/codecs/wcd939x.h
@@ -842,9 +842,6 @@
#define WCD939X_DSD_HPHR_CFG5 (0x35a6)
#define WCD939X_MAX_REGISTER (WCD939X_DSD_HPHR_CFG5)
-#define WCD939X_MAX_SWR_PORTS (6)
-#define WCD939X_MAX_RX_SWR_PORTS (6)
-#define WCD939X_MAX_TX_SWR_PORTS (4)
#define WCD939X_MAX_SWR_CH_IDS (15)
struct wcd939x_sdw_ch_info {
@@ -863,6 +860,7 @@ enum wcd939x_tx_sdw_ports {
WCD939X_ADC_DMIC_1_2_PORT,
WCD939X_DMIC_0_3_MBHC_PORT,
WCD939X_DMIC_3_7_PORT,
+ WCD939X_MAX_TX_SWR_PORTS = WCD939X_DMIC_3_7_PORT,
};
enum wcd939x_tx_sdw_channels {
@@ -888,6 +886,8 @@ enum wcd939x_rx_sdw_ports {
WCD939X_LO_PORT,
WCD939X_DSD_PORT,
WCD939X_HIFI_PCM_PORT,
+ WCD939X_MAX_RX_SWR_PORTS = WCD939X_HIFI_PCM_PORT,
+ WCD939X_MAX_SWR_PORTS = WCD939X_MAX_RX_SWR_PORTS,
};
enum wcd939x_rx_sdw_channels {
diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c
index fb9e92f08d98..dd2d6661adc7 100644
--- a/sound/soc/codecs/wsa881x.c
+++ b/sound/soc/codecs/wsa881x.c
@@ -386,33 +386,32 @@ enum wsa_port_ids {
/* 4 ports */
static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA881X_MAX_SWR_PORTS] = {
- {
- /* DAC */
- .num = 1,
+ [WSA881X_PORT_DAC] = {
+ .num = WSA881X_PORT_DAC + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
.simple_ch_prep_sm = true,
.read_only_wordlength = true,
- }, {
- /* COMP */
- .num = 2,
+ },
+ [WSA881X_PORT_COMP] = {
+ .num = WSA881X_PORT_COMP + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
.simple_ch_prep_sm = true,
.read_only_wordlength = true,
- }, {
- /* BOOST */
- .num = 3,
+ },
+ [WSA881X_PORT_BOOST] = {
+ .num = WSA881X_PORT_BOOST + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
.simple_ch_prep_sm = true,
.read_only_wordlength = true,
- }, {
- /* VISENSE */
- .num = 4,
+ },
+ [WSA881X_PORT_VISENSE] = {
+ .num = WSA881X_PORT_VISENSE + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
@@ -422,17 +421,20 @@ static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA881X_MAX_SWR_PORTS] = {
};
static const struct sdw_port_config wsa881x_pconfig[WSA881X_MAX_SWR_PORTS] = {
- {
- .num = 1,
+ [WSA881X_PORT_DAC] = {
+ .num = WSA881X_PORT_DAC + 1,
.ch_mask = 0x1,
- }, {
- .num = 2,
+ },
+ [WSA881X_PORT_COMP] = {
+ .num = WSA881X_PORT_COMP + 1,
.ch_mask = 0xf,
- }, {
- .num = 3,
+ },
+ [WSA881X_PORT_BOOST] = {
+ .num = WSA881X_PORT_BOOST + 1,
.ch_mask = 0x3,
- }, { /* IV feedback */
- .num = 4,
+ },
+ [WSA881X_PORT_VISENSE] = {
+ .num = WSA881X_PORT_VISENSE + 1,
.ch_mask = 0x3,
},
};
@@ -680,7 +682,6 @@ struct wsa881x_priv {
* For backwards compatibility.
*/
unsigned int sd_n_val;
- int version;
int active_ports;
bool port_prepared[WSA881X_MAX_SWR_PORTS];
bool port_enable[WSA881X_MAX_SWR_PORTS];
@@ -691,7 +692,6 @@ static void wsa881x_init(struct wsa881x_priv *wsa881x)
struct regmap *rm = wsa881x->regmap;
unsigned int val = 0;
- regmap_read(rm, WSA881X_CHIP_ID1, &wsa881x->version);
regmap_register_patch(wsa881x->regmap, wsa881x_rev_2_0,
ARRAY_SIZE(wsa881x_rev_2_0));
diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c
index 3e4fdaa3f44f..47da5674d7c9 100644
--- a/sound/soc/codecs/wsa883x.c
+++ b/sound/soc/codecs/wsa883x.c
@@ -438,8 +438,6 @@ struct wsa883x_priv {
struct gpio_desc *sd_n;
bool port_prepared[WSA883X_MAX_SWR_PORTS];
bool port_enable[WSA883X_MAX_SWR_PORTS];
- int version;
- int variant;
int active_ports;
int dev_mode;
int comp_offset;
@@ -482,33 +480,32 @@ static const struct soc_enum wsa_dev_mode_enum =
/* 4 ports */
static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA883X_MAX_SWR_PORTS] = {
- {
- /* DAC */
- .num = 1,
+ [WSA883X_PORT_DAC] = {
+ .num = WSA883X_PORT_DAC + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
.simple_ch_prep_sm = true,
.read_only_wordlength = true,
- }, {
- /* COMP */
- .num = 2,
+ },
+ [WSA883X_PORT_COMP] = {
+ .num = WSA883X_PORT_COMP + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
.simple_ch_prep_sm = true,
.read_only_wordlength = true,
- }, {
- /* BOOST */
- .num = 3,
+ },
+ [WSA883X_PORT_BOOST] = {
+ .num = WSA883X_PORT_BOOST + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
.simple_ch_prep_sm = true,
.read_only_wordlength = true,
- }, {
- /* VISENSE */
- .num = 4,
+ },
+ [WSA883X_PORT_VISENSE] = {
+ .num = WSA883X_PORT_VISENSE + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
@@ -518,17 +515,20 @@ static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA883X_MAX_SWR_PORTS] = {
};
static const struct sdw_port_config wsa883x_pconfig[WSA883X_MAX_SWR_PORTS] = {
- {
- .num = 1,
+ [WSA883X_PORT_DAC] = {
+ .num = WSA883X_PORT_DAC + 1,
.ch_mask = 0x1,
- }, {
- .num = 2,
+ },
+ [WSA883X_PORT_COMP] = {
+ .num = WSA883X_PORT_COMP + 1,
.ch_mask = 0xf,
- }, {
- .num = 3,
+ },
+ [WSA883X_PORT_BOOST] = {
+ .num = WSA883X_PORT_BOOST + 1,
.ch_mask = 0x3,
- }, { /* IV feedback */
- .num = 4,
+ },
+ [WSA883X_PORT_VISENSE] = {
+ .num = WSA883X_PORT_VISENSE + 1,
.ch_mask = 0x3,
},
};
@@ -997,33 +997,36 @@ static const struct reg_sequence reg_init[] = {
{WSA883X_GMAMP_SUP1, 0xE2},
};
-static void wsa883x_init(struct wsa883x_priv *wsa883x)
+static int wsa883x_init(struct wsa883x_priv *wsa883x)
{
struct regmap *regmap = wsa883x->regmap;
- int variant, version;
+ int variant, version, ret;
- regmap_read(regmap, WSA883X_OTP_REG_0, &variant);
- wsa883x->variant = variant & WSA883X_ID_MASK;
+ ret = regmap_read(regmap, WSA883X_OTP_REG_0, &variant);
+ if (ret)
+ return ret;
+ variant = variant & WSA883X_ID_MASK;
- regmap_read(regmap, WSA883X_CHIP_ID0, &version);
- wsa883x->version = version;
+ ret = regmap_read(regmap, WSA883X_CHIP_ID0, &version);
+ if (ret)
+ return ret;
- switch (wsa883x->variant) {
+ switch (variant) {
case WSA8830:
dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8830\n",
- wsa883x->version);
+ version);
break;
case WSA8835:
dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835\n",
- wsa883x->version);
+ version);
break;
case WSA8832:
dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8832\n",
- wsa883x->version);
+ version);
break;
case WSA8835_V2:
dev_info(wsa883x->dev, "WSA883X Version 1_%d, Variant: WSA8835_V2\n",
- wsa883x->version);
+ version);
break;
default:
break;
@@ -1034,12 +1037,14 @@ static void wsa883x_init(struct wsa883x_priv *wsa883x)
/* Initial settings */
regmap_multi_reg_write(regmap, reg_init, ARRAY_SIZE(reg_init));
- if (wsa883x->variant == WSA8830 || wsa883x->variant == WSA8832) {
+ if (variant == WSA8830 || variant == WSA8832) {
wsa883x->comp_offset = COMP_OFFSET3;
regmap_update_bits(regmap, WSA883X_DRE_CTL_0,
WSA883X_DRE_OFFSET_MASK,
wsa883x->comp_offset);
}
+
+ return 0;
}
static int wsa883x_update_status(struct sdw_slave *slave,
@@ -1048,7 +1053,7 @@ static int wsa883x_update_status(struct sdw_slave *slave,
struct wsa883x_priv *wsa883x = dev_get_drvdata(&slave->dev);
if (status == SDW_SLAVE_ATTACHED && slave->dev_num > 0)
- wsa883x_init(wsa883x);
+ return wsa883x_init(wsa883x);
return 0;
}
diff --git a/sound/soc/codecs/wsa884x.c b/sound/soc/codecs/wsa884x.c
index 89eb5e03a617..8db1380d1f10 100644
--- a/sound/soc/codecs/wsa884x.c
+++ b/sound/soc/codecs/wsa884x.c
@@ -703,7 +703,6 @@ struct wsa884x_priv {
struct reset_control *sd_reset;
bool port_prepared[WSA884X_MAX_SWR_PORTS];
bool port_enable[WSA884X_MAX_SWR_PORTS];
- unsigned int variant;
int active_ports;
int dev_mode;
bool hw_init;
@@ -782,42 +781,47 @@ static const struct soc_enum wsa884x_dev_mode_enum =
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa884x_dev_mode_text), wsa884x_dev_mode_text);
static struct sdw_dpn_prop wsa884x_sink_dpn_prop[WSA884X_MAX_SWR_PORTS] = {
- {
+ [WSA884X_PORT_DAC] = {
.num = WSA884X_PORT_DAC + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
.simple_ch_prep_sm = true,
.read_only_wordlength = true,
- }, {
+ },
+ [WSA884X_PORT_COMP] = {
.num = WSA884X_PORT_COMP + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
.simple_ch_prep_sm = true,
.read_only_wordlength = true,
- }, {
+ },
+ [WSA884X_PORT_BOOST] = {
.num = WSA884X_PORT_BOOST + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
.simple_ch_prep_sm = true,
.read_only_wordlength = true,
- }, {
+ },
+ [WSA884X_PORT_PBR] = {
.num = WSA884X_PORT_PBR + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
.simple_ch_prep_sm = true,
.read_only_wordlength = true,
- }, {
+ },
+ [WSA884X_PORT_VISENSE] = {
.num = WSA884X_PORT_VISENSE + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
.max_ch = 1,
.simple_ch_prep_sm = true,
.read_only_wordlength = true,
- }, {
+ },
+ [WSA884X_PORT_CPS] = {
.num = WSA884X_PORT_CPS + 1,
.type = SDW_DPN_SIMPLE,
.min_ch = 1,
@@ -828,22 +832,27 @@ static struct sdw_dpn_prop wsa884x_sink_dpn_prop[WSA884X_MAX_SWR_PORTS] = {
};
static const struct sdw_port_config wsa884x_pconfig[WSA884X_MAX_SWR_PORTS] = {
- {
+ [WSA884X_PORT_DAC] = {
.num = WSA884X_PORT_DAC + 1,
.ch_mask = 0x1,
- }, {
+ },
+ [WSA884X_PORT_COMP] = {
.num = WSA884X_PORT_COMP + 1,
.ch_mask = 0xf,
- }, {
+ },
+ [WSA884X_PORT_BOOST] = {
.num = WSA884X_PORT_BOOST + 1,
.ch_mask = 0x3,
- }, {
+ },
+ [WSA884X_PORT_PBR] = {
.num = WSA884X_PORT_PBR + 1,
.ch_mask = 0x1,
- }, {
+ },
+ [WSA884X_PORT_VISENSE] = {
.num = WSA884X_PORT_VISENSE + 1,
.ch_mask = 0x3,
- }, {
+ },
+ [WSA884X_PORT_CPS] = {
.num = WSA884X_PORT_CPS + 1,
.ch_mask = 0x3,
},
@@ -1465,7 +1474,7 @@ static void wsa884x_init(struct wsa884x_priv *wsa884x)
unsigned int variant = 0;
if (!regmap_read(wsa884x->regmap, WSA884X_OTP_REG_0, &variant))
- wsa884x->variant = variant & WSA884X_OTP_REG_0_ID_MASK;
+ variant = variant & WSA884X_OTP_REG_0_ID_MASK;
regmap_multi_reg_write(wsa884x->regmap, wsa884x_reg_init,
ARRAY_SIZE(wsa884x_reg_init));
@@ -1474,7 +1483,7 @@ static void wsa884x_init(struct wsa884x_priv *wsa884x)
wo_ctl_0 |= FIELD_PREP(WSA884X_ANA_WO_CTL_0_DAC_CM_CLAMP_EN_MASK,
WSA884X_ANA_WO_CTL_0_DAC_CM_CLAMP_EN_MODE_SPEAKER);
/* Assume that compander is enabled by default unless it is haptics sku */
- if (wsa884x->variant == WSA884X_OTP_ID_WSA8845H)
+ if (variant == WSA884X_OTP_ID_WSA8845H)
wo_ctl_0 |= FIELD_PREP(WSA884X_ANA_WO_CTL_0_PA_AUX_GAIN_MASK,
WSA884X_ANA_WO_CTL_0_PA_AUX_18_DB);
else
diff --git a/sound/soc/fsl/lpc3xxx-i2s.c b/sound/soc/fsl/lpc3xxx-i2s.c
index af995ca081a3..c65c17dfa174 100644
--- a/sound/soc/fsl/lpc3xxx-i2s.c
+++ b/sound/soc/fsl/lpc3xxx-i2s.c
@@ -39,7 +39,7 @@ static void __lpc3xxx_find_clkdiv(u32 *clkx, u32 *clky, int freq, int xbytes, u3
{
u32 i2srate;
u32 idxx, idyy;
- u32 savedbitclkrate, diff, trate, baseclk;
+ u32 diff, trate, baseclk;
/* Adjust rate for sample size (bits) and 2 channels and offset for
* divider in clock output
@@ -53,14 +53,12 @@ static void __lpc3xxx_find_clkdiv(u32 *clkx, u32 *clky, int freq, int xbytes, u3
/* Find the best divider */
*clkx = *clky = 0;
- savedbitclkrate = 0;
diff = ~0;
for (idxx = 1; idxx < 0xFF; idxx++) {
for (idyy = 1; idyy < 0xFF; idyy++) {
trate = (baseclk * idxx) / idyy;
if (abs(trate - i2srate) < diff) {
diff = abs(trate - i2srate);
- savedbitclkrate = trate;
*clkx = idxx;
*clky = idyy;
}
@@ -190,8 +188,7 @@ static int lpc3xxx_i2s_hw_params(struct snd_pcm_substream *substream,
__lpc3xxx_find_clkdiv(&clkx, &clky, i2s_info_p->freq, xfersize, i2s_info_p->clkrate);
- dev_dbg(dev, "Stream : %s\n",
- substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "playback" : "capture");
+ dev_dbg(dev, "Stream : %s\n", snd_pcm_direction_name(substream->stream));
dev_dbg(dev, "Desired clock rate : %d\n", i2s_info_p->freq);
dev_dbg(dev, "Base clock rate : %d\n", i2s_info_p->clkrate);
dev_dbg(dev, "Transfer size (bytes) : %d\n", xfersize);
@@ -260,7 +257,7 @@ static int lpc3xxx_i2s_dai_probe(struct snd_soc_dai *dai)
return 0;
}
-const struct snd_soc_dai_ops lpc3xxx_i2s_dai_ops = {
+static const struct snd_soc_dai_ops lpc3xxx_i2s_dai_ops = {
.probe = lpc3xxx_i2s_dai_probe,
.startup = lpc3xxx_i2s_startup,
.shutdown = lpc3xxx_i2s_shutdown,
@@ -270,7 +267,7 @@ const struct snd_soc_dai_ops lpc3xxx_i2s_dai_ops = {
.set_fmt = lpc3xxx_i2s_set_dai_fmt,
};
-struct snd_soc_dai_driver lpc3xxx_i2s_dai_driver = {
+static struct snd_soc_dai_driver lpc3xxx_i2s_dai_driver = {
.playback = {
.channels_min = 1,
.channels_max = 2,
diff --git a/sound/soc/fsl/lpc3xxx-pcm.c b/sound/soc/fsl/lpc3xxx-pcm.c
index c0d499b9b8ba..e6abaf63895a 100644
--- a/sound/soc/fsl/lpc3xxx-pcm.c
+++ b/sound/soc/fsl/lpc3xxx-pcm.c
@@ -52,7 +52,7 @@ static const struct snd_dmaengine_pcm_config lpc3xxx_dmaengine_pcm_config = {
.prealloc_buffer_size = 128 * 1024,
};
-const struct snd_soc_component_driver lpc3xxx_soc_platform_driver = {
+static const struct snd_soc_component_driver lpc3xxx_soc_platform_driver = {
.name = "lpc32xx-pcm",
};
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index af8b9d098d2d..931b430fa983 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -184,7 +184,7 @@ static int psc_i2s_of_probe(struct platform_device *op)
/* Check for the codec handle. If it is not present then we
* are done */
- if (!of_get_property(op->dev.of_node, "codec-handle", NULL))
+ if (!of_property_present(op->dev.of_node, "codec-handle"))
return 0;
/* Due to errata in the dma mode; need to line up enabling
diff --git a/sound/soc/generic/test-component.c b/sound/soc/generic/test-component.c
index e9e5e235a8a6..df2487b700cc 100644
--- a/sound/soc/generic/test-component.c
+++ b/sound/soc/generic/test-component.c
@@ -181,14 +181,6 @@ static int test_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct
return 0;
}
-static int test_dai_bespoke_trigger(struct snd_pcm_substream *substream,
- int cmd, struct snd_soc_dai *dai)
-{
- mile_stone(dai);
-
- return 0;
-}
-
static const u64 test_dai_formats =
/*
* Select below from Sound Card, not auto
@@ -228,7 +220,6 @@ static const struct snd_soc_dai_ops test_verbose_ops = {
.hw_params = test_dai_hw_params,
.hw_free = test_dai_hw_free,
.trigger = test_dai_trigger,
- .bespoke_trigger = test_dai_bespoke_trigger,
.auto_selectable_formats = &test_dai_formats,
.num_auto_selectable_formats = 1,
};
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index f1faa5dd2a4f..3d59d6982763 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -656,6 +656,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
depends on MFD_INTEL_LPSS || COMPILE_TEST
depends on SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES || COMPILE_TEST
depends on SOUNDWIRE
+ select SND_SOC_SDW_UTILS
select SND_SOC_MAX98363
select SND_SOC_MAX98373_I2C
select SND_SOC_MAX98373_SDW
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index dc6fe110f279..5bd8dc2d166a 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -35,15 +35,6 @@ snd-soc-skl_nau88l25_ssm4567-y := skl_nau88l25_ssm4567.o
snd-soc-ehl-rt5660-y := ehl_rt5660.o
snd-soc-sof-ssp-amp-y := sof_ssp_amp.o
snd-soc-sof-sdw-y += sof_sdw.o \
- sof_sdw_maxim.o sof_sdw_rt_amp.o \
- bridge_cs35l56.o \
- sof_sdw_rt5682.o sof_sdw_rt700.o \
- sof_sdw_rt711.o sof_sdw_rt_sdca_jack_common.o \
- sof_sdw_rt712_sdca.o sof_sdw_rt722_sdca.o \
- sof_sdw_rt_dmic.o \
- sof_sdw_cs42l42.o sof_sdw_cs42l43.o \
- sof_sdw_cs_amp.o \
- sof_sdw_dmic.o \
sof_sdw_hdmi.o
obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o
obj-$(CONFIG_SND_SOC_INTEL_SOF_CS42L42_MACH) += snd-soc-sof_cs42l42.o
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index e5feaef669d1..d258728d64cf 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
-#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "sof_sdw_common.h"
#include "../../codecs/rt711.h"
@@ -23,24 +22,24 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override");
static void log_quirks(struct device *dev)
{
- if (SOF_JACK_JDSRC(sof_sdw_quirk))
+ if (SOC_SDW_JACK_JDSRC(sof_sdw_quirk))
dev_dbg(dev, "quirk realtek,jack-detect-source %ld\n",
- SOF_JACK_JDSRC(sof_sdw_quirk));
- if (sof_sdw_quirk & SOF_SDW_FOUR_SPK)
- dev_err(dev, "quirk SOF_SDW_FOUR_SPK enabled but no longer supported\n");
+ SOC_SDW_JACK_JDSRC(sof_sdw_quirk));
+ if (sof_sdw_quirk & SOC_SDW_FOUR_SPK)
+ dev_err(dev, "quirk SOC_SDW_FOUR_SPK enabled but no longer supported\n");
if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
dev_dbg(dev, "quirk SOF_SDW_TGL_HDMI enabled\n");
- if (sof_sdw_quirk & SOF_SDW_PCH_DMIC)
- dev_dbg(dev, "quirk SOF_SDW_PCH_DMIC enabled\n");
+ if (sof_sdw_quirk & SOC_SDW_PCH_DMIC)
+ dev_dbg(dev, "quirk SOC_SDW_PCH_DMIC enabled\n");
if (SOF_SSP_GET_PORT(sof_sdw_quirk))
dev_dbg(dev, "SSP port %ld\n",
SOF_SSP_GET_PORT(sof_sdw_quirk));
- if (sof_sdw_quirk & SOF_SDW_NO_AGGREGATION)
- dev_err(dev, "quirk SOF_SDW_NO_AGGREGATION enabled but no longer supported\n");
- if (sof_sdw_quirk & SOF_CODEC_SPKR)
- dev_dbg(dev, "quirk SOF_CODEC_SPKR enabled\n");
- if (sof_sdw_quirk & SOF_SIDECAR_AMPS)
- dev_dbg(dev, "quirk SOF_SIDECAR_AMPS enabled\n");
+ if (sof_sdw_quirk & SOC_SDW_NO_AGGREGATION)
+ dev_err(dev, "quirk SOC_SDW_NO_AGGREGATION enabled but no longer supported\n");
+ if (sof_sdw_quirk & SOC_SDW_CODEC_SPKR)
+ dev_dbg(dev, "quirk SOC_SDW_CODEC_SPKR enabled\n");
+ if (sof_sdw_quirk & SOC_SDW_SIDECAR_AMPS)
+ dev_dbg(dev, "quirk SOC_SDW_SIDECAR_AMPS enabled\n");
}
static int sof_sdw_quirk_cb(const struct dmi_system_id *id)
@@ -57,7 +56,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"),
},
- .driver_data = (void *)SOF_SDW_PCH_DMIC,
+ .driver_data = (void *)SOC_SDW_PCH_DMIC,
},
{
.callback = sof_sdw_quirk_cb,
@@ -99,7 +98,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"),
},
- .driver_data = (void *)SOF_SDW_PCH_DMIC,
+ .driver_data = (void *)SOC_SDW_PCH_DMIC,
},
/* TigerLake devices */
{
@@ -111,7 +110,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
RT711_JD1 |
- SOF_SDW_PCH_DMIC |
+ SOC_SDW_PCH_DMIC |
SOF_SSP_PORT(SOF_I2S_SSP2)),
},
{
@@ -159,7 +158,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Volteer"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_SDW_PCH_DMIC |
+ SOC_SDW_PCH_DMIC |
SOF_BT_OFFLOAD_SSP(2) |
SOF_SSP_BT_OFFLOAD_PRESENT),
},
@@ -170,7 +169,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Ripto"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_SDW_PCH_DMIC),
+ SOC_SDW_PCH_DMIC),
},
{
/*
@@ -185,7 +184,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Conv"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_SDW_PCH_DMIC |
+ SOC_SDW_PCH_DMIC |
RT711_JD1),
},
{
@@ -199,7 +198,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "8709"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_SDW_PCH_DMIC |
+ SOC_SDW_PCH_DMIC |
RT711_JD1),
},
{
@@ -210,7 +209,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "LAPBC"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_SDW_PCH_DMIC |
+ SOC_SDW_PCH_DMIC |
RT711_JD1),
},
{
@@ -221,7 +220,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_SDW_PCH_DMIC |
+ SOC_SDW_PCH_DMIC |
RT711_JD1),
},
{
@@ -232,7 +231,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "LAPRC"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_SDW_PCH_DMIC |
+ SOC_SDW_PCH_DMIC |
RT711_JD2_100K),
},
{
@@ -243,7 +242,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "LAPRC710"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_SDW_PCH_DMIC |
+ SOC_SDW_PCH_DMIC |
RT711_JD2_100K),
},
/* TigerLake-SDCA devices */
@@ -293,7 +292,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Brya"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- SOF_SDW_PCH_DMIC |
+ SOC_SDW_PCH_DMIC |
SOF_BT_OFFLOAD_SSP(2) |
SOF_SSP_BT_OFFLOAD_PRESENT),
},
@@ -501,7 +500,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
DMI_MATCH(DMI_PRODUCT_NAME, "Rex"),
},
- .driver_data = (void *)(SOF_SDW_PCH_DMIC |
+ .driver_data = (void *)(SOC_SDW_PCH_DMIC |
SOF_BT_OFFLOAD_SSP(1) |
SOF_SSP_BT_OFFLOAD_PRESENT),
},
@@ -529,7 +528,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CE3")
},
- .driver_data = (void *)(SOF_SIDECAR_AMPS),
+ .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS),
},
{
.callback = sof_sdw_quirk_cb,
@@ -537,7 +536,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CE4")
},
- .driver_data = (void *)(SOF_SIDECAR_AMPS),
+ .driver_data = (void *)(SOC_SDW_SIDECAR_AMPS),
},
{}
};
@@ -549,900 +548,15 @@ static struct snd_soc_dai_link_component platform_component[] = {
}
};
-static const struct snd_soc_dapm_widget generic_dmic_widgets[] = {
- SND_SOC_DAPM_MIC("DMIC", NULL),
-};
-
-static const struct snd_soc_dapm_widget generic_jack_widgets[] = {
- SND_SOC_DAPM_HP("Headphone", NULL),
- SND_SOC_DAPM_MIC("Headset Mic", NULL),
-};
-
-static const struct snd_kcontrol_new generic_jack_controls[] = {
- SOC_DAPM_PIN_SWITCH("Headphone"),
- SOC_DAPM_PIN_SWITCH("Headset Mic"),
-};
-
-static const struct snd_soc_dapm_widget generic_spk_widgets[] = {
- SND_SOC_DAPM_SPK("Speaker", NULL),
-};
-
-static const struct snd_kcontrol_new generic_spk_controls[] = {
- SOC_DAPM_PIN_SWITCH("Speaker"),
-};
-
-static const struct snd_soc_dapm_widget maxim_widgets[] = {
- SND_SOC_DAPM_SPK("Left Spk", NULL),
- SND_SOC_DAPM_SPK("Right Spk", NULL),
-};
-
-static const struct snd_kcontrol_new maxim_controls[] = {
- SOC_DAPM_PIN_SWITCH("Left Spk"),
- SOC_DAPM_PIN_SWITCH("Right Spk"),
-};
-
-static const struct snd_soc_dapm_widget rt700_widgets[] = {
- SND_SOC_DAPM_HP("Headphones", NULL),
- SND_SOC_DAPM_MIC("AMIC", NULL),
- SND_SOC_DAPM_SPK("Speaker", NULL),
-};
-
-static const struct snd_kcontrol_new rt700_controls[] = {
- SOC_DAPM_PIN_SWITCH("Headphones"),
- SOC_DAPM_PIN_SWITCH("AMIC"),
- SOC_DAPM_PIN_SWITCH("Speaker"),
-};
-
-/* these wrappers are only needed to avoid typecast compilation errors */
-int sdw_startup(struct snd_pcm_substream *substream)
-{
- return sdw_startup_stream(substream);
-}
-
-int sdw_prepare(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct sdw_stream_runtime *sdw_stream;
- struct snd_soc_dai *dai;
-
- /* Find stream from first CPU DAI */
- dai = snd_soc_rtd_to_cpu(rtd, 0);
-
- sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
- if (IS_ERR(sdw_stream)) {
- dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
- return PTR_ERR(sdw_stream);
- }
-
- return sdw_prepare_stream(sdw_stream);
-}
-
-int sdw_trigger(struct snd_pcm_substream *substream, int cmd)
-{
- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct sdw_stream_runtime *sdw_stream;
- struct snd_soc_dai *dai;
- int ret;
-
- /* Find stream from first CPU DAI */
- dai = snd_soc_rtd_to_cpu(rtd, 0);
-
- sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
- if (IS_ERR(sdw_stream)) {
- dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
- return PTR_ERR(sdw_stream);
- }
-
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- case SNDRV_PCM_TRIGGER_RESUME:
- ret = sdw_enable_stream(sdw_stream);
- break;
-
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_STOP:
- ret = sdw_disable_stream(sdw_stream);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- if (ret)
- dev_err(rtd->dev, "%s trigger %d failed: %d\n", __func__, cmd, ret);
-
- return ret;
-}
-
-int sdw_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
-{
- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct snd_soc_dai_link_ch_map *ch_maps;
- int ch = params_channels(params);
- unsigned int ch_mask;
- int num_codecs;
- int step;
- int i;
-
- if (!rtd->dai_link->ch_maps)
- return 0;
-
- /* Identical data will be sent to all codecs in playback */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- ch_mask = GENMASK(ch - 1, 0);
- step = 0;
- } else {
- num_codecs = rtd->dai_link->num_codecs;
-
- if (ch < num_codecs || ch % num_codecs != 0) {
- dev_err(rtd->dev, "Channels number %d is invalid when codec number = %d\n",
- ch, num_codecs);
- return -EINVAL;
- }
-
- ch_mask = GENMASK(ch / num_codecs - 1, 0);
- step = hweight_long(ch_mask);
-
- }
-
- /*
- * The captured data will be combined from each cpu DAI if the dai
- * link has more than one codec DAIs. Set codec channel mask and
- * ASoC will set the corresponding channel numbers for each cpu dai.
- */
- for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
- ch_maps->ch_mask = ch_mask << (i * step);
-
- return 0;
-}
-
-int sdw_hw_free(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct sdw_stream_runtime *sdw_stream;
- struct snd_soc_dai *dai;
-
- /* Find stream from first CPU DAI */
- dai = snd_soc_rtd_to_cpu(rtd, 0);
-
- sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
- if (IS_ERR(sdw_stream)) {
- dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
- return PTR_ERR(sdw_stream);
- }
-
- return sdw_deprepare_stream(sdw_stream);
-}
-
-void sdw_shutdown(struct snd_pcm_substream *substream)
-{
- sdw_shutdown_stream(substream);
-}
-
static const struct snd_soc_ops sdw_ops = {
- .startup = sdw_startup,
- .prepare = sdw_prepare,
- .trigger = sdw_trigger,
- .hw_params = sdw_hw_params,
- .hw_free = sdw_hw_free,
- .shutdown = sdw_shutdown,
-};
-
-static struct sof_sdw_codec_info codec_info_list[] = {
- {
- .part_id = 0x700,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt700-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_JACK,
- .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
- .rtd_init = rt700_rtd_init,
- .controls = rt700_controls,
- .num_controls = ARRAY_SIZE(rt700_controls),
- .widgets = rt700_widgets,
- .num_widgets = ARRAY_SIZE(rt700_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x711,
- .version_id = 3,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt711-sdca-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_JACK,
- .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
- .init = sof_sdw_rt_sdca_jack_init,
- .exit = sof_sdw_rt_sdca_jack_exit,
- .rtd_init = rt_sdca_jack_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x711,
- .version_id = 2,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt711-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_JACK,
- .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
- .init = sof_sdw_rt711_init,
- .exit = sof_sdw_rt711_exit,
- .rtd_init = rt711_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x712,
- .version_id = 3,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt712-sdca-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_JACK,
- .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
- .init = sof_sdw_rt_sdca_jack_init,
- .exit = sof_sdw_rt_sdca_jack_exit,
- .rtd_init = rt_sdca_jack_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- {
- .direction = {true, false},
- .dai_name = "rt712-sdca-aif2",
- .dai_type = SOF_SDW_DAI_TYPE_AMP,
- .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
- .init = sof_sdw_rt_amp_init,
- .exit = sof_sdw_rt_amp_exit,
- .rtd_init = rt712_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- },
- },
- .dai_num = 2,
- },
- {
- .part_id = 0x1712,
- .version_id = 3,
- .dais = {
- {
- .direction = {false, true},
- .dai_name = "rt712-sdca-dmic-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_MIC,
- .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
- .rtd_init = rt_dmic_rtd_init,
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x713,
- .version_id = 3,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt712-sdca-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_JACK,
- .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
- .init = sof_sdw_rt_sdca_jack_init,
- .exit = sof_sdw_rt_sdca_jack_exit,
- .rtd_init = rt_sdca_jack_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x1713,
- .version_id = 3,
- .dais = {
- {
- .direction = {false, true},
- .dai_name = "rt712-sdca-dmic-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_MIC,
- .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
- .rtd_init = rt_dmic_rtd_init,
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x1308,
- .acpi_id = "10EC1308",
- .dais = {
- {
- .direction = {true, false},
- .dai_name = "rt1308-aif",
- .dai_type = SOF_SDW_DAI_TYPE_AMP,
- .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
- .init = sof_sdw_rt_amp_init,
- .exit = sof_sdw_rt_amp_exit,
- .rtd_init = rt_amp_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- },
- },
- .dai_num = 1,
- .ops = &sof_sdw_rt1308_i2s_ops,
- },
- {
- .part_id = 0x1316,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt1316-aif",
- .dai_type = SOF_SDW_DAI_TYPE_AMP,
- .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
- .init = sof_sdw_rt_amp_init,
- .exit = sof_sdw_rt_amp_exit,
- .rtd_init = rt_amp_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x1318,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt1318-aif",
- .dai_type = SOF_SDW_DAI_TYPE_AMP,
- .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
- .init = sof_sdw_rt_amp_init,
- .exit = sof_sdw_rt_amp_exit,
- .rtd_init = rt_amp_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x714,
- .version_id = 3,
- .ignore_pch_dmic = true,
- .dais = {
- {
- .direction = {false, true},
- .dai_name = "rt715-sdca-aif2",
- .dai_type = SOF_SDW_DAI_TYPE_MIC,
- .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
- .rtd_init = rt_dmic_rtd_init,
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x715,
- .version_id = 3,
- .ignore_pch_dmic = true,
- .dais = {
- {
- .direction = {false, true},
- .dai_name = "rt715-sdca-aif2",
- .dai_type = SOF_SDW_DAI_TYPE_MIC,
- .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
- .rtd_init = rt_dmic_rtd_init,
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x714,
- .version_id = 2,
- .ignore_pch_dmic = true,
- .dais = {
- {
- .direction = {false, true},
- .dai_name = "rt715-aif2",
- .dai_type = SOF_SDW_DAI_TYPE_MIC,
- .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
- .rtd_init = rt_dmic_rtd_init,
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x715,
- .version_id = 2,
- .ignore_pch_dmic = true,
- .dais = {
- {
- .direction = {false, true},
- .dai_name = "rt715-aif2",
- .dai_type = SOF_SDW_DAI_TYPE_MIC,
- .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
- .rtd_init = rt_dmic_rtd_init,
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x722,
- .version_id = 3,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt722-sdca-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_JACK,
- .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
- .init = sof_sdw_rt_sdca_jack_init,
- .exit = sof_sdw_rt_sdca_jack_exit,
- .rtd_init = rt_sdca_jack_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- {
- .direction = {true, false},
- .dai_name = "rt722-sdca-aif2",
- .dai_type = SOF_SDW_DAI_TYPE_AMP,
- /* No feedback capability is provided by rt722-sdca codec driver*/
- .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
- .init = sof_sdw_rt_amp_init,
- .exit = sof_sdw_rt_amp_exit,
- .rtd_init = rt722_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- },
- {
- .direction = {false, true},
- .dai_name = "rt722-sdca-aif3",
- .dai_type = SOF_SDW_DAI_TYPE_MIC,
- .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
- .rtd_init = rt_dmic_rtd_init,
- },
- },
- .dai_num = 3,
- },
- {
- .part_id = 0x8373,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "max98373-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_AMP,
- .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
- .init = sof_sdw_maxim_init,
- .rtd_init = maxim_spk_rtd_init,
- .controls = maxim_controls,
- .num_controls = ARRAY_SIZE(maxim_controls),
- .widgets = maxim_widgets,
- .num_widgets = ARRAY_SIZE(maxim_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x8363,
- .dais = {
- {
- .direction = {true, false},
- .dai_name = "max98363-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_AMP,
- .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
- .init = sof_sdw_maxim_init,
- .rtd_init = maxim_spk_rtd_init,
- .controls = maxim_controls,
- .num_controls = ARRAY_SIZE(maxim_controls),
- .widgets = maxim_widgets,
- .num_widgets = ARRAY_SIZE(maxim_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x5682,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "rt5682-sdw",
- .dai_type = SOF_SDW_DAI_TYPE_JACK,
- .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
- .rtd_init = rt5682_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x3556,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "cs35l56-sdw1",
- .dai_type = SOF_SDW_DAI_TYPE_AMP,
- .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
- .init = sof_sdw_cs_amp_init,
- .rtd_init = cs_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x4242,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "cs42l42-sdw",
- .dai_type = SOF_SDW_DAI_TYPE_JACK,
- .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
- .rtd_init = cs42l42_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x4243,
- .codec_name = "cs42l43-codec",
- .count_sidecar = bridge_cs35l56_count_sidecar,
- .add_sidecar = bridge_cs35l56_add_sidecar,
- .dais = {
- {
- .direction = {true, false},
- .dai_name = "cs42l43-dp5",
- .dai_type = SOF_SDW_DAI_TYPE_JACK,
- .dailink = {SDW_JACK_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
- .rtd_init = cs42l43_hs_rtd_init,
- .controls = generic_jack_controls,
- .num_controls = ARRAY_SIZE(generic_jack_controls),
- .widgets = generic_jack_widgets,
- .num_widgets = ARRAY_SIZE(generic_jack_widgets),
- },
- {
- .direction = {false, true},
- .dai_name = "cs42l43-dp1",
- .dai_type = SOF_SDW_DAI_TYPE_MIC,
- .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
- .rtd_init = cs42l43_dmic_rtd_init,
- .widgets = generic_dmic_widgets,
- .num_widgets = ARRAY_SIZE(generic_dmic_widgets),
- },
- {
- .direction = {false, true},
- .dai_name = "cs42l43-dp2",
- .dai_type = SOF_SDW_DAI_TYPE_JACK,
- .dailink = {SDW_UNUSED_DAI_ID, SDW_JACK_IN_DAI_ID},
- },
- {
- .direction = {true, false},
- .dai_name = "cs42l43-dp6",
- .dai_type = SOF_SDW_DAI_TYPE_AMP,
- .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
- .init = sof_sdw_cs42l43_spk_init,
- .rtd_init = cs42l43_spk_rtd_init,
- .controls = generic_spk_controls,
- .num_controls = ARRAY_SIZE(generic_spk_controls),
- .widgets = generic_spk_widgets,
- .num_widgets = ARRAY_SIZE(generic_spk_widgets),
- .quirk = SOF_CODEC_SPKR | SOF_SIDECAR_AMPS,
- },
- },
- .dai_num = 4,
- },
- {
- .part_id = 0xaaaa, /* generic codec mockup */
- .version_id = 0,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "sdw-mockup-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_JACK,
- .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0xaa55, /* headset codec mockup */
- .version_id = 0,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "sdw-mockup-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_JACK,
- .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID},
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x55aa, /* amplifier mockup */
- .version_id = 0,
- .dais = {
- {
- .direction = {true, true},
- .dai_name = "sdw-mockup-aif1",
- .dai_type = SOF_SDW_DAI_TYPE_AMP,
- .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID},
- },
- },
- .dai_num = 1,
- },
- {
- .part_id = 0x5555,
- .version_id = 0,
- .dais = {
- {
- .dai_name = "sdw-mockup-aif1",
- .direction = {false, true},
- .dai_type = SOF_SDW_DAI_TYPE_MIC,
- .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
- },
- },
- .dai_num = 1,
- },
+ .startup = asoc_sdw_startup,
+ .prepare = asoc_sdw_prepare,
+ .trigger = asoc_sdw_trigger,
+ .hw_params = asoc_sdw_hw_params,
+ .hw_free = asoc_sdw_hw_free,
+ .shutdown = asoc_sdw_shutdown,
};
-static struct sof_sdw_codec_info *find_codec_info_part(const u64 adr)
-{
- unsigned int part_id, sdw_version;
- int i;
-
- part_id = SDW_PART_ID(adr);
- sdw_version = SDW_VERSION(adr);
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
- /*
- * A codec info is for all sdw version with the part id if
- * version_id is not specified in the codec info.
- */
- if (part_id == codec_info_list[i].part_id &&
- (!codec_info_list[i].version_id ||
- sdw_version == codec_info_list[i].version_id))
- return &codec_info_list[i];
-
- return NULL;
-
-}
-
-static struct sof_sdw_codec_info *find_codec_info_acpi(const u8 *acpi_id)
-{
- int i;
-
- if (!acpi_id[0])
- return NULL;
-
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
- if (!memcmp(codec_info_list[i].acpi_id, acpi_id, ACPI_ID_LEN))
- return &codec_info_list[i];
-
- return NULL;
-}
-
-static struct sof_sdw_codec_info *find_codec_info_dai(const char *dai_name,
- int *dai_index)
-{
- int i, j;
-
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
- for (j = 0; j < codec_info_list[i].dai_num; j++) {
- if (!strcmp(codec_info_list[i].dais[j].dai_name, dai_name)) {
- *dai_index = j;
- return &codec_info_list[i];
- }
- }
- }
-
- return NULL;
-}
-
-static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
- int *be_id, char *name, int playback, int capture,
- struct snd_soc_dai_link_component *cpus, int cpus_num,
- struct snd_soc_dai_link_component *codecs, int codecs_num,
- int (*init)(struct snd_soc_pcm_runtime *rtd),
- const struct snd_soc_ops *ops)
-{
- dev_dbg(dev, "create dai link %s, id %d\n", name, *be_id);
- dai_links->id = (*be_id)++;
- dai_links->name = name;
- dai_links->platforms = platform_component;
- dai_links->num_platforms = ARRAY_SIZE(platform_component);
- dai_links->no_pcm = 1;
- dai_links->cpus = cpus;
- dai_links->num_cpus = cpus_num;
- dai_links->codecs = codecs;
- dai_links->num_codecs = codecs_num;
- dai_links->dpcm_playback = playback;
- dai_links->dpcm_capture = capture;
- dai_links->init = init;
- dai_links->ops = ops;
-}
-
-static int init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
- int *be_id, char *name, int playback, int capture,
- const char *cpu_dai_name,
- const char *codec_name, const char *codec_dai_name,
- int (*init)(struct snd_soc_pcm_runtime *rtd),
- const struct snd_soc_ops *ops)
-{
- struct snd_soc_dai_link_component *dlc;
-
- /* Allocate two DLCs one for the CPU, one for the CODEC */
- dlc = devm_kcalloc(dev, 2, sizeof(*dlc), GFP_KERNEL);
- if (!dlc || !name || !cpu_dai_name || !codec_name || !codec_dai_name)
- return -ENOMEM;
-
- dlc[0].dai_name = cpu_dai_name;
-
- dlc[1].name = codec_name;
- dlc[1].dai_name = codec_dai_name;
-
- init_dai_link(dev, dai_links, be_id, name, playback, capture,
- &dlc[0], 1, &dlc[1], 1, init, ops);
-
- return 0;
-}
-
-static bool is_unique_device(const struct snd_soc_acpi_link_adr *adr_link,
- unsigned int sdw_version,
- unsigned int mfg_id,
- unsigned int part_id,
- unsigned int class_id,
- int index_in_link)
-{
- int i;
-
- for (i = 0; i < adr_link->num_adr; i++) {
- unsigned int sdw1_version, mfg1_id, part1_id, class1_id;
- u64 adr;
-
- /* skip itself */
- if (i == index_in_link)
- continue;
-
- adr = adr_link->adr_d[i].adr;
-
- sdw1_version = SDW_VERSION(adr);
- mfg1_id = SDW_MFG_ID(adr);
- part1_id = SDW_PART_ID(adr);
- class1_id = SDW_CLASS_ID(adr);
-
- if (sdw_version == sdw1_version &&
- mfg_id == mfg1_id &&
- part_id == part1_id &&
- class_id == class1_id)
- return false;
- }
-
- return true;
-}
-
-static const char *get_codec_name(struct device *dev,
- const struct sof_sdw_codec_info *codec_info,
- const struct snd_soc_acpi_link_adr *adr_link,
- int adr_index)
-{
- u64 adr = adr_link->adr_d[adr_index].adr;
- unsigned int sdw_version = SDW_VERSION(adr);
- unsigned int link_id = SDW_DISCO_LINK_ID(adr);
- unsigned int unique_id = SDW_UNIQUE_ID(adr);
- unsigned int mfg_id = SDW_MFG_ID(adr);
- unsigned int part_id = SDW_PART_ID(adr);
- unsigned int class_id = SDW_CLASS_ID(adr);
-
- if (codec_info->codec_name)
- return devm_kstrdup(dev, codec_info->codec_name, GFP_KERNEL);
- else if (is_unique_device(adr_link, sdw_version, mfg_id, part_id,
- class_id, adr_index))
- return devm_kasprintf(dev, GFP_KERNEL, "sdw:0:%01x:%04x:%04x:%02x",
- link_id, mfg_id, part_id, class_id);
- else
- return devm_kasprintf(dev, GFP_KERNEL, "sdw:0:%01x:%04x:%04x:%02x:%01x",
- link_id, mfg_id, part_id, class_id, unique_id);
-
- return NULL;
-}
-
-static int sof_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_card *card = rtd->card;
- struct sof_sdw_codec_info *codec_info;
- struct snd_soc_dai *dai;
- int dai_index;
- int ret;
- int i;
-
- for_each_rtd_codec_dais(rtd, i, dai) {
- codec_info = find_codec_info_dai(dai->name, &dai_index);
- if (!codec_info)
- return -EINVAL;
-
- /*
- * A codec dai can be connected to different dai links for capture and playback,
- * but we only need to call the rtd_init function once.
- * The rtd_init for each codec dai is independent. So, the order of rtd_init
- * doesn't matter.
- */
- if (codec_info->dais[dai_index].rtd_init_done)
- continue;
-
- /*
- * Add card controls and dapm widgets for the first codec dai.
- * The controls and widgets will be used for all codec dais.
- */
-
- if (i > 0)
- goto skip_add_controls_widgets;
-
- if (codec_info->dais[dai_index].controls) {
- ret = snd_soc_add_card_controls(card, codec_info->dais[dai_index].controls,
- codec_info->dais[dai_index].num_controls);
- if (ret) {
- dev_err(card->dev, "%#x controls addition failed: %d\n",
- codec_info->part_id, ret);
- return ret;
- }
- }
- if (codec_info->dais[dai_index].widgets) {
- ret = snd_soc_dapm_new_controls(&card->dapm,
- codec_info->dais[dai_index].widgets,
- codec_info->dais[dai_index].num_widgets);
- if (ret) {
- dev_err(card->dev, "%#x widgets addition failed: %d\n",
- codec_info->part_id, ret);
- return ret;
- }
- }
-
-skip_add_controls_widgets:
- if (codec_info->dais[dai_index].rtd_init) {
- ret = codec_info->dais[dai_index].rtd_init(rtd, dai);
- if (ret)
- return ret;
- }
- codec_info->dais[dai_index].rtd_init_done = true;
- }
-
- return 0;
-}
-
struct sof_sdw_endpoint {
struct list_head list;
@@ -1451,8 +565,8 @@ struct sof_sdw_endpoint {
const char *name_prefix;
bool include_sidecar;
- struct sof_sdw_codec_info *codec_info;
- const struct sof_sdw_dai_info *dai_info;
+ struct asoc_sdw_codec_info *codec_info;
+ const struct asoc_sdw_dai_info *dai_info;
};
struct sof_sdw_dailink {
@@ -1509,7 +623,7 @@ static int parse_sdw_endpoints(struct snd_soc_card *card,
int *num_devs)
{
struct device *dev = card->dev;
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
const struct snd_soc_acpi_link_adr *adr_link;
@@ -1529,7 +643,7 @@ static int parse_sdw_endpoints(struct snd_soc_card *card,
for (i = 0; i < adr_link->num_adr; i++) {
const struct snd_soc_acpi_adr_device *adr_dev = &adr_link->adr_d[i];
- struct sof_sdw_codec_info *codec_info;
+ struct asoc_sdw_codec_info *codec_info;
const char *codec_name;
if (!adr_dev->name_prefix) {
@@ -1538,13 +652,13 @@ static int parse_sdw_endpoints(struct snd_soc_card *card,
return -EINVAL;
}
- codec_info = find_codec_info_part(adr_dev->adr);
+ codec_info = asoc_sdw_find_codec_info_part(adr_dev->adr);
if (!codec_info)
return -EINVAL;
- ctx->ignore_pch_dmic |= codec_info->ignore_pch_dmic;
+ ctx->ignore_internal_dmic |= codec_info->ignore_internal_dmic;
- codec_name = get_codec_name(dev, codec_info, adr_link, i);
+ codec_name = asoc_sdw_get_codec_name(dev, codec_info, adr_link, i);
if (!codec_name)
return -ENOMEM;
@@ -1563,7 +677,7 @@ static int parse_sdw_endpoints(struct snd_soc_card *card,
for (j = 0; j < adr_dev->num_endpoints; j++) {
const struct snd_soc_acpi_endpoint *adr_end;
- const struct sof_sdw_dai_info *dai_info;
+ const struct asoc_sdw_dai_info *dai_info;
struct sof_sdw_dailink *sof_dai;
int stream;
@@ -1630,7 +744,8 @@ static int create_sdw_dailink(struct snd_soc_card *card,
int *be_id, struct snd_soc_codec_conf **codec_conf)
{
struct device *dev = card->dev;
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private;
struct sof_sdw_endpoint *sof_end;
int stream;
int ret;
@@ -1709,7 +824,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
if (cur_link != sof_end->link_mask) {
int link_num = ffs(sof_end->link_mask) - 1;
- int pin_num = ctx->sdw_pin_index[link_num]++;
+ int pin_num = intel_ctx->sdw_pin_index[link_num]++;
cur_link = sof_end->link_mask;
@@ -1734,9 +849,10 @@ static int create_sdw_dailink(struct snd_soc_card *card,
playback = (stream == SNDRV_PCM_STREAM_PLAYBACK);
capture = (stream == SNDRV_PCM_STREAM_CAPTURE);
- init_dai_link(dev, *dai_links, be_id, name, playback, capture,
- cpus, num_cpus, codecs, num_codecs,
- sof_sdw_rtd_init, &sdw_ops);
+ asoc_sdw_init_dai_link(dev, *dai_links, be_id, name, playback, capture,
+ cpus, num_cpus, platform_component,
+ ARRAY_SIZE(platform_component), codecs, num_codecs,
+ asoc_sdw_rtd_init, &sdw_ops);
/*
* SoundWire DAILINKs use 'stream' functions and Bank Switch operations
@@ -1763,11 +879,12 @@ static int create_sdw_dailinks(struct snd_soc_card *card,
struct sof_sdw_dailink *sof_dais,
struct snd_soc_codec_conf **codec_conf)
{
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private;
int ret, i;
for (i = 0; i < SDW_MAX_LINKS; i++)
- ctx->sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE;
+ intel_ctx->sdw_pin_index[i] = SOC_SDW_INTEL_BIDIR_PDI_BASE;
/* generate DAI links by each sdw link */
while (sof_dais->initialised) {
@@ -1790,7 +907,7 @@ static int create_sdw_dailinks(struct snd_soc_card *card,
static int create_ssp_dailinks(struct snd_soc_card *card,
struct snd_soc_dai_link **dai_links, int *be_id,
- struct sof_sdw_codec_info *ssp_info,
+ struct asoc_sdw_codec_info *ssp_info,
unsigned long ssp_mask)
{
struct device *dev = card->dev;
@@ -1805,10 +922,12 @@ static int create_ssp_dailinks(struct snd_soc_card *card,
int playback = ssp_info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK];
int capture = ssp_info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE];
- ret = init_simple_dai_link(dev, *dai_links, be_id, name,
- playback, capture, cpu_dai_name,
- codec_name, ssp_info->dais[0].dai_name,
- NULL, ssp_info->ops);
+ ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name,
+ playback, capture, cpu_dai_name,
+ platform_component->name,
+ ARRAY_SIZE(platform_component), codec_name,
+ ssp_info->dais[0].dai_name, NULL,
+ ssp_info->ops);
if (ret)
return ret;
@@ -1828,20 +947,24 @@ static int create_dmic_dailinks(struct snd_soc_card *card,
struct device *dev = card->dev;
int ret;
- ret = init_simple_dai_link(dev, *dai_links, be_id, "dmic01",
- 0, 1, // DMIC only supports capture
- "DMIC01 Pin", "dmic-codec", "dmic-hifi",
- sof_sdw_dmic_init, NULL);
+ ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, "dmic01",
+ 0, 1, // DMIC only supports capture
+ "DMIC01 Pin", platform_component->name,
+ ARRAY_SIZE(platform_component),
+ "dmic-codec", "dmic-hifi",
+ asoc_sdw_dmic_init, NULL);
if (ret)
return ret;
(*dai_links)++;
- ret = init_simple_dai_link(dev, *dai_links, be_id, "dmic16k",
- 0, 1, // DMIC only supports capture
- "DMIC16k Pin", "dmic-codec", "dmic-hifi",
- /* don't call sof_sdw_dmic_init() twice */
- NULL, NULL);
+ ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, "dmic16k",
+ 0, 1, // DMIC only supports capture
+ "DMIC16k Pin", platform_component->name,
+ ARRAY_SIZE(platform_component),
+ "dmic-codec", "dmic-hifi",
+ /* don't call asoc_sdw_dmic_init() twice */
+ NULL, NULL);
if (ret)
return ret;
@@ -1855,7 +978,8 @@ static int create_hdmi_dailinks(struct snd_soc_card *card,
int hdmi_num)
{
struct device *dev = card->dev;
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private;
int i, ret;
for (i = 0; i < hdmi_num; i++) {
@@ -1863,7 +987,7 @@ static int create_hdmi_dailinks(struct snd_soc_card *card,
char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", i + 1);
char *codec_name, *codec_dai_name;
- if (ctx->hdmi.idisp_codec) {
+ if (intel_ctx->hdmi.idisp_codec) {
codec_name = "ehdaudio0D2";
codec_dai_name = devm_kasprintf(dev, GFP_KERNEL,
"intel-hdmi-hifi%d", i + 1);
@@ -1872,10 +996,12 @@ static int create_hdmi_dailinks(struct snd_soc_card *card,
codec_dai_name = "snd-soc-dummy-dai";
}
- ret = init_simple_dai_link(dev, *dai_links, be_id, name,
- 1, 0, // HDMI only supports playback
- cpu_dai_name, codec_name, codec_dai_name,
- i == 0 ? sof_sdw_hdmi_init : NULL, NULL);
+ ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name,
+ 1, 0, // HDMI only supports playback
+ cpu_dai_name, platform_component->name,
+ ARRAY_SIZE(platform_component),
+ codec_name, codec_dai_name,
+ i == 0 ? sof_sdw_hdmi_init : NULL, NULL);
if (ret)
return ret;
@@ -1895,9 +1021,11 @@ static int create_bt_dailinks(struct snd_soc_card *card,
char *cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port);
int ret;
- ret = init_simple_dai_link(dev, *dai_links, be_id, name,
- 1, 1, cpu_dai_name, snd_soc_dummy_dlc.name,
- snd_soc_dummy_dlc.dai_name, NULL, NULL);
+ ret = asoc_sdw_init_simple_dai_link(dev, *dai_links, be_id, name,
+ 1, 1, cpu_dai_name, platform_component->name,
+ ARRAY_SIZE(platform_component),
+ snd_soc_dummy_dlc.name, snd_soc_dummy_dlc.dai_name,
+ NULL, NULL);
if (ret)
return ret;
@@ -1911,10 +1039,11 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
struct device *dev = card->dev;
struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, bt_num = 0;
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private;
struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
struct snd_soc_codec_conf *codec_conf;
- struct sof_sdw_codec_info *ssp_info;
+ struct asoc_sdw_codec_info *ssp_info;
struct sof_sdw_endpoint *sof_ends;
struct sof_sdw_dailink *sof_dais;
int num_devs = 0;
@@ -1956,14 +1085,14 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
* system only when I2S mode is supported, not sdw mode.
* Here check ACPI ID to confirm I2S is supported.
*/
- ssp_info = find_codec_info_acpi(mach->id);
+ ssp_info = asoc_sdw_find_codec_info_acpi(mach->id);
if (ssp_info) {
ssp_mask = SOF_SSP_GET_PORT(sof_sdw_quirk);
ssp_num = hweight_long(ssp_mask);
}
if (mach_params->codec_mask & IDISP_CODEC_MASK)
- ctx->hdmi.idisp_codec = true;
+ intel_ctx->hdmi.idisp_codec = true;
if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
hdmi_num = SOF_TGL_HDMI_COUNT;
@@ -1971,7 +1100,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
hdmi_num = SOF_PRE_TGL_HDMI_COUNT;
/* enable dmic01 & dmic16k */
- if (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num)
+ if (sof_sdw_quirk & SOC_SDW_PCH_DMIC || mach_params->dmic_num)
dmic_num = 2;
if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
@@ -1979,7 +1108,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d, bt: %d\n",
sdw_be_num, ssp_num, dmic_num,
- ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num);
+ intel_ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num);
codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL);
if (!codec_conf) {
@@ -2018,7 +1147,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
/* dmic */
if (dmic_num > 0) {
- if (ctx->ignore_pch_dmic) {
+ if (ctx->ignore_internal_dmic) {
dev_warn(dev, "Ignoring PCH DMIC\n");
} else {
ret = create_dmic_dailinks(card, &dai_links, &be_id);
@@ -2052,88 +1181,41 @@ err_dai:
static int sof_sdw_card_late_probe(struct snd_soc_card *card)
{
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private;
int ret = 0;
- int i;
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
- if (codec_info_list[i].codec_card_late_probe) {
- ret = codec_info_list[i].codec_card_late_probe(card);
-
- if (ret < 0)
- return ret;
- }
- }
+ ret = asoc_sdw_card_late_probe(card);
+ if (ret < 0)
+ return ret;
- if (ctx->hdmi.idisp_codec)
+ if (intel_ctx->hdmi.idisp_codec)
ret = sof_sdw_hdmi_card_late_probe(card);
return ret;
}
-/* helper to get the link that the codec DAI is used */
-static struct snd_soc_dai_link *mc_find_codec_dai_used(struct snd_soc_card *card,
- const char *dai_name)
-{
- struct snd_soc_dai_link *dai_link;
- int i;
- int j;
-
- for_each_card_prelinks(card, i, dai_link) {
- for (j = 0; j < dai_link->num_codecs; j++) {
- /* Check each codec in a link */
- if (!strcmp(dai_link->codecs[j].dai_name, dai_name))
- return dai_link;
- }
- }
- return NULL;
-}
-
-static void mc_dailink_exit_loop(struct snd_soc_card *card)
-{
- struct snd_soc_dai_link *dai_link;
- int ret;
- int i, j;
-
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
- for (j = 0; j < codec_info_list[i].dai_num; j++) {
- codec_info_list[i].dais[j].rtd_init_done = false;
- /* Check each dai in codec_info_lis to see if it is used in the link */
- if (!codec_info_list[i].dais[j].exit)
- continue;
- /*
- * We don't need to call .exit function if there is no matched
- * dai link found.
- */
- dai_link = mc_find_codec_dai_used(card,
- codec_info_list[i].dais[j].dai_name);
- if (dai_link) {
- /* Do the .exit function if the codec dai is used in the link */
- ret = codec_info_list[i].dais[j].exit(card, dai_link);
- if (ret)
- dev_warn(card->dev,
- "codec exit failed %d\n",
- ret);
- break;
- }
- }
- }
-}
-
static int mc_probe(struct platform_device *pdev)
{
struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev);
struct snd_soc_card *card;
- struct mc_private *ctx;
+ struct asoc_sdw_mc_private *ctx;
+ struct intel_mc_ctx *intel_ctx;
int amp_num = 0, i;
int ret;
dev_dbg(&pdev->dev, "Entry\n");
+ intel_ctx = devm_kzalloc(&pdev->dev, sizeof(*intel_ctx), GFP_KERNEL);
+ if (!intel_ctx)
+ return -ENOMEM;
+
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
+ ctx->private = intel_ctx;
+ ctx->codec_info_list_count = asoc_sdw_get_codec_info_list_count();
card = &ctx->card;
card->dev = &pdev->dev;
card->name = "soundwire";
@@ -2152,8 +1234,9 @@ static int mc_probe(struct platform_device *pdev)
log_quirks(card->dev);
+ ctx->mc_quirk = sof_sdw_quirk;
/* reset amp_num to ensure amp_num++ starts from 0 in each probe */
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
+ for (i = 0; i < ctx->codec_info_list_count; i++)
codec_info_list[i].amp_num = 0;
if (mach->mach_params.subsystem_id_set) {
@@ -2171,7 +1254,7 @@ static int mc_probe(struct platform_device *pdev)
* amp_num will only be increased for active amp
* codecs on used platform
*/
- for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
+ for (i = 0; i < ctx->codec_info_list_count; i++)
amp_num += codec_info_list[i].amp_num;
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
@@ -2192,7 +1275,7 @@ static int mc_probe(struct platform_device *pdev)
ret = devm_snd_soc_register_card(card->dev, card);
if (ret) {
dev_err_probe(card->dev, ret, "snd_soc_register_card failed %d\n", ret);
- mc_dailink_exit_loop(card);
+ asoc_sdw_mc_dailink_exit_loop(card);
return ret;
}
@@ -2205,7 +1288,7 @@ static void mc_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
- mc_dailink_exit_loop(card);
+ asoc_sdw_mc_dailink_exit_loop(card);
}
static const struct platform_device_id mc_id_table[] = {
@@ -2232,3 +1315,4 @@ MODULE_AUTHOR("Rander Wang <[email protected]>");
MODULE_AUTHOR("Pierre-Louis Bossart <[email protected]>");
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
+MODULE_IMPORT_NS(SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h
index 2a3145d1feb6..02f3eebd019d 100644
--- a/sound/soc/intel/boards/sof_sdw_common.h
+++ b/sound/soc/intel/boards/sof_sdw_common.h
@@ -12,18 +12,12 @@
#include <linux/bits.h>
#include <linux/types.h>
#include <sound/soc.h>
+#include <sound/soc_sdw_utils.h>
#include "sof_hdmi_common.h"
-#define MAX_NO_PROPS 2
#define MAX_HDMI_NUM 4
-#define SDW_UNUSED_DAI_ID -1
-#define SDW_JACK_OUT_DAI_ID 0
-#define SDW_JACK_IN_DAI_ID 1
-#define SDW_AMP_OUT_DAI_ID 2
-#define SDW_AMP_IN_DAI_ID 3
-#define SDW_DMIC_DAI_ID 4
-#define SDW_MAX_CPU_DAIS 16
-#define SDW_INTEL_BIDIR_PDI_BASE 2
+#define SOC_SDW_MAX_CPU_DAIS 16
+#define SOC_SDW_INTEL_BIDIR_PDI_BASE 2
#define SDW_MAX_LINKS 4
@@ -44,27 +38,14 @@ enum {
SOF_I2S_SSP5 = BIT(5),
};
-#define SOF_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0))
/* Deprecated and no longer supported by the code */
-#define SOF_SDW_FOUR_SPK BIT(4)
+#define SOC_SDW_FOUR_SPK BIT(4)
#define SOF_SDW_TGL_HDMI BIT(5)
-#define SOF_SDW_PCH_DMIC BIT(6)
+#define SOC_SDW_PCH_DMIC BIT(6)
#define SOF_SSP_PORT(x) (((x) & GENMASK(5, 0)) << 7)
#define SOF_SSP_GET_PORT(quirk) (((quirk) >> 7) & GENMASK(5, 0))
/* Deprecated and no longer supported by the code */
-#define SOF_SDW_NO_AGGREGATION BIT(14)
-/* If a CODEC has an optional speaker output, this quirk will enable it */
-#define SOF_CODEC_SPKR BIT(15)
-/*
- * If the CODEC has additional devices attached directly to it.
- *
- * For the cs42l43:
- * - 0 - No speaker output
- * - SOF_CODEC_SPKR - CODEC internal speaker
- * - SOF_SIDECAR_AMPS - 2x Sidecar amplifiers + CODEC internal speaker
- * - SOF_CODEC_SPKR | SOF_SIDECAR_AMPS - Not currently supported
- */
-#define SOF_SIDECAR_AMPS BIT(16)
+#define SOC_SDW_NO_AGGREGATION BIT(14)
/* BT audio offload: reserve 3 bits for future */
#define SOF_BT_OFFLOAD_SSP_SHIFT 15
@@ -73,150 +54,17 @@ enum {
(((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK)
#define SOF_SSP_BT_OFFLOAD_PRESENT BIT(18)
-#define SOF_SDW_DAI_TYPE_JACK 0
-#define SOF_SDW_DAI_TYPE_AMP 1
-#define SOF_SDW_DAI_TYPE_MIC 2
-
-#define SOF_SDW_MAX_DAI_NUM 8
-
-struct sof_sdw_codec_info;
-
-struct sof_sdw_dai_info {
- const bool direction[2]; /* playback & capture support */
- const char *dai_name;
- const int dai_type;
- const int dailink[2]; /* dailink id for each direction */
- const struct snd_kcontrol_new *controls;
- const int num_controls;
- const struct snd_soc_dapm_widget *widgets;
- const int num_widgets;
- int (*init)(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback);
- int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
- int (*rtd_init)(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
- bool rtd_init_done; /* Indicate that the rtd_init callback is done */
- unsigned long quirk;
-};
-
-struct sof_sdw_codec_info {
- const int part_id;
- const int version_id;
- const char *codec_name;
- int amp_num;
- const u8 acpi_id[ACPI_ID_LEN];
- const bool ignore_pch_dmic;
- const struct snd_soc_ops *ops;
- struct sof_sdw_dai_info dais[SOF_SDW_MAX_DAI_NUM];
- const int dai_num;
-
- int (*codec_card_late_probe)(struct snd_soc_card *card);
-
- int (*count_sidecar)(struct snd_soc_card *card,
- int *num_dais, int *num_devs);
- int (*add_sidecar)(struct snd_soc_card *card,
- struct snd_soc_dai_link **dai_links,
- struct snd_soc_codec_conf **codec_conf);
-};
-
-struct mc_private {
- struct snd_soc_card card;
- struct snd_soc_jack sdw_headset;
+struct intel_mc_ctx {
struct sof_hdmi_private hdmi;
- struct device *headset_codec_dev; /* only one headset per card */
- struct device *amp_dev1, *amp_dev2;
/* To store SDW Pin index for each SoundWire link */
unsigned int sdw_pin_index[SDW_MAX_LINKS];
- bool append_dai_type;
- bool ignore_pch_dmic;
};
extern unsigned long sof_sdw_quirk;
-int sdw_startup(struct snd_pcm_substream *substream);
-int sdw_prepare(struct snd_pcm_substream *substream);
-int sdw_trigger(struct snd_pcm_substream *substream, int cmd);
-int sdw_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params);
-int sdw_hw_free(struct snd_pcm_substream *substream);
-void sdw_shutdown(struct snd_pcm_substream *substream);
-
/* generic HDMI support */
int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd);
int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card);
-/* DMIC support */
-int sof_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd);
-
-/* RT711 support */
-int sof_sdw_rt711_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback);
-int sof_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
-
-/* RT711-SDCA support */
-int sof_sdw_rt_sdca_jack_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback);
-int sof_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
-
-/* RT1308 I2S support */
-extern const struct snd_soc_ops sof_sdw_rt1308_i2s_ops;
-
-/* generic amp support */
-int sof_sdw_rt_amp_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback);
-int sof_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
-
-/* MAXIM codec support */
-int sof_sdw_maxim_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback);
-
-/* CS42L43 support */
-int sof_sdw_cs42l43_spk_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback);
-
-/* CS AMP support */
-int bridge_cs35l56_count_sidecar(struct snd_soc_card *card,
- int *num_dais, int *num_devs);
-int bridge_cs35l56_add_sidecar(struct snd_soc_card *card,
- struct snd_soc_dai_link **dai_links,
- struct snd_soc_codec_conf **codec_conf);
-int bridge_cs35l56_spk_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback);
-
-int sof_sdw_cs_amp_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback);
-
-/* dai_link init callbacks */
-
-int cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int rt712_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int rt722_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-int rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
-
#endif
diff --git a/sound/soc/intel/boards/sof_sdw_hdmi.c b/sound/soc/intel/boards/sof_sdw_hdmi.c
index f34fabdf9d93..4084119a9a5f 100644
--- a/sound/soc/intel/boards/sof_sdw_hdmi.c
+++ b/sound/soc/intel/boards/sof_sdw_hdmi.c
@@ -17,23 +17,25 @@
int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd)
{
- struct mc_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+ struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private;
struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
- ctx->hdmi.hdmi_comp = dai->component;
+ intel_ctx->hdmi.hdmi_comp = dai->component;
return 0;
}
int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card)
{
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct intel_mc_ctx *intel_ctx = (struct intel_mc_ctx *)ctx->private;
- if (!ctx->hdmi.idisp_codec)
+ if (!intel_ctx->hdmi.idisp_codec)
return 0;
- if (!ctx->hdmi.hdmi_comp)
+ if (!intel_ctx->hdmi.hdmi_comp)
return -EINVAL;
- return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp);
+ return hda_dsp_hdmi_build_controls(card, intel_ctx->hdmi.hdmi_comp);
}
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
index 40a74a19c508..91e146e2487d 100644
--- a/sound/soc/intel/common/Makefile
+++ b/sound/soc/intel/common/Makefile
@@ -12,6 +12,7 @@ snd-soc-acpi-intel-match-y := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-matc
soc-acpi-intel-rpl-match.o soc-acpi-intel-mtl-match.o \
soc-acpi-intel-arl-match.o \
soc-acpi-intel-lnl-match.o \
+ soc-acpi-intel-ptl-match.o \
soc-acpi-intel-hda-match.o \
soc-acpi-intel-sdw-mockup-match.o
diff --git a/sound/soc/intel/common/soc-acpi-intel-ptl-match.c b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c
new file mode 100644
index 000000000000..90f97a44b607
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-ptl-match.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * soc-acpi-intel-ptl-match.c - tables and support for PTL ACPI enumeration.
+ *
+ * Copyright (c) 2024, Intel Corporation.
+ *
+ */
+
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+#include "soc-acpi-intel-sdw-mockup-match.h"
+
+struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_machines[] = {
+ {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ptl_machines);
+
+static const struct snd_soc_acpi_endpoint single_endpoint = {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+};
+
+/*
+ * RT722 is a multi-function codec, three endpoints are created for
+ * its headset, amp and dmic functions.
+ */
+static const struct snd_soc_acpi_endpoint rt722_endpoints[] = {
+ {
+ .num = 0,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ {
+ .num = 1,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+ {
+ .num = 2,
+ .aggregated = 0,
+ .group_position = 0,
+ .group_id = 0,
+ },
+};
+
+static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = {
+ {
+ .adr = 0x000030025D071101ull,
+ .num_endpoints = 1,
+ .endpoints = &single_endpoint,
+ .name_prefix = "rt711"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = {
+ {
+ .adr = 0x000030025d072201ull,
+ .num_endpoints = ARRAY_SIZE(rt722_endpoints),
+ .endpoints = rt722_endpoints,
+ .name_prefix = "rt722"
+ }
+};
+
+static const struct snd_soc_acpi_adr_device rt722_3_single_adr[] = {
+ {
+ .adr = 0x000330025d072201ull,
+ .num_endpoints = ARRAY_SIZE(rt722_endpoints),
+ .endpoints = rt722_endpoints,
+ .name_prefix = "rt722"
+ }
+};
+
+static const struct snd_soc_acpi_link_adr ptl_rt722_only[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt722_0_single_adr),
+ .adr_d = rt722_0_single_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr ptl_rt722_l3[] = {
+ {
+ .mask = BIT(3),
+ .num_adr = ARRAY_SIZE(rt722_3_single_adr),
+ .adr_d = rt722_3_single_adr,
+ },
+ {}
+};
+
+static const struct snd_soc_acpi_link_adr ptl_rvp[] = {
+ {
+ .mask = BIT(0),
+ .num_adr = ARRAY_SIZE(rt711_sdca_0_adr),
+ .adr_d = rt711_sdca_0_adr,
+ },
+ {}
+};
+
+/* this table is used when there is no I2S codec present */
+struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = {
+ /* mockup tests need to be first */
+ {
+ .link_mask = GENMASK(3, 0),
+ .links = sdw_mockup_headset_2amps_mic,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt711-rt1308-rt715.tplg",
+ },
+ {
+ .link_mask = BIT(0) | BIT(1) | BIT(3),
+ .links = sdw_mockup_headset_1amp_mic,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt711-rt1308-mono-rt715.tplg",
+ },
+ {
+ .link_mask = GENMASK(2, 0),
+ .links = sdw_mockup_mic_headset_1amp,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt715-rt711-rt1308-mono.tplg",
+ },
+ {
+ .link_mask = BIT(0),
+ .links = ptl_rvp,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt711.tplg",
+ },
+ {
+ .link_mask = BIT(0),
+ .links = ptl_rt722_only,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt722.tplg",
+ },
+ {
+ .link_mask = BIT(3),
+ .links = ptl_rt722_l3,
+ .drv_name = "sof_sdw",
+ .sof_tplg_filename = "sof-ptl-rt722.tplg",
+ },
+ {},
+};
+EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_ptl_sdw_machines);
diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
index 8b323fb19925..db00704e206d 100644
--- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
+++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
@@ -1108,9 +1108,7 @@ static int mt8192_mt6359_legacy_probe(struct mtk_soc_card_data *soc_card_data)
err_headset_codec:
of_node_put(speaker_codec);
err_speaker_codec:
- if (hdmi_codec)
- of_node_put(hdmi_codec);
-
+ of_node_put(hdmi_codec);
return ret;
}
diff --git a/sound/soc/sdw_utils/Kconfig b/sound/soc/sdw_utils/Kconfig
new file mode 100644
index 000000000000..d915083c3889
--- /dev/null
+++ b/sound/soc/sdw_utils/Kconfig
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config SND_SOC_SDW_UTILS
+ tristate
+ help
+ This option enables to use SoundWire common helper functions and
+ SoundWire codec helper functions in machine driver.
diff --git a/sound/soc/sdw_utils/Makefile b/sound/soc/sdw_utils/Makefile
new file mode 100644
index 000000000000..28229ed96ffb
--- /dev/null
+++ b/sound/soc/sdw_utils/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+snd-soc-sdw-utils-y := soc_sdw_utils.o soc_sdw_dmic.o soc_sdw_rt_dmic.o \
+ soc_sdw_rt700.o soc_sdw_rt711.o \
+ soc_sdw_rt712_sdca.o soc_sdw_rt722_sdca.o \
+ soc_sdw_rt5682.o soc_sdw_rt_sdca_jack_common.o \
+ soc_sdw_rt_amp.o \
+ soc_sdw_bridge_cs35l56.o \
+ soc_sdw_cs42l42.o soc_sdw_cs42l43.o \
+ soc_sdw_cs_amp.o \
+ soc_sdw_maxim.o
+obj-$(CONFIG_SND_SOC_SDW_UTILS) += snd-soc-sdw-utils.o
diff --git a/sound/soc/intel/boards/bridge_cs35l56.c b/sound/soc/sdw_utils/soc_sdw_bridge_cs35l56.c
index c3995e724aed..fcc3ef685af7 100644
--- a/sound/soc/intel/boards/bridge_cs35l56.c
+++ b/sound/soc/sdw_utils/soc_sdw_bridge_cs35l56.c
@@ -1,6 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-only
-//
-// Intel SOF Machine Driver with Cirrus Logic CS35L56 Smart Amp
+// This file incorporates work covered by the following copyright notice:
+// Copyright (c) 2024 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
+
+/*
+ * soc_sdw_bridge_cs35l56 - codec helper functions for handling CS35L56 Smart AMP
+ */
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -9,7 +14,7 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
static const struct snd_soc_dapm_widget bridge_widgets[] = {
SND_SOC_DAPM_SPK("Bridge Speaker", NULL),
@@ -25,7 +30,7 @@ static const char * const bridge_cs35l56_name_prefixes[] = {
"AMPR",
};
-static int bridge_cs35l56_asp_init(struct snd_soc_pcm_runtime *rtd)
+static int asoc_sdw_bridge_cs35l56_asp_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
int i, ret;
@@ -73,7 +78,7 @@ static int bridge_cs35l56_asp_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
-static const struct snd_soc_pcm_stream bridge_params = {
+static const struct snd_soc_pcm_stream asoc_sdw_bridge_params = {
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rate_min = 48000,
.rate_max = 48000,
@@ -81,7 +86,7 @@ static const struct snd_soc_pcm_stream bridge_params = {
.channels_max = 2,
};
-SND_SOC_DAILINK_DEFS(bridge_dai,
+SND_SOC_DAILINK_DEFS(asoc_sdw_bridge_dai,
DAILINK_COMP_ARRAY(COMP_CODEC("cs42l43-codec", "cs42l43-asp")),
DAILINK_COMP_ARRAY(COMP_CODEC("spi-cs35l56-left", "cs35l56-asp1"),
COMP_CODEC("spi-cs35l56-right", "cs35l56-asp1")),
@@ -89,28 +94,33 @@ SND_SOC_DAILINK_DEFS(bridge_dai,
static const struct snd_soc_dai_link bridge_dai_template = {
.name = "cs42l43-cs35l56",
- .init = bridge_cs35l56_asp_init,
- .c2c_params = &bridge_params,
+ .init = asoc_sdw_bridge_cs35l56_asp_init,
+ .c2c_params = &asoc_sdw_bridge_params,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBC_CFC,
- SND_SOC_DAILINK_REG(bridge_dai),
+ SND_SOC_DAILINK_REG(asoc_sdw_bridge_dai),
};
-int bridge_cs35l56_count_sidecar(struct snd_soc_card *card,
- int *num_dais, int *num_devs)
+int asoc_sdw_bridge_cs35l56_count_sidecar(struct snd_soc_card *card,
+ int *num_dais, int *num_devs)
{
- if (sof_sdw_quirk & SOF_SIDECAR_AMPS) {
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+
+ if (ctx->mc_quirk & SOC_SDW_SIDECAR_AMPS) {
(*num_dais)++;
(*num_devs) += ARRAY_SIZE(bridge_cs35l56_name_prefixes);
}
return 0;
}
+EXPORT_SYMBOL_NS(asoc_sdw_bridge_cs35l56_count_sidecar, SND_SOC_SDW_UTILS);
-int bridge_cs35l56_add_sidecar(struct snd_soc_card *card,
- struct snd_soc_dai_link **dai_links,
- struct snd_soc_codec_conf **codec_conf)
+int asoc_sdw_bridge_cs35l56_add_sidecar(struct snd_soc_card *card,
+ struct snd_soc_dai_link **dai_links,
+ struct snd_soc_codec_conf **codec_conf)
{
- if (sof_sdw_quirk & SOF_SIDECAR_AMPS) {
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+
+ if (ctx->mc_quirk & SOC_SDW_SIDECAR_AMPS) {
**dai_links = bridge_dai_template;
for (int i = 0; i < ARRAY_SIZE(bridge_cs35l56_name_prefixes); i++) {
@@ -124,14 +134,18 @@ int bridge_cs35l56_add_sidecar(struct snd_soc_card *card,
return 0;
}
+EXPORT_SYMBOL_NS(asoc_sdw_bridge_cs35l56_add_sidecar, SND_SOC_SDW_UTILS);
-int bridge_cs35l56_spk_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback)
+int asoc_sdw_bridge_cs35l56_spk_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback)
{
- if (sof_sdw_quirk & SOF_SIDECAR_AMPS)
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+
+ if (ctx->mc_quirk & SOC_SDW_SIDECAR_AMPS)
info->amp_num += ARRAY_SIZE(bridge_cs35l56_name_prefixes);
return 0;
}
+EXPORT_SYMBOL_NS(asoc_sdw_bridge_cs35l56_spk_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_cs42l42.c b/sound/soc/sdw_utils/soc_sdw_cs42l42.c
index fc18e4aa3dbe..78a6cb059ac0 100644
--- a/sound/soc/intel/boards/sof_sdw_cs42l42.c
+++ b/sound/soc/sdw_utils/soc_sdw_cs42l42.c
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2023 Intel Corporation
-
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
/*
- * sof_sdw_cs42l42 - Helpers to handle CS42L42 from generic machine driver
+ * soc_sdw_cs42l42 - Helpers to handle CS42L42 from generic machine driver
*/
#include <linux/device.h>
@@ -15,7 +16,7 @@
#include <sound/soc-acpi.h>
#include <sound/soc-dapm.h>
#include <sound/jack.h>
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
static const struct snd_soc_dapm_route cs42l42_map[] = {
/* HP jack connectors - unknown if we have jack detection */
@@ -36,10 +37,10 @@ static struct snd_soc_jack_pin cs42l42_jack_pins[] = {
},
};
-int cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_component *component;
struct snd_soc_jack *jack;
int ret;
@@ -87,4 +88,4 @@ int cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
return ret;
}
-MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
+EXPORT_SYMBOL_NS(asoc_sdw_cs42l42_rtd_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_cs42l43.c b/sound/soc/sdw_utils/soc_sdw_cs42l43.c
index b7e2750c1074..adb1c008e871 100644
--- a/sound/soc/intel/boards/sof_sdw_cs42l43.c
+++ b/sound/soc/sdw_utils/soc_sdw_cs42l43.c
@@ -1,9 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-only
// Based on sof_sdw_rt5682.c
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2023 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
/*
- * sof_sdw_cs42l43 - Helpers to handle CS42L43 from generic machine driver
+ * soc_sdw_cs42l43 - Helpers to handle CS42L43 from generic machine driver
*/
#include <linux/device.h>
#include <linux/errno.h>
@@ -16,7 +18,7 @@
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/soc-dapm.h>
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
static const struct snd_soc_dapm_route cs42l43_hs_map[] = {
{ "Headphone", NULL, "cs42l43 AMP3_OUT" },
@@ -37,7 +39,7 @@ static const struct snd_soc_dapm_route cs42l43_dmic_map[] = {
{ "cs42l43 PDM2_DIN", NULL, "DMIC" },
};
-static struct snd_soc_jack_pin sof_jack_pins[] = {
+static struct snd_soc_jack_pin soc_jack_pins[] = {
{
.pin = "Headphone",
.mask = SND_JACK_HEADPHONE,
@@ -48,10 +50,10 @@ static struct snd_soc_jack_pin sof_jack_pins[] = {
},
};
-int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
- struct mc_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_jack *jack = &ctx->sdw_headset;
struct snd_soc_card *card = rtd->card;
int ret;
@@ -73,8 +75,8 @@ int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai
SND_JACK_HEADSET | SND_JACK_LINEOUT |
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3,
- jack, sof_jack_pins,
- ARRAY_SIZE(sof_jack_pins));
+ jack, soc_jack_pins,
+ ARRAY_SIZE(soc_jack_pins));
if (ret) {
dev_err(card->dev, "Failed to create jack: %d\n", ret);
return ret;
@@ -98,13 +100,15 @@ int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai
return ret;
}
+EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_hs_rtd_init, SND_SOC_SDW_UTILS);
-int cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
int ret;
- if (!(sof_sdw_quirk & SOF_SIDECAR_AMPS)) {
+ if (!(ctx->mc_quirk & SOC_SDW_SIDECAR_AMPS)) {
/* Will be set by the bridge code in this case */
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
"%s spk:cs42l43-spk",
@@ -120,11 +124,12 @@ int cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *da
return ret;
}
+EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_spk_rtd_init, SND_SOC_SDW_UTILS);
-int sof_sdw_cs42l43_spk_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback)
+int asoc_sdw_cs42l43_spk_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback)
{
/* Do init on playback link only. */
if (!playback)
@@ -132,10 +137,11 @@ int sof_sdw_cs42l43_spk_init(struct snd_soc_card *card,
info->amp_num++;
- return bridge_cs35l56_spk_init(card, dai_links, info, playback);
+ return asoc_sdw_bridge_cs35l56_spk_init(card, dai_links, info, playback);
}
+EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_spk_init, SND_SOC_SDW_UTILS);
-int cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
int ret;
@@ -152,4 +158,4 @@ int cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *d
return ret;
}
-
+EXPORT_SYMBOL_NS(asoc_sdw_cs42l43_dmic_rtd_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_cs_amp.c b/sound/soc/sdw_utils/soc_sdw_cs_amp.c
index 10e08207619a..58b059b68016 100644
--- a/sound/soc/intel/boards/sof_sdw_cs_amp.c
+++ b/sound/soc/sdw_utils/soc_sdw_cs_amp.c
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2023 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
/*
- * sof_sdw_cs_amp - Helpers to handle CS35L56 from generic machine driver
+ * soc_sdw_cs_amp - Helpers to handle CS35L56 from generic machine driver
*/
#include <linux/device.h>
@@ -10,11 +12,11 @@
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/soc-dai.h>
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
#define CODEC_NAME_SIZE 8
-int cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
const char *dai_name = rtd->dai_link->codecs->dai_name;
struct snd_soc_card *card = rtd->card;
@@ -44,11 +46,12 @@ int cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
return 0;
}
+EXPORT_SYMBOL_NS(asoc_sdw_cs_spk_rtd_init, SND_SOC_SDW_UTILS);
-int sof_sdw_cs_amp_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback)
+int asoc_sdw_cs_amp_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback)
{
/* Do init on playback link only. */
if (!playback)
@@ -58,3 +61,4 @@ int sof_sdw_cs_amp_init(struct snd_soc_card *card,
return 0;
}
+EXPORT_SYMBOL_NS(asoc_sdw_cs_amp_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_dmic.c b/sound/soc/sdw_utils/soc_sdw_dmic.c
index 19df0f7a1d85..fc2aae985084 100644
--- a/sound/soc/intel/boards/sof_sdw_dmic.c
+++ b/sound/soc/sdw_utils/soc_sdw_dmic.c
@@ -1,14 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2020 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
/*
- * sof_sdw_dmic - Helpers to handle dmic from generic machine driver
+ * soc_sdw_dmic - Helpers to handle dmic from generic machine driver
*/
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/soc-dapm.h>
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
static const struct snd_soc_dapm_widget dmic_widgets[] = {
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
@@ -19,7 +21,7 @@ static const struct snd_soc_dapm_route dmic_map[] = {
{"DMic", NULL, "SoC DMIC"},
};
-int sof_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd)
+int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
int ret;
@@ -40,4 +42,4 @@ int sof_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd)
return ret;
}
-
+EXPORT_SYMBOL_NS(asoc_sdw_dmic_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_maxim.c b/sound/soc/sdw_utils/soc_sdw_maxim.c
index b7f73177867f..cdcd8df37e1d 100644
--- a/sound/soc/intel/boards/sof_sdw_maxim.c
+++ b/sound/soc/sdw_utils/soc_sdw_maxim.c
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2020 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
//
-// sof_sdw_maxim - Helpers to handle maxim codecs
+// soc_sdw_maxim - Helpers to handle maxim codecs
// codec devices from generic machine driver
#include <linux/device.h>
@@ -10,18 +12,18 @@
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/soc-dapm.h>
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
static int maxim_part_id;
-#define SOF_SDW_PART_ID_MAX98363 0x8363
-#define SOF_SDW_PART_ID_MAX98373 0x8373
+#define SOC_SDW_PART_ID_MAX98363 0x8363
+#define SOC_SDW_PART_ID_MAX98373 0x8373
static const struct snd_soc_dapm_route max_98373_dapm_routes[] = {
{ "Left Spk", NULL, "Left BE_OUT" },
{ "Right Spk", NULL, "Right BE_OUT" },
};
-int maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
int ret;
@@ -41,8 +43,9 @@ int maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
return ret;
}
+EXPORT_SYMBOL_NS(asoc_sdw_maxim_spk_rtd_init, SND_SOC_SDW_UTILS);
-static int mx8373_enable_spk_pin(struct snd_pcm_substream *substream, bool enable)
+static int asoc_sdw_mx8373_enable_spk_pin(struct snd_pcm_substream *substream, bool enable)
{
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai;
@@ -75,40 +78,40 @@ static int mx8373_enable_spk_pin(struct snd_pcm_substream *substream, bool enabl
return 0;
}
-static int mx8373_sdw_prepare(struct snd_pcm_substream *substream)
+static int asoc_sdw_mx8373_prepare(struct snd_pcm_substream *substream)
{
int ret;
/* according to soc_pcm_prepare dai link prepare is called first */
- ret = sdw_prepare(substream);
+ ret = asoc_sdw_prepare(substream);
if (ret < 0)
return ret;
- return mx8373_enable_spk_pin(substream, true);
+ return asoc_sdw_mx8373_enable_spk_pin(substream, true);
}
-static int mx8373_sdw_hw_free(struct snd_pcm_substream *substream)
+static int asoc_sdw_mx8373_hw_free(struct snd_pcm_substream *substream)
{
int ret;
/* according to soc_pcm_hw_free dai link free is called first */
- ret = sdw_hw_free(substream);
+ ret = asoc_sdw_hw_free(substream);
if (ret < 0)
return ret;
- return mx8373_enable_spk_pin(substream, false);
+ return asoc_sdw_mx8373_enable_spk_pin(substream, false);
}
static const struct snd_soc_ops max_98373_sdw_ops = {
- .startup = sdw_startup,
- .prepare = mx8373_sdw_prepare,
- .trigger = sdw_trigger,
- .hw_params = sdw_hw_params,
- .hw_free = mx8373_sdw_hw_free,
- .shutdown = sdw_shutdown,
+ .startup = asoc_sdw_startup,
+ .prepare = asoc_sdw_mx8373_prepare,
+ .trigger = asoc_sdw_trigger,
+ .hw_params = asoc_sdw_hw_params,
+ .hw_free = asoc_sdw_mx8373_hw_free,
+ .shutdown = asoc_sdw_shutdown,
};
-static int mx8373_sdw_late_probe(struct snd_soc_card *card)
+static int asoc_sdw_mx8373_sdw_late_probe(struct snd_soc_card *card)
{
struct snd_soc_dapm_context *dapm = &card->dapm;
@@ -118,22 +121,22 @@ static int mx8373_sdw_late_probe(struct snd_soc_card *card)
return snd_soc_dapm_sync(dapm);
}
-int sof_sdw_maxim_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback)
+int asoc_sdw_maxim_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback)
{
info->amp_num++;
maxim_part_id = info->part_id;
switch (maxim_part_id) {
- case SOF_SDW_PART_ID_MAX98363:
+ case SOC_SDW_PART_ID_MAX98363:
/* Default ops are set in function init_dai_link.
* called as part of function create_sdw_dailink
*/
break;
- case SOF_SDW_PART_ID_MAX98373:
- info->codec_card_late_probe = mx8373_sdw_late_probe;
+ case SOC_SDW_PART_ID_MAX98373:
+ info->codec_card_late_probe = asoc_sdw_mx8373_sdw_late_probe;
dai_links->ops = &max_98373_sdw_ops;
break;
default:
@@ -142,3 +145,4 @@ int sof_sdw_maxim_init(struct snd_soc_card *card,
}
return 0;
}
+EXPORT_SYMBOL_NS(asoc_sdw_maxim_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_rt5682.c b/sound/soc/sdw_utils/soc_sdw_rt5682.c
index 67737815d016..80b4caa92667 100644
--- a/sound/soc/intel/boards/sof_sdw_rt5682.c
+++ b/sound/soc/sdw_utils/soc_sdw_rt5682.c
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2020 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
/*
- * sof_sdw_rt5682 - Helpers to handle RT5682 from generic machine driver
+ * soc_sdw_rt5682 - Helpers to handle RT5682 from generic machine driver
*/
#include <linux/device.h>
@@ -15,7 +17,7 @@
#include <sound/soc-acpi.h>
#include <sound/soc-dapm.h>
#include <sound/jack.h>
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
static const struct snd_soc_dapm_route rt5682_map[] = {
/*Headphones*/
@@ -35,10 +37,10 @@ static struct snd_soc_jack_pin rt5682_jack_pins[] = {
},
};
-int rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_component *component;
struct snd_soc_jack *jack;
int ret;
@@ -86,4 +88,4 @@ int rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
return ret;
}
-MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
+EXPORT_SYMBOL_NS(asoc_sdw_rt5682_rtd_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_rt700.c b/sound/soc/sdw_utils/soc_sdw_rt700.c
index 0db730071be2..4dbeeeca3434 100644
--- a/sound/soc/intel/boards/sof_sdw_rt700.c
+++ b/sound/soc/sdw_utils/soc_sdw_rt700.c
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2020 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
/*
- * sof_sdw_rt700 - Helpers to handle RT700 from generic machine driver
+ * soc_sdw_rt700 - Helpers to handle RT700 from generic machine driver
*/
#include <linux/device.h>
@@ -13,7 +15,7 @@
#include <sound/soc-acpi.h>
#include <sound/soc-dapm.h>
#include <sound/jack.h>
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
static const struct snd_soc_dapm_route rt700_map[] = {
/* Headphones */
@@ -33,10 +35,10 @@ static struct snd_soc_jack_pin rt700_jack_pins[] = {
},
};
-int rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_component *component;
struct snd_soc_jack *jack;
int ret;
@@ -83,4 +85,4 @@ int rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
return ret;
}
-MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
+EXPORT_SYMBOL_NS(asoc_sdw_rt700_rtd_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/sdw_utils/soc_sdw_rt711.c
index 60ff4d88e2dc..38b4126dd45f 100644
--- a/sound/soc/intel/boards/sof_sdw_rt711.c
+++ b/sound/soc/sdw_utils/soc_sdw_rt711.c
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2020 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
/*
- * sof_sdw_rt711 - Helpers to handle RT711 from generic machine driver
+ * soc_sdw_rt711 - Helpers to handle RT711 from generic machine driver
*/
#include <linux/device.h>
@@ -15,21 +17,21 @@
#include <sound/soc-acpi.h>
#include <sound/soc-dapm.h>
#include <sound/jack.h>
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
/*
* Note this MUST be called before snd_soc_register_card(), so that the props
* are in place before the codec component driver's probe function parses them.
*/
-static int rt711_add_codec_device_props(struct device *sdw_dev)
+static int rt711_add_codec_device_props(struct device *sdw_dev, unsigned long quirk)
{
- struct property_entry props[MAX_NO_PROPS] = {};
+ struct property_entry props[SOC_SDW_MAX_NO_PROPS] = {};
struct fwnode_handle *fwnode;
int ret;
- if (!SOF_JACK_JDSRC(sof_sdw_quirk))
+ if (!SOC_SDW_JACK_JDSRC(quirk))
return 0;
- props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_JACK_JDSRC(sof_sdw_quirk));
+ props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOC_SDW_JACK_JDSRC(quirk));
fwnode = fwnode_create_software_node(props, NULL);
if (IS_ERR(fwnode))
@@ -59,10 +61,10 @@ static struct snd_soc_jack_pin rt711_jack_pins[] = {
},
};
-int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_component *component;
struct snd_soc_jack *jack;
int ret;
@@ -110,10 +112,11 @@ int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
return ret;
}
+EXPORT_SYMBOL_NS(asoc_sdw_rt711_rtd_init, SND_SOC_SDW_UTILS);
-int sof_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
+int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
{
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
if (!ctx->headset_codec_dev)
return 0;
@@ -123,13 +126,14 @@ int sof_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_l
return 0;
}
+EXPORT_SYMBOL_NS(asoc_sdw_rt711_exit, SND_SOC_SDW_UTILS);
-int sof_sdw_rt711_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback)
+int asoc_sdw_rt711_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback)
{
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct device *sdw_dev;
int ret;
@@ -144,7 +148,7 @@ int sof_sdw_rt711_init(struct snd_soc_card *card,
if (!sdw_dev)
return -EPROBE_DEFER;
- ret = rt711_add_codec_device_props(sdw_dev);
+ ret = rt711_add_codec_device_props(sdw_dev, ctx->mc_quirk);
if (ret < 0) {
put_device(sdw_dev);
return ret;
@@ -153,4 +157,4 @@ int sof_sdw_rt711_init(struct snd_soc_card *card,
return 0;
}
-MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
+EXPORT_SYMBOL_NS(asoc_sdw_rt711_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_rt712_sdca.c b/sound/soc/sdw_utils/soc_sdw_rt712_sdca.c
index 788796461885..5127210b9a03 100644
--- a/sound/soc/intel/boards/sof_sdw_rt712_sdca.c
+++ b/sound/soc/sdw_utils/soc_sdw_rt712_sdca.c
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2023 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
/*
- * sof_sdw_rt712_sdca - Helpers to handle RT712-SDCA from generic machine driver
+ * soc_sdw_rt712_sdca - Helpers to handle RT712-SDCA from generic machine driver
*/
#include <linux/device.h>
@@ -13,7 +15,7 @@
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/soc-dapm.h>
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
/*
* dapm routes for rt712 spk will be registered dynamically according
@@ -26,7 +28,7 @@ static const struct snd_soc_dapm_route rt712_spk_map[] = {
{ "Speaker", NULL, "rt712 SPOR" },
};
-int rt712_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_rt712_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
int ret;
@@ -43,4 +45,4 @@ int rt712_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
return ret;
}
-
+EXPORT_SYMBOL_NS(asoc_sdw_rt712_spk_rtd_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_rt722_sdca.c b/sound/soc/sdw_utils/soc_sdw_rt722_sdca.c
index 083d281bd052..6a402172289f 100644
--- a/sound/soc/intel/boards/sof_sdw_rt722_sdca.c
+++ b/sound/soc/sdw_utils/soc_sdw_rt722_sdca.c
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2023 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
/*
- * sof_sdw_rt722_sdca - Helpers to handle RT722-SDCA from generic machine driver
+ * soc_sdw_rt722_sdca - Helpers to handle RT722-SDCA from generic machine driver
*/
#include <linux/device.h>
@@ -13,13 +15,13 @@
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/soc-dapm.h>
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
static const struct snd_soc_dapm_route rt722_spk_map[] = {
{ "Speaker", NULL, "rt722 SPK" },
};
-int rt722_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_rt722_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
int ret;
@@ -36,4 +38,4 @@ int rt722_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
return ret;
}
-
+EXPORT_SYMBOL_NS(asoc_sdw_rt722_spk_rtd_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_rt_amp.c b/sound/soc/sdw_utils/soc_sdw_rt_amp.c
index d1c0f91ce589..42be01405ab4 100644
--- a/sound/soc/intel/boards/sof_sdw_rt_amp.c
+++ b/sound/soc/sdw_utils/soc_sdw_rt_amp.c
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2022 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
/*
- * sof_sdw_rt_amp - Helpers to handle RT1308/RT1316/RT1318 from generic machine driver
+ * soc_sdw_rt_amp - Helpers to handle RT1308/RT1316/RT1318 from generic machine driver
*/
#include <linux/device.h>
@@ -14,9 +16,9 @@
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
#include <linux/dmi.h>
-#include "sof_sdw_common.h"
-#include "sof_sdw_amp_coeff_tables.h"
-#include "../../codecs/rt1308.h"
+#include <sound/soc_sdw_utils.h>
+#include "soc_sdw_rt_amp_coeff_tables.h"
+#include "../codecs/rt1308.h"
#define CODEC_NAME_SIZE 7
@@ -173,7 +175,7 @@ static const struct snd_soc_dapm_route *get_codec_name_and_route(struct snd_soc_
return rt1318_map;
}
-int rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
const struct snd_soc_dapm_route *rt_amp_map;
@@ -199,6 +201,7 @@ int rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai
return ret;
}
+EXPORT_SYMBOL_NS(asoc_sdw_rt_amp_spk_rtd_init, SND_SOC_SDW_UTILS);
static int rt1308_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
@@ -233,13 +236,14 @@ static int rt1308_i2s_hw_params(struct snd_pcm_substream *substream,
}
/* machine stream operations */
-const struct snd_soc_ops sof_sdw_rt1308_i2s_ops = {
+const struct snd_soc_ops soc_sdw_rt1308_i2s_ops = {
.hw_params = rt1308_i2s_hw_params,
};
+EXPORT_SYMBOL_NS(soc_sdw_rt1308_i2s_ops, SND_SOC_SDW_UTILS);
-int sof_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
+int asoc_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
{
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
if (ctx->amp_dev1) {
device_remove_software_node(ctx->amp_dev1);
@@ -253,13 +257,14 @@ int sof_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_
return 0;
}
+EXPORT_SYMBOL_NS(asoc_sdw_rt_amp_exit, SND_SOC_SDW_UTILS);
-int sof_sdw_rt_amp_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback)
+int asoc_sdw_rt_amp_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback)
{
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct device *sdw_dev1, *sdw_dev2;
int ret;
@@ -295,3 +300,4 @@ int sof_sdw_rt_amp_init(struct snd_soc_card *card,
return 0;
}
+EXPORT_SYMBOL_NS(asoc_sdw_rt_amp_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h b/sound/soc/sdw_utils/soc_sdw_rt_amp_coeff_tables.h
index 4a3e6fdbd623..4803d134d071 100644
--- a/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h
+++ b/sound/soc/sdw_utils/soc_sdw_rt_amp_coeff_tables.h
@@ -2,11 +2,11 @@
*/
/*
- * sof_sdw_amp_coeff_tables.h - related coefficients for amplifier parameters
+ * soc_sdw_rt_amp_coeff_tables.h - related coefficients for RTK amplifier parameters
*/
-#ifndef SND_SOC_SOF_SDW_AMP_COEFF_H
-#define SND_SOC_SOF_SDW_AMP_COEFF_H
+#ifndef SND_SOC_SDW_RT_SDW_AMP_COEFF_H
+#define SND_SOC_SDW_RT_SDW_AMP_COEFF_H
#define RT1308_MAX_BQ_REG 480
#define RT1316_MAX_BQ_REG 580
diff --git a/sound/soc/intel/boards/sof_sdw_rt_dmic.c b/sound/soc/sdw_utils/soc_sdw_rt_dmic.c
index ea7c1a4bc566..7f24806d809d 100644
--- a/sound/soc/intel/boards/sof_sdw_rt_dmic.c
+++ b/sound/soc/sdw_utils/soc_sdw_rt_dmic.c
@@ -1,18 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2024 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
/*
- * sof_sdw_rt_dmic - Helpers to handle Realtek SDW DMIC from generic machine driver
+ * soc_sdw_rt_dmic - Helpers to handle Realtek SDW DMIC from generic machine driver
*/
#include <linux/device.h>
#include <linux/errno.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
-#include "sof_board_helpers.h"
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
-int rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
struct snd_soc_component *component;
@@ -39,4 +40,4 @@ int rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
return 0;
}
-MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
+EXPORT_SYMBOL_NS(asoc_sdw_rt_dmic_rtd_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c b/sound/soc/sdw_utils/soc_sdw_rt_sdca_jack_common.c
index 4254e30ee4c3..3e6211dc1599 100644
--- a/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c
+++ b/sound/soc/sdw_utils/soc_sdw_rt_sdca_jack_common.c
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
// Copyright (c) 2020 Intel Corporation
+// Copyright (c) 2024 Advanced Micro Devices, Inc.
/*
- * sof_sdw_rt711_sdca - Helpers to handle RT711-SDCA from generic machine driver
+ * soc_sdw_rt711_sdca - Helpers to handle RT711-SDCA from generic machine driver
*/
#include <linux/device.h>
@@ -15,22 +17,22 @@
#include <sound/soc-acpi.h>
#include <sound/soc-dapm.h>
#include <sound/jack.h>
-#include "sof_sdw_common.h"
+#include <sound/soc_sdw_utils.h>
/*
* Note this MUST be called before snd_soc_register_card(), so that the props
* are in place before the codec component driver's probe function parses them.
*/
-static int rt_sdca_jack_add_codec_device_props(struct device *sdw_dev)
+static int rt_sdca_jack_add_codec_device_props(struct device *sdw_dev, unsigned long quirk)
{
- struct property_entry props[MAX_NO_PROPS] = {};
+ struct property_entry props[SOC_SDW_MAX_NO_PROPS] = {};
struct fwnode_handle *fwnode;
int ret;
- if (!SOF_JACK_JDSRC(sof_sdw_quirk))
+ if (!SOC_SDW_JACK_JDSRC(quirk))
return 0;
- props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_JACK_JDSRC(sof_sdw_quirk));
+ props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOC_SDW_JACK_JDSRC(quirk));
fwnode = fwnode_create_software_node(props, NULL);
if (IS_ERR(fwnode))
@@ -83,10 +85,10 @@ static const char * const need_sdca_suffix[] = {
"rt711", "rt713"
};
-int rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
+int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
struct snd_soc_card *card = rtd->card;
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_component *component;
struct snd_soc_jack *jack;
int ret;
@@ -160,15 +162,16 @@ int rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *d
return ret;
}
+EXPORT_SYMBOL_NS(asoc_sdw_rt_sdca_jack_rtd_init, SND_SOC_SDW_UTILS);
-int sof_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
+int asoc_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
{
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
if (!ctx->headset_codec_dev)
return 0;
- if (!SOF_JACK_JDSRC(sof_sdw_quirk))
+ if (!SOC_SDW_JACK_JDSRC(ctx->mc_quirk))
return 0;
device_remove_software_node(ctx->headset_codec_dev);
@@ -177,13 +180,14 @@ int sof_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link
return 0;
}
+EXPORT_SYMBOL_NS(asoc_sdw_rt_sdca_jack_exit, SND_SOC_SDW_UTILS);
-int sof_sdw_rt_sdca_jack_init(struct snd_soc_card *card,
- struct snd_soc_dai_link *dai_links,
- struct sof_sdw_codec_info *info,
- bool playback)
+int asoc_sdw_rt_sdca_jack_init(struct snd_soc_card *card,
+ struct snd_soc_dai_link *dai_links,
+ struct asoc_sdw_codec_info *info,
+ bool playback)
{
- struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct device *sdw_dev;
int ret;
@@ -198,7 +202,7 @@ int sof_sdw_rt_sdca_jack_init(struct snd_soc_card *card,
if (!sdw_dev)
return -EPROBE_DEFER;
- ret = rt_sdca_jack_add_codec_device_props(sdw_dev);
+ ret = rt_sdca_jack_add_codec_device_props(sdw_dev, ctx->mc_quirk);
if (ret < 0) {
put_device(sdw_dev);
return ret;
@@ -207,4 +211,4 @@ int sof_sdw_rt_sdca_jack_init(struct snd_soc_card *card,
return 0;
}
-MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
+EXPORT_SYMBOL_NS(asoc_sdw_rt_sdca_jack_init, SND_SOC_SDW_UTILS);
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
new file mode 100644
index 000000000000..6183629d1754
--- /dev/null
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -0,0 +1,990 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// This file incorporates work covered by the following copyright notice:
+// Copyright (c) 2020 Intel Corporation
+// Copyright(c) 2024 Advanced Micro Devices, Inc.
+/*
+ * soc-sdw-utils.c - common SoundWire machine driver helper functions
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_type.h>
+#include <sound/soc_sdw_utils.h>
+
+static const struct snd_soc_dapm_widget generic_dmic_widgets[] = {
+ SND_SOC_DAPM_MIC("DMIC", NULL),
+};
+
+static const struct snd_soc_dapm_widget generic_jack_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_kcontrol_new generic_jack_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+static const struct snd_soc_dapm_widget generic_spk_widgets[] = {
+ SND_SOC_DAPM_SPK("Speaker", NULL),
+};
+
+static const struct snd_kcontrol_new generic_spk_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Speaker"),
+};
+
+static const struct snd_soc_dapm_widget maxim_widgets[] = {
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
+};
+
+static const struct snd_kcontrol_new maxim_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Left Spk"),
+ SOC_DAPM_PIN_SWITCH("Right Spk"),
+};
+
+static const struct snd_soc_dapm_widget rt700_widgets[] = {
+ SND_SOC_DAPM_HP("Headphones", NULL),
+ SND_SOC_DAPM_MIC("AMIC", NULL),
+ SND_SOC_DAPM_SPK("Speaker", NULL),
+};
+
+static const struct snd_kcontrol_new rt700_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphones"),
+ SOC_DAPM_PIN_SWITCH("AMIC"),
+ SOC_DAPM_PIN_SWITCH("Speaker"),
+};
+
+struct asoc_sdw_codec_info codec_info_list[] = {
+ {
+ .part_id = 0x700,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt700-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .rtd_init = asoc_sdw_rt700_rtd_init,
+ .controls = rt700_controls,
+ .num_controls = ARRAY_SIZE(rt700_controls),
+ .widgets = rt700_widgets,
+ .num_widgets = ARRAY_SIZE(rt700_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x711,
+ .version_id = 3,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt711-sdca-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .init = asoc_sdw_rt_sdca_jack_init,
+ .exit = asoc_sdw_rt_sdca_jack_exit,
+ .rtd_init = asoc_sdw_rt_sdca_jack_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x711,
+ .version_id = 2,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt711-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .init = asoc_sdw_rt711_init,
+ .exit = asoc_sdw_rt711_exit,
+ .rtd_init = asoc_sdw_rt711_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x712,
+ .version_id = 3,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt712-sdca-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .init = asoc_sdw_rt_sdca_jack_init,
+ .exit = asoc_sdw_rt_sdca_jack_exit,
+ .rtd_init = asoc_sdw_rt_sdca_jack_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ {
+ .direction = {true, false},
+ .dai_name = "rt712-sdca-aif2",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .init = asoc_sdw_rt_amp_init,
+ .exit = asoc_sdw_rt_amp_exit,
+ .rtd_init = asoc_sdw_rt712_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ },
+ .dai_num = 2,
+ },
+ {
+ .part_id = 0x1712,
+ .version_id = 3,
+ .dais = {
+ {
+ .direction = {false, true},
+ .dai_name = "rt712-sdca-dmic-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x713,
+ .version_id = 3,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt712-sdca-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .init = asoc_sdw_rt_sdca_jack_init,
+ .exit = asoc_sdw_rt_sdca_jack_exit,
+ .rtd_init = asoc_sdw_rt_sdca_jack_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x1713,
+ .version_id = 3,
+ .dais = {
+ {
+ .direction = {false, true},
+ .dai_name = "rt712-sdca-dmic-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x1308,
+ .acpi_id = "10EC1308",
+ .dais = {
+ {
+ .direction = {true, false},
+ .dai_name = "rt1308-aif",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .init = asoc_sdw_rt_amp_init,
+ .exit = asoc_sdw_rt_amp_exit,
+ .rtd_init = asoc_sdw_rt_amp_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ },
+ .dai_num = 1,
+ .ops = &soc_sdw_rt1308_i2s_ops,
+ },
+ {
+ .part_id = 0x1316,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt1316-aif",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
+ .init = asoc_sdw_rt_amp_init,
+ .exit = asoc_sdw_rt_amp_exit,
+ .rtd_init = asoc_sdw_rt_amp_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x1318,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt1318-aif",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
+ .init = asoc_sdw_rt_amp_init,
+ .exit = asoc_sdw_rt_amp_exit,
+ .rtd_init = asoc_sdw_rt_amp_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x714,
+ .version_id = 3,
+ .ignore_internal_dmic = true,
+ .dais = {
+ {
+ .direction = {false, true},
+ .dai_name = "rt715-sdca-aif2",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x715,
+ .version_id = 3,
+ .ignore_internal_dmic = true,
+ .dais = {
+ {
+ .direction = {false, true},
+ .dai_name = "rt715-sdca-aif2",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x714,
+ .version_id = 2,
+ .ignore_internal_dmic = true,
+ .dais = {
+ {
+ .direction = {false, true},
+ .dai_name = "rt715-aif2",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x715,
+ .version_id = 2,
+ .ignore_internal_dmic = true,
+ .dais = {
+ {
+ .direction = {false, true},
+ .dai_name = "rt715-aif2",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x722,
+ .version_id = 3,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt722-sdca-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .init = asoc_sdw_rt_sdca_jack_init,
+ .exit = asoc_sdw_rt_sdca_jack_exit,
+ .rtd_init = asoc_sdw_rt_sdca_jack_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ {
+ .direction = {true, false},
+ .dai_name = "rt722-sdca-aif2",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ /* No feedback capability is provided by rt722-sdca codec driver*/
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .init = asoc_sdw_rt_amp_init,
+ .exit = asoc_sdw_rt_amp_exit,
+ .rtd_init = asoc_sdw_rt722_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ {
+ .direction = {false, true},
+ .dai_name = "rt722-sdca-aif3",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_rt_dmic_rtd_init,
+ },
+ },
+ .dai_num = 3,
+ },
+ {
+ .part_id = 0x8373,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "max98373-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
+ .init = asoc_sdw_maxim_init,
+ .rtd_init = asoc_sdw_maxim_spk_rtd_init,
+ .controls = maxim_controls,
+ .num_controls = ARRAY_SIZE(maxim_controls),
+ .widgets = maxim_widgets,
+ .num_widgets = ARRAY_SIZE(maxim_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x8363,
+ .dais = {
+ {
+ .direction = {true, false},
+ .dai_name = "max98363-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .init = asoc_sdw_maxim_init,
+ .rtd_init = asoc_sdw_maxim_spk_rtd_init,
+ .controls = maxim_controls,
+ .num_controls = ARRAY_SIZE(maxim_controls),
+ .widgets = maxim_widgets,
+ .num_widgets = ARRAY_SIZE(maxim_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x5682,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "rt5682-sdw",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .rtd_init = asoc_sdw_rt5682_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x3556,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "cs35l56-sdw1",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
+ .init = asoc_sdw_cs_amp_init,
+ .rtd_init = asoc_sdw_cs_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x4242,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "cs42l42-sdw",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ .rtd_init = asoc_sdw_cs42l42_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x4243,
+ .codec_name = "cs42l43-codec",
+ .count_sidecar = asoc_sdw_bridge_cs35l56_count_sidecar,
+ .add_sidecar = asoc_sdw_bridge_cs35l56_add_sidecar,
+ .dais = {
+ {
+ .direction = {true, false},
+ .dai_name = "cs42l43-dp5",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .rtd_init = asoc_sdw_cs42l43_hs_rtd_init,
+ .controls = generic_jack_controls,
+ .num_controls = ARRAY_SIZE(generic_jack_controls),
+ .widgets = generic_jack_widgets,
+ .num_widgets = ARRAY_SIZE(generic_jack_widgets),
+ },
+ {
+ .direction = {false, true},
+ .dai_name = "cs42l43-dp1",
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ .rtd_init = asoc_sdw_cs42l43_dmic_rtd_init,
+ .widgets = generic_dmic_widgets,
+ .num_widgets = ARRAY_SIZE(generic_dmic_widgets),
+ },
+ {
+ .direction = {false, true},
+ .dai_name = "cs42l43-dp2",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ },
+ {
+ .direction = {true, false},
+ .dai_name = "cs42l43-dp6",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
+ .init = asoc_sdw_cs42l43_spk_init,
+ .rtd_init = asoc_sdw_cs42l43_spk_rtd_init,
+ .controls = generic_spk_controls,
+ .num_controls = ARRAY_SIZE(generic_spk_controls),
+ .widgets = generic_spk_widgets,
+ .num_widgets = ARRAY_SIZE(generic_spk_widgets),
+ .quirk = SOC_SDW_CODEC_SPKR | SOC_SDW_SIDECAR_AMPS,
+ },
+ },
+ .dai_num = 4,
+ },
+ {
+ .part_id = 0xaaaa, /* generic codec mockup */
+ .version_id = 0,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "sdw-mockup-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0xaa55, /* headset codec mockup */
+ .version_id = 0,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "sdw-mockup-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_JACK,
+ .dailink = {SOC_SDW_JACK_OUT_DAI_ID, SOC_SDW_JACK_IN_DAI_ID},
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x55aa, /* amplifier mockup */
+ .version_id = 0,
+ .dais = {
+ {
+ .direction = {true, true},
+ .dai_name = "sdw-mockup-aif1",
+ .dai_type = SOC_SDW_DAI_TYPE_AMP,
+ .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
+ },
+ },
+ .dai_num = 1,
+ },
+ {
+ .part_id = 0x5555,
+ .version_id = 0,
+ .dais = {
+ {
+ .dai_name = "sdw-mockup-aif1",
+ .direction = {false, true},
+ .dai_type = SOC_SDW_DAI_TYPE_MIC,
+ .dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
+ },
+ },
+ .dai_num = 1,
+ },
+};
+EXPORT_SYMBOL_NS(codec_info_list, SND_SOC_SDW_UTILS);
+
+int asoc_sdw_get_codec_info_list_count(void)
+{
+ return ARRAY_SIZE(codec_info_list);
+};
+EXPORT_SYMBOL_NS(asoc_sdw_get_codec_info_list_count, SND_SOC_SDW_UTILS);
+
+struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr)
+{
+ unsigned int part_id, sdw_version;
+ int i;
+
+ part_id = SDW_PART_ID(adr);
+ sdw_version = SDW_VERSION(adr);
+ for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
+ /*
+ * A codec info is for all sdw version with the part id if
+ * version_id is not specified in the codec info.
+ */
+ if (part_id == codec_info_list[i].part_id &&
+ (!codec_info_list[i].version_id ||
+ sdw_version == codec_info_list[i].version_id))
+ return &codec_info_list[i];
+
+ return NULL;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_part, SND_SOC_SDW_UTILS);
+
+struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id)
+{
+ int i;
+
+ if (!acpi_id[0])
+ return NULL;
+
+ for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
+ if (!memcmp(codec_info_list[i].acpi_id, acpi_id, ACPI_ID_LEN))
+ return &codec_info_list[i];
+
+ return NULL;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_acpi, SND_SOC_SDW_UTILS);
+
+struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, int *dai_index)
+{
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
+ for (j = 0; j < codec_info_list[i].dai_num; j++) {
+ if (!strcmp(codec_info_list[i].dais[j].dai_name, dai_name)) {
+ *dai_index = j;
+ return &codec_info_list[i];
+ }
+ }
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_find_codec_info_dai, SND_SOC_SDW_UTILS);
+
+int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct asoc_sdw_codec_info *codec_info;
+ struct snd_soc_dai *dai;
+ int dai_index;
+ int ret;
+ int i;
+
+ for_each_rtd_codec_dais(rtd, i, dai) {
+ codec_info = asoc_sdw_find_codec_info_dai(dai->name, &dai_index);
+ if (!codec_info)
+ return -EINVAL;
+
+ /*
+ * A codec dai can be connected to different dai links for capture and playback,
+ * but we only need to call the rtd_init function once.
+ * The rtd_init for each codec dai is independent. So, the order of rtd_init
+ * doesn't matter.
+ */
+ if (codec_info->dais[dai_index].rtd_init_done)
+ continue;
+
+ /*
+ * Add card controls and dapm widgets for the first codec dai.
+ * The controls and widgets will be used for all codec dais.
+ */
+
+ if (i > 0)
+ goto skip_add_controls_widgets;
+
+ if (codec_info->dais[dai_index].controls) {
+ ret = snd_soc_add_card_controls(card, codec_info->dais[dai_index].controls,
+ codec_info->dais[dai_index].num_controls);
+ if (ret) {
+ dev_err(card->dev, "%#x controls addition failed: %d\n",
+ codec_info->part_id, ret);
+ return ret;
+ }
+ }
+ if (codec_info->dais[dai_index].widgets) {
+ ret = snd_soc_dapm_new_controls(&card->dapm,
+ codec_info->dais[dai_index].widgets,
+ codec_info->dais[dai_index].num_widgets);
+ if (ret) {
+ dev_err(card->dev, "%#x widgets addition failed: %d\n",
+ codec_info->part_id, ret);
+ return ret;
+ }
+ }
+
+skip_add_controls_widgets:
+ if (codec_info->dais[dai_index].rtd_init) {
+ ret = codec_info->dais[dai_index].rtd_init(rtd, dai);
+ if (ret)
+ return ret;
+ }
+ codec_info->dais[dai_index].rtd_init_done = true;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_rtd_init, SND_SOC_SDW_UTILS);
+
+/* these wrappers are only needed to avoid typecast compilation errors */
+int asoc_sdw_startup(struct snd_pcm_substream *substream)
+{
+ return sdw_startup_stream(substream);
+}
+EXPORT_SYMBOL_NS(asoc_sdw_startup, SND_SOC_SDW_UTILS);
+
+int asoc_sdw_prepare(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct sdw_stream_runtime *sdw_stream;
+ struct snd_soc_dai *dai;
+
+ /* Find stream from first CPU DAI */
+ dai = snd_soc_rtd_to_cpu(rtd, 0);
+
+ sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
+ if (IS_ERR(sdw_stream)) {
+ dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
+ return PTR_ERR(sdw_stream);
+ }
+
+ return sdw_prepare_stream(sdw_stream);
+}
+EXPORT_SYMBOL_NS(asoc_sdw_prepare, SND_SOC_SDW_UTILS);
+
+int asoc_sdw_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct sdw_stream_runtime *sdw_stream;
+ struct snd_soc_dai *dai;
+ int ret;
+
+ /* Find stream from first CPU DAI */
+ dai = snd_soc_rtd_to_cpu(rtd, 0);
+
+ sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
+ if (IS_ERR(sdw_stream)) {
+ dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
+ return PTR_ERR(sdw_stream);
+ }
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ ret = sdw_enable_stream(sdw_stream);
+ break;
+
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_STOP:
+ ret = sdw_disable_stream(sdw_stream);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret)
+ dev_err(rtd->dev, "%s trigger %d failed: %d\n", __func__, cmd, ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_trigger, SND_SOC_SDW_UTILS);
+
+int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai_link_ch_map *ch_maps;
+ int ch = params_channels(params);
+ unsigned int ch_mask;
+ int num_codecs;
+ int step;
+ int i;
+
+ if (!rtd->dai_link->ch_maps)
+ return 0;
+
+ /* Identical data will be sent to all codecs in playback */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ch_mask = GENMASK(ch - 1, 0);
+ step = 0;
+ } else {
+ num_codecs = rtd->dai_link->num_codecs;
+
+ if (ch < num_codecs || ch % num_codecs != 0) {
+ dev_err(rtd->dev, "Channels number %d is invalid when codec number = %d\n",
+ ch, num_codecs);
+ return -EINVAL;
+ }
+
+ ch_mask = GENMASK(ch / num_codecs - 1, 0);
+ step = hweight_long(ch_mask);
+ }
+
+ /*
+ * The captured data will be combined from each cpu DAI if the dai
+ * link has more than one codec DAIs. Set codec channel mask and
+ * ASoC will set the corresponding channel numbers for each cpu dai.
+ */
+ for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
+ ch_maps->ch_mask = ch_mask << (i * step);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_hw_params, SND_SOC_SDW_UTILS);
+
+int asoc_sdw_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct sdw_stream_runtime *sdw_stream;
+ struct snd_soc_dai *dai;
+
+ /* Find stream from first CPU DAI */
+ dai = snd_soc_rtd_to_cpu(rtd, 0);
+
+ sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
+ if (IS_ERR(sdw_stream)) {
+ dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
+ return PTR_ERR(sdw_stream);
+ }
+
+ return sdw_deprepare_stream(sdw_stream);
+}
+EXPORT_SYMBOL_NS(asoc_sdw_hw_free, SND_SOC_SDW_UTILS);
+
+void asoc_sdw_shutdown(struct snd_pcm_substream *substream)
+{
+ sdw_shutdown_stream(substream);
+}
+EXPORT_SYMBOL_NS(asoc_sdw_shutdown, SND_SOC_SDW_UTILS);
+
+static bool asoc_sdw_is_unique_device(const struct snd_soc_acpi_link_adr *adr_link,
+ unsigned int sdw_version,
+ unsigned int mfg_id,
+ unsigned int part_id,
+ unsigned int class_id,
+ int index_in_link)
+{
+ int i;
+
+ for (i = 0; i < adr_link->num_adr; i++) {
+ unsigned int sdw1_version, mfg1_id, part1_id, class1_id;
+ u64 adr;
+
+ /* skip itself */
+ if (i == index_in_link)
+ continue;
+
+ adr = adr_link->adr_d[i].adr;
+
+ sdw1_version = SDW_VERSION(adr);
+ mfg1_id = SDW_MFG_ID(adr);
+ part1_id = SDW_PART_ID(adr);
+ class1_id = SDW_CLASS_ID(adr);
+
+ if (sdw_version == sdw1_version &&
+ mfg_id == mfg1_id &&
+ part_id == part1_id &&
+ class_id == class1_id)
+ return false;
+ }
+
+ return true;
+}
+
+const char *asoc_sdw_get_codec_name(struct device *dev,
+ const struct asoc_sdw_codec_info *codec_info,
+ const struct snd_soc_acpi_link_adr *adr_link,
+ int adr_index)
+{
+ u64 adr = adr_link->adr_d[adr_index].adr;
+ unsigned int sdw_version = SDW_VERSION(adr);
+ unsigned int link_id = SDW_DISCO_LINK_ID(adr);
+ unsigned int unique_id = SDW_UNIQUE_ID(adr);
+ unsigned int mfg_id = SDW_MFG_ID(adr);
+ unsigned int part_id = SDW_PART_ID(adr);
+ unsigned int class_id = SDW_CLASS_ID(adr);
+
+ if (codec_info->codec_name)
+ return devm_kstrdup(dev, codec_info->codec_name, GFP_KERNEL);
+ else if (asoc_sdw_is_unique_device(adr_link, sdw_version, mfg_id, part_id,
+ class_id, adr_index))
+ return devm_kasprintf(dev, GFP_KERNEL, "sdw:0:%01x:%04x:%04x:%02x",
+ link_id, mfg_id, part_id, class_id);
+ else
+ return devm_kasprintf(dev, GFP_KERNEL, "sdw:0:%01x:%04x:%04x:%02x:%01x",
+ link_id, mfg_id, part_id, class_id, unique_id);
+
+ return NULL;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_get_codec_name, SND_SOC_SDW_UTILS);
+
+/* helper to get the link that the codec DAI is used */
+struct snd_soc_dai_link *asoc_sdw_mc_find_codec_dai_used(struct snd_soc_card *card,
+ const char *dai_name)
+{
+ struct snd_soc_dai_link *dai_link;
+ int i;
+ int j;
+
+ for_each_card_prelinks(card, i, dai_link) {
+ for (j = 0; j < dai_link->num_codecs; j++) {
+ /* Check each codec in a link */
+ if (!strcmp(dai_link->codecs[j].dai_name, dai_name))
+ return dai_link;
+ }
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_mc_find_codec_dai_used, SND_SOC_SDW_UTILS);
+
+void asoc_sdw_mc_dailink_exit_loop(struct snd_soc_card *card)
+{
+ struct snd_soc_dai_link *dai_link;
+ struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+ int ret;
+ int i, j;
+
+ for (i = 0; i < ctx->codec_info_list_count; i++) {
+ for (j = 0; j < codec_info_list[i].dai_num; j++) {
+ codec_info_list[i].dais[j].rtd_init_done = false;
+ /* Check each dai in codec_info_lis to see if it is used in the link */
+ if (!codec_info_list[i].dais[j].exit)
+ continue;
+ /*
+ * We don't need to call .exit function if there is no matched
+ * dai link found.
+ */
+ dai_link = asoc_sdw_mc_find_codec_dai_used(card,
+ codec_info_list[i].dais[j].dai_name);
+ if (dai_link) {
+ /* Do the .exit function if the codec dai is used in the link */
+ ret = codec_info_list[i].dais[j].exit(card, dai_link);
+ if (ret)
+ dev_warn(card->dev,
+ "codec exit failed %d\n",
+ ret);
+ break;
+ }
+ }
+ }
+}
+EXPORT_SYMBOL_NS(asoc_sdw_mc_dailink_exit_loop, SND_SOC_SDW_UTILS);
+
+int asoc_sdw_card_late_probe(struct snd_soc_card *card)
+{
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) {
+ if (codec_info_list[i].codec_card_late_probe) {
+ ret = codec_info_list[i].codec_card_late_probe(card);
+ if (ret < 0)
+ return ret;
+ }
+ }
+ return ret;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_card_late_probe, SND_SOC_SDW_UTILS);
+
+void asoc_sdw_init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
+ int *be_id, char *name, int playback, int capture,
+ struct snd_soc_dai_link_component *cpus, int cpus_num,
+ struct snd_soc_dai_link_component *platform_component,
+ int num_platforms, struct snd_soc_dai_link_component *codecs,
+ int codecs_num, int (*init)(struct snd_soc_pcm_runtime *rtd),
+ const struct snd_soc_ops *ops)
+{
+ dev_dbg(dev, "create dai link %s, id %d\n", name, *be_id);
+ dai_links->id = (*be_id)++;
+ dai_links->name = name;
+ dai_links->platforms = platform_component;
+ dai_links->num_platforms = num_platforms;
+ dai_links->no_pcm = 1;
+ dai_links->cpus = cpus;
+ dai_links->num_cpus = cpus_num;
+ dai_links->codecs = codecs;
+ dai_links->num_codecs = codecs_num;
+ dai_links->dpcm_playback = playback;
+ dai_links->dpcm_capture = capture;
+ dai_links->init = init;
+ dai_links->ops = ops;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_init_dai_link, SND_SOC_SDW_UTILS);
+
+int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
+ int *be_id, char *name, int playback, int capture,
+ const char *cpu_dai_name, const char *platform_comp_name,
+ int num_platforms, const char *codec_name,
+ const char *codec_dai_name,
+ int (*init)(struct snd_soc_pcm_runtime *rtd),
+ const struct snd_soc_ops *ops)
+{
+ struct snd_soc_dai_link_component *dlc;
+
+ /* Allocate three DLCs one for the CPU, one for platform and one for the CODEC */
+ dlc = devm_kcalloc(dev, 3, sizeof(*dlc), GFP_KERNEL);
+ if (!dlc || !name || !cpu_dai_name || !platform_comp_name || !codec_name || !codec_dai_name)
+ return -ENOMEM;
+
+ dlc[0].dai_name = cpu_dai_name;
+ dlc[1].name = platform_comp_name;
+
+ dlc[2].name = codec_name;
+ dlc[2].dai_name = codec_dai_name;
+
+ asoc_sdw_init_dai_link(dev, dai_links, be_id, name, playback, capture,
+ &dlc[0], 1, &dlc[1], num_platforms,
+ &dlc[2], 1, init, ops);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_init_simple_dai_link, SND_SOC_SDW_UTILS);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SoundWire ASoC helpers");
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 7bddfd5e38d6..426632996a0a 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -41,6 +41,7 @@ config SND_SOC_RCAR
depends on COMMON_CLK
depends on OF
select SND_SIMPLE_CARD_UTILS
+ select SND_DMAENGINE_PCM
select REGMAP_MMIO
help
This option enables R-Car SRU/SCU/SSIU/SSI sound support
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index afd69c6eb654..0f190abf00e7 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -262,7 +262,7 @@ int rsnd_adg_set_src_timesel_gen2(struct rsnd_mod *src_mod,
int id = rsnd_mod_id(src_mod);
int shift = (id % 2) ? 16 : 0;
- rsnd_mod_confirm_src(src_mod);
+ rsnd_mod_make_sure(src_mod, RSND_MOD_SRC);
rsnd_adg_get_timesel_ratio(priv, io,
in_rate, out_rate,
@@ -291,7 +291,7 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
int shift = (id % 4) * 8;
u32 mask = 0xFF << shift;
- rsnd_mod_confirm_ssi(ssi_mod);
+ rsnd_mod_make_sure(ssi_mod, RSND_MOD_SSI);
val = val << shift;
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 63b3c8bf0fde..15cb5e7008f9 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -660,23 +660,6 @@ static struct rsnd_dai *rsnd_dai_to_rdai(struct snd_soc_dai *dai)
return rsnd_rdai_get(priv, dai->id);
}
-/*
- * rsnd_soc_dai functions
- */
-void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io)
-{
- struct snd_pcm_substream *substream = io->substream;
-
- /*
- * this function should be called...
- *
- * - if rsnd_dai_pointer_update() returns true
- * - without spin lock
- */
-
- snd_pcm_period_elapsed(substream);
-}
-
static void rsnd_dai_stream_init(struct rsnd_dai_stream *io,
struct snd_pcm_substream *substream)
{
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 7b499eee5080..2342bbb6fe92 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -7,6 +7,7 @@
#include <linux/delay.h>
#include <linux/of_dma.h>
+#include <sound/dmaengine_pcm.h>
#include "rsnd.h"
/*
@@ -22,8 +23,6 @@
struct rsnd_dmaen {
struct dma_chan *chan;
- dma_cookie_t cookie;
- unsigned int dma_len;
};
struct rsnd_dmapp {
@@ -66,20 +65,6 @@ static struct rsnd_mod mem = {
/*
* Audio DMAC
*/
-static void __rsnd_dmaen_complete(struct rsnd_mod *mod,
- struct rsnd_dai_stream *io)
-{
- if (rsnd_io_is_working(io))
- rsnd_dai_period_elapsed(io);
-}
-
-static void rsnd_dmaen_complete(void *data)
-{
- struct rsnd_mod *mod = data;
-
- rsnd_mod_interrupt(mod, __rsnd_dmaen_complete);
-}
-
static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_dai_stream *io,
struct rsnd_mod *mod_from,
struct rsnd_mod *mod_to)
@@ -98,13 +83,7 @@ static int rsnd_dmaen_stop(struct rsnd_mod *mod,
struct rsnd_dai_stream *io,
struct rsnd_priv *priv)
{
- struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
- struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
-
- if (dmaen->chan)
- dmaengine_terminate_async(dmaen->chan);
-
- return 0;
+ return snd_dmaengine_pcm_trigger(io->substream, SNDRV_PCM_TRIGGER_STOP);
}
static int rsnd_dmaen_cleanup(struct rsnd_mod *mod,
@@ -120,7 +99,7 @@ static int rsnd_dmaen_cleanup(struct rsnd_mod *mod,
* Let's call it under prepare
*/
if (dmaen->chan)
- dma_release_channel(dmaen->chan);
+ snd_dmaengine_pcm_close_release_chan(io->substream);
dmaen->chan = NULL;
@@ -153,7 +132,7 @@ static int rsnd_dmaen_prepare(struct rsnd_mod *mod,
return -EIO;
}
- return 0;
+ return snd_dmaengine_pcm_open(io->substream, dmaen->chan);
}
static int rsnd_dmaen_start(struct rsnd_mod *mod,
@@ -162,12 +141,9 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
{
struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
- struct snd_pcm_substream *substream = io->substream;
struct device *dev = rsnd_priv_to_dev(priv);
- struct dma_async_tx_descriptor *desc;
struct dma_slave_config cfg = {};
enum dma_slave_buswidth buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
- int is_play = rsnd_io_is_play(io);
int ret;
/*
@@ -195,7 +171,7 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
}
}
- cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
+ cfg.direction = snd_pcm_substream_to_dma_direction(io->substream);
cfg.src_addr = dma->src_addr;
cfg.dst_addr = dma->dst_addr;
cfg.src_addr_width = buswidth;
@@ -209,32 +185,7 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
if (ret < 0)
return ret;
- desc = dmaengine_prep_dma_cyclic(dmaen->chan,
- substream->runtime->dma_addr,
- snd_pcm_lib_buffer_bytes(substream),
- snd_pcm_lib_period_bytes(substream),
- is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-
- if (!desc) {
- dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
- return -EIO;
- }
-
- desc->callback = rsnd_dmaen_complete;
- desc->callback_param = rsnd_mod_get(dma);
-
- dmaen->dma_len = snd_pcm_lib_buffer_bytes(substream);
-
- dmaen->cookie = dmaengine_submit(desc);
- if (dmaen->cookie < 0) {
- dev_err(dev, "dmaengine_submit() fail\n");
- return -EIO;
- }
-
- dma_async_issue_pending(dmaen->chan);
-
- return 0;
+ return snd_dmaengine_pcm_trigger(io->substream, SNDRV_PCM_TRIGGER_START);
}
struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, char *name,
@@ -307,19 +258,7 @@ static int rsnd_dmaen_pointer(struct rsnd_mod *mod,
struct rsnd_dai_stream *io,
snd_pcm_uframes_t *pointer)
{
- struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
- struct rsnd_dma *dma = rsnd_mod_to_dma(mod);
- struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
- struct dma_tx_state state;
- enum dma_status status;
- unsigned int pos = 0;
-
- status = dmaengine_tx_status(dmaen->chan, dmaen->cookie, &state);
- if (status == DMA_IN_PROGRESS || status == DMA_PAUSED) {
- if (state.residue > 0 && state.residue <= dmaen->dma_len)
- pos = dmaen->dma_len - state.residue;
- }
- *pointer = bytes_to_frames(runtime, pos);
+ *pointer = snd_dmaengine_pcm_pointer(io->substream);
return 0;
}
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index ff294aa2d640..3c164d8e3b16 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -576,7 +576,6 @@ int rsnd_rdai_ssi_lane_ctrl(struct rsnd_dai *rdai,
#define rsnd_rdai_width_get(rdai) \
rsnd_rdai_width_ctrl(rdai, 0)
int rsnd_rdai_width_ctrl(struct rsnd_dai *rdai, int width);
-void rsnd_dai_period_elapsed(struct rsnd_dai_stream *io);
int rsnd_dai_connect(struct rsnd_mod *mod,
struct rsnd_dai_stream *io,
enum rsnd_mod_type type);
@@ -871,15 +870,6 @@ void rsnd_cmd_remove(struct rsnd_priv *priv);
int rsnd_cmd_attach(struct rsnd_dai_stream *io, int id);
void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
-#ifdef DEBUG
-#define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI)
-#define rsnd_mod_confirm_src(msrc) rsnd_mod_make_sure(msrc, RSND_MOD_SRC)
-#define rsnd_mod_confirm_dvc(mdvc) rsnd_mod_make_sure(mdvc, RSND_MOD_DVC)
-#else
-#define rsnd_mod_confirm_ssi(mssi)
-#define rsnd_mod_confirm_src(msrc)
-#define rsnd_mod_confirm_dvc(mdvc)
-#endif
/*
* If you don't need interrupt status debug message,
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 8d2a86383ae0..b3d4e8ae07ef 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -706,7 +706,7 @@ rsnd_ssi_interrupt_out:
spin_unlock(&priv->lock);
if (elapsed)
- rsnd_dai_period_elapsed(io);
+ snd_pcm_period_elapsed(io->substream);
if (stop)
snd_pcm_stop_xrun(io->substream);
diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c
index 9d103646973a..d0bf0487bf1b 100644
--- a/sound/soc/sh/rz-ssi.c
+++ b/sound/soc/sh/rz-ssi.c
@@ -52,6 +52,7 @@
#define SSIFCR_RIE BIT(2)
#define SSIFCR_TFRST BIT(1)
#define SSIFCR_RFRST BIT(0)
+#define SSIFCR_FIFO_RST (SSIFCR_TFRST | SSIFCR_RFRST)
#define SSIFSR_TDC_MASK 0x3f
#define SSIFSR_TDC_SHIFT 24
@@ -130,6 +131,14 @@ struct rz_ssi_priv {
bool lrckp_fsync_fall; /* LR clock polarity (SSICR.LRCKP) */
bool bckp_rise; /* Bit clock polarity (SSICR.BCKP) */
bool dma_rt;
+
+ /* Full duplex communication support */
+ struct {
+ unsigned int rate;
+ unsigned int channels;
+ unsigned int sample_width;
+ unsigned int sample_bits;
+ } hw_params_cache;
};
static void rz_ssi_dma_complete(void *data);
@@ -208,6 +217,11 @@ static bool rz_ssi_stream_is_valid(struct rz_ssi_priv *ssi,
return ret;
}
+static inline bool rz_ssi_is_stream_running(struct rz_ssi_stream *strm)
+{
+ return strm->substream && strm->running;
+}
+
static void rz_ssi_stream_init(struct rz_ssi_stream *strm,
struct snd_pcm_substream *substream)
{
@@ -303,13 +317,53 @@ static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, unsigned int rate,
return 0;
}
+static void rz_ssi_set_idle(struct rz_ssi_priv *ssi)
+{
+ int timeout;
+
+ /* Disable irqs */
+ rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TUIEN | SSICR_TOIEN |
+ SSICR_RUIEN | SSICR_ROIEN, 0);
+ rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_TIE | SSIFCR_RIE, 0);
+
+ /* Clear all error flags */
+ rz_ssi_reg_mask_setl(ssi, SSISR,
+ (SSISR_TOIRQ | SSISR_TUIRQ | SSISR_ROIRQ |
+ SSISR_RUIRQ), 0);
+
+ /* Wait for idle */
+ timeout = 100;
+ while (--timeout) {
+ if (rz_ssi_reg_readl(ssi, SSISR) & SSISR_IIRQ)
+ break;
+ udelay(1);
+ }
+
+ if (!timeout)
+ dev_info(ssi->dev, "timeout waiting for SSI idle\n");
+
+ /* Hold FIFOs in reset */
+ rz_ssi_reg_mask_setl(ssi, SSIFCR, 0,
+ SSIFCR_TFRST | SSIFCR_RFRST);
+}
+
static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
{
bool is_play = rz_ssi_stream_is_play(ssi, strm->substream);
+ bool is_full_duplex;
u32 ssicr, ssifcr;
+ is_full_duplex = rz_ssi_is_stream_running(&ssi->playback) ||
+ rz_ssi_is_stream_running(&ssi->capture);
ssicr = rz_ssi_reg_readl(ssi, SSICR);
- ssifcr = rz_ssi_reg_readl(ssi, SSIFCR) & ~0xF;
+ ssifcr = rz_ssi_reg_readl(ssi, SSIFCR);
+ if (!is_full_duplex) {
+ ssifcr &= ~0xF;
+ } else {
+ rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TEN | SSICR_REN, 0);
+ rz_ssi_set_idle(ssi);
+ ssifcr &= ~SSIFCR_FIFO_RST;
+ }
/* FIFO interrupt thresholds */
if (rz_ssi_is_dma_enabled(ssi))
@@ -322,10 +376,14 @@ static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
/* enable IRQ */
if (is_play) {
ssicr |= SSICR_TUIEN | SSICR_TOIEN;
- ssifcr |= SSIFCR_TIE | SSIFCR_RFRST;
+ ssifcr |= SSIFCR_TIE;
+ if (!is_full_duplex)
+ ssifcr |= SSIFCR_RFRST;
} else {
ssicr |= SSICR_RUIEN | SSICR_ROIEN;
- ssifcr |= SSIFCR_RIE | SSIFCR_TFRST;
+ ssifcr |= SSIFCR_RIE;
+ if (!is_full_duplex)
+ ssifcr |= SSIFCR_TFRST;
}
rz_ssi_reg_writel(ssi, SSICR, ssicr);
@@ -337,7 +395,11 @@ static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
SSISR_RUIRQ), 0);
strm->running = 1;
- ssicr |= is_play ? SSICR_TEN : SSICR_REN;
+ if (is_full_duplex)
+ ssicr |= SSICR_TEN | SSICR_REN;
+ else
+ ssicr |= is_play ? SSICR_TEN : SSICR_REN;
+
rz_ssi_reg_writel(ssi, SSICR, ssicr);
return 0;
@@ -345,10 +407,12 @@ static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
{
- int timeout;
-
strm->running = 0;
+ if (rz_ssi_is_stream_running(&ssi->playback) ||
+ rz_ssi_is_stream_running(&ssi->capture))
+ return 0;
+
/* Disable TX/RX */
rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TEN | SSICR_REN, 0);
@@ -356,30 +420,7 @@ static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
if (rz_ssi_is_dma_enabled(ssi))
dmaengine_terminate_async(strm->dma_ch);
- /* Disable irqs */
- rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TUIEN | SSICR_TOIEN |
- SSICR_RUIEN | SSICR_ROIEN, 0);
- rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_TIE | SSIFCR_RIE, 0);
-
- /* Clear all error flags */
- rz_ssi_reg_mask_setl(ssi, SSISR,
- (SSISR_TOIRQ | SSISR_TUIRQ | SSISR_ROIRQ |
- SSISR_RUIRQ), 0);
-
- /* Wait for idle */
- timeout = 100;
- while (--timeout) {
- if (rz_ssi_reg_readl(ssi, SSISR) & SSISR_IIRQ)
- break;
- udelay(1);
- }
-
- if (!timeout)
- dev_info(ssi->dev, "timeout waiting for SSI idle\n");
-
- /* Hold FIFOs in reset */
- rz_ssi_reg_mask_setl(ssi, SSIFCR, 0,
- SSIFCR_TFRST | SSIFCR_RFRST);
+ rz_ssi_set_idle(ssi);
return 0;
}
@@ -512,66 +553,90 @@ static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
static irqreturn_t rz_ssi_interrupt(int irq, void *data)
{
- struct rz_ssi_stream *strm = NULL;
+ struct rz_ssi_stream *strm_playback = NULL;
+ struct rz_ssi_stream *strm_capture = NULL;
struct rz_ssi_priv *ssi = data;
u32 ssisr = rz_ssi_reg_readl(ssi, SSISR);
if (ssi->playback.substream)
- strm = &ssi->playback;
- else if (ssi->capture.substream)
- strm = &ssi->capture;
- else
+ strm_playback = &ssi->playback;
+ if (ssi->capture.substream)
+ strm_capture = &ssi->capture;
+
+ if (!strm_playback && !strm_capture)
return IRQ_HANDLED; /* Left over TX/RX interrupt */
if (irq == ssi->irq_int) { /* error or idle */
- if (ssisr & SSISR_TUIRQ)
- strm->uerr_num++;
- if (ssisr & SSISR_TOIRQ)
- strm->oerr_num++;
- if (ssisr & SSISR_RUIRQ)
- strm->uerr_num++;
- if (ssisr & SSISR_ROIRQ)
- strm->oerr_num++;
-
- if (ssisr & (SSISR_TUIRQ | SSISR_TOIRQ | SSISR_RUIRQ |
- SSISR_ROIRQ)) {
- /* Error handling */
- /* You must reset (stop/restart) after each interrupt */
- rz_ssi_stop(ssi, strm);
-
- /* Clear all flags */
- rz_ssi_reg_mask_setl(ssi, SSISR, SSISR_TOIRQ |
- SSISR_TUIRQ | SSISR_ROIRQ |
- SSISR_RUIRQ, 0);
-
- /* Add/remove more data */
- strm->transfer(ssi, strm);
-
- /* Resume */
- rz_ssi_start(ssi, strm);
+ bool is_stopped = false;
+ int i, count;
+
+ if (rz_ssi_is_dma_enabled(ssi))
+ count = 4;
+ else
+ count = 1;
+
+ if (ssisr & (SSISR_RUIRQ | SSISR_ROIRQ | SSISR_TUIRQ | SSISR_TOIRQ))
+ is_stopped = true;
+
+ if (ssi->capture.substream && is_stopped) {
+ if (ssisr & SSISR_RUIRQ)
+ strm_capture->uerr_num++;
+ if (ssisr & SSISR_ROIRQ)
+ strm_capture->oerr_num++;
+
+ rz_ssi_stop(ssi, strm_capture);
}
+
+ if (ssi->playback.substream && is_stopped) {
+ if (ssisr & SSISR_TUIRQ)
+ strm_playback->uerr_num++;
+ if (ssisr & SSISR_TOIRQ)
+ strm_playback->oerr_num++;
+
+ rz_ssi_stop(ssi, strm_playback);
+ }
+
+ /* Clear all flags */
+ rz_ssi_reg_mask_setl(ssi, SSISR, SSISR_TOIRQ | SSISR_TUIRQ |
+ SSISR_ROIRQ | SSISR_RUIRQ, 0);
+
+ /* Add/remove more data */
+ if (ssi->capture.substream && is_stopped) {
+ for (i = 0; i < count; i++)
+ strm_capture->transfer(ssi, strm_capture);
+ }
+
+ if (ssi->playback.substream && is_stopped) {
+ for (i = 0; i < count; i++)
+ strm_playback->transfer(ssi, strm_playback);
+ }
+
+ /* Resume */
+ if (ssi->playback.substream && is_stopped)
+ rz_ssi_start(ssi, &ssi->playback);
+ if (ssi->capture.substream && is_stopped)
+ rz_ssi_start(ssi, &ssi->capture);
}
- if (!strm->running)
+ if (!rz_ssi_is_stream_running(&ssi->playback) &&
+ !rz_ssi_is_stream_running(&ssi->capture))
return IRQ_HANDLED;
/* tx data empty */
- if (irq == ssi->irq_tx)
- strm->transfer(ssi, &ssi->playback);
+ if (irq == ssi->irq_tx && rz_ssi_is_stream_running(&ssi->playback))
+ strm_playback->transfer(ssi, &ssi->playback);
/* rx data full */
- if (irq == ssi->irq_rx) {
- strm->transfer(ssi, &ssi->capture);
+ if (irq == ssi->irq_rx && rz_ssi_is_stream_running(&ssi->capture)) {
+ strm_capture->transfer(ssi, &ssi->capture);
rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
}
if (irq == ssi->irq_rt) {
- struct snd_pcm_substream *substream = strm->substream;
-
- if (rz_ssi_stream_is_play(ssi, substream)) {
- strm->transfer(ssi, &ssi->playback);
+ if (ssi->playback.substream) {
+ strm_playback->transfer(ssi, &ssi->playback);
} else {
- strm->transfer(ssi, &ssi->capture);
+ strm_capture->transfer(ssi, &ssi->capture);
rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
}
}
@@ -731,9 +796,12 @@ static int rz_ssi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
/* Soft Reset */
- rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, SSIFCR_SSIRST);
- rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, 0);
- udelay(5);
+ if (!rz_ssi_is_stream_running(&ssi->playback) &&
+ !rz_ssi_is_stream_running(&ssi->capture)) {
+ rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, SSIFCR_SSIRST);
+ rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, 0);
+ udelay(5);
+ }
rz_ssi_stream_init(strm, substream);
@@ -824,14 +892,41 @@ static int rz_ssi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return 0;
}
+static bool rz_ssi_is_valid_hw_params(struct rz_ssi_priv *ssi, unsigned int rate,
+ unsigned int channels,
+ unsigned int sample_width,
+ unsigned int sample_bits)
+{
+ if (ssi->hw_params_cache.rate != rate ||
+ ssi->hw_params_cache.channels != channels ||
+ ssi->hw_params_cache.sample_width != sample_width ||
+ ssi->hw_params_cache.sample_bits != sample_bits)
+ return false;
+
+ return true;
+}
+
+static void rz_ssi_cache_hw_params(struct rz_ssi_priv *ssi, unsigned int rate,
+ unsigned int channels,
+ unsigned int sample_width,
+ unsigned int sample_bits)
+{
+ ssi->hw_params_cache.rate = rate;
+ ssi->hw_params_cache.channels = channels;
+ ssi->hw_params_cache.sample_width = sample_width;
+ ssi->hw_params_cache.sample_bits = sample_bits;
+}
+
static int rz_ssi_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai);
+ struct rz_ssi_stream *strm = rz_ssi_stream_get(ssi, substream);
unsigned int sample_bits = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
unsigned int channels = params_channels(params);
+ unsigned int rate = params_rate(params);
if (sample_bits != 16) {
dev_err(ssi->dev, "Unsupported sample width: %d\n",
@@ -845,8 +940,20 @@ static int rz_ssi_dai_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- return rz_ssi_clk_setup(ssi, params_rate(params),
- params_channels(params));
+ if (rz_ssi_is_stream_running(&ssi->playback) ||
+ rz_ssi_is_stream_running(&ssi->capture)) {
+ if (rz_ssi_is_valid_hw_params(ssi, rate, channels,
+ strm->sample_width, sample_bits))
+ return 0;
+
+ dev_err(ssi->dev, "Full duplex needs same HW params\n");
+ return -EINVAL;
+ }
+
+ rz_ssi_cache_hw_params(ssi, rate, channels, strm->sample_width,
+ sample_bits);
+
+ return rz_ssi_clk_setup(ssi, rate, channels);
}
static const struct snd_soc_dai_ops rz_ssi_dai_ops = {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 724fe1f033b5..20248a29d167 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -326,8 +326,8 @@ static int snd_soc_rtd_add_component(struct snd_soc_pcm_runtime *rtd,
}
/* see for_each_rtd_components */
- rtd->components[rtd->num_components] = component;
- rtd->num_components++;
+ rtd->num_components++; // increment flex array count at first
+ rtd->components[rtd->num_components - 1] = component;
return 0;
}
@@ -494,7 +494,6 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
{
struct snd_soc_pcm_runtime *rtd;
- struct snd_soc_component *component;
struct device *dev;
int ret;
int stream;
@@ -521,10 +520,10 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
* for rtd
*/
rtd = devm_kzalloc(dev,
- sizeof(*rtd) +
- sizeof(component) * (dai_link->num_cpus +
- dai_link->num_codecs +
- dai_link->num_platforms),
+ struct_size(rtd, components,
+ dai_link->num_cpus +
+ dai_link->num_codecs +
+ dai_link->num_platforms),
GFP_KERNEL);
if (!rtd) {
device_unregister(dev);
@@ -3372,10 +3371,10 @@ unsigned int snd_soc_daifmt_parse_format(struct device_node *np,
* SND_SOC_DAIFMT_INV_MASK area
*/
snprintf(prop, sizeof(prop), "%sbitclock-inversion", prefix);
- bit = !!of_get_property(np, prop, NULL);
+ bit = of_property_read_bool(np, prop);
snprintf(prop, sizeof(prop), "%sframe-inversion", prefix);
- frame = !!of_get_property(np, prop, NULL);
+ frame = of_property_read_bool(np, prop);
switch ((bit << 4) + frame) {
case 0x11:
@@ -3412,12 +3411,12 @@ unsigned int snd_soc_daifmt_parse_clock_provider_raw(struct device_node *np,
* check "[prefix]frame-master"
*/
snprintf(prop, sizeof(prop), "%sbitclock-master", prefix);
- bit = !!of_get_property(np, prop, NULL);
+ bit = of_property_read_bool(np, prop);
if (bit && bitclkmaster)
*bitclkmaster = of_parse_phandle(np, prop, 0);
snprintf(prop, sizeof(prop), "%sframe-master", prefix);
- frame = !!of_get_property(np, prop, NULL);
+ frame = of_property_read_bool(np, prop);
if (frame && framemaster)
*framemaster = of_parse_phandle(np, prop, 0);
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index 9e47053419c1..302ca753a1f3 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -685,26 +685,6 @@ int snd_soc_pcm_dai_trigger(struct snd_pcm_substream *substream,
return ret;
}
-int snd_soc_pcm_dai_bespoke_trigger(struct snd_pcm_substream *substream,
- int cmd)
-{
- struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
- struct snd_soc_dai *dai;
- int i, ret;
-
- for_each_rtd_dais(rtd, i, dai) {
- if (dai->driver->ops &&
- dai->driver->ops->bespoke_trigger) {
- ret = dai->driver->ops->bespoke_trigger(substream,
- cmd, dai);
- if (ret < 0)
- return soc_dai_ret(dai, ret);
- }
- }
-
- return 0;
-}
-
void snd_soc_pcm_dai_delay(struct snd_pcm_substream *substream,
snd_pcm_sframes_t *cpu_delay,
snd_pcm_sframes_t *codec_delay)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 37dccd9c1ba0..d7d6dbb9d9ea 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -2751,8 +2751,7 @@ static int dapm_update_dai_unlocked(struct snd_pcm_substream *substream,
if (!w)
return 0;
- dev_dbg(dai->dev, "Update DAI routes for %s %s\n", dai->name,
- dir == SNDRV_PCM_STREAM_PLAYBACK ? "playback" : "capture");
+ dev_dbg(dai->dev, "Update DAI routes for %s %s\n", dai->name, snd_pcm_direction_name(dir));
snd_soc_dapm_widget_for_each_sink_path(w, p) {
ret = dapm_update_dai_chan(p, p->sink, channels);
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index bad823718ae4..1edcb8d6f6ee 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -222,7 +222,7 @@ static void dpcm_create_debugfs_state(struct snd_soc_dpcm *dpcm, int stream)
char *name;
name = kasprintf(GFP_KERNEL, "%s:%s", dpcm->be->dai_link->name,
- stream ? "capture" : "playback");
+ snd_pcm_direction_name(stream));
if (name) {
dpcm->debugfs_state = debugfs_create_dir(
name, dpcm->fe->debugfs_dpcm_root);
@@ -1278,7 +1278,7 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
snd_soc_dpcm_stream_unlock_irq(fe, stream);
dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n",
- stream ? "capture" : "playback", fe->dai_link->name,
+ snd_pcm_direction_name(stream), fe->dai_link->name,
stream ? "<-" : "->", be->dai_link->name);
dpcm_create_debugfs_state(dpcm, stream);
@@ -1306,7 +1306,7 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
continue;
dev_dbg(fe->dev, "reparent %s path %s %s %s\n",
- stream ? "capture" : "playback",
+ snd_pcm_direction_name(stream),
dpcm->fe->dai_link->name,
stream ? "<-" : "->", dpcm->be->dai_link->name);
@@ -1327,14 +1327,14 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
snd_soc_dpcm_stream_lock_irq(fe, stream);
for_each_dpcm_be_safe(fe, stream, dpcm, d) {
dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n",
- stream ? "capture" : "playback",
+ snd_pcm_direction_name(stream),
dpcm->be->dai_link->name);
if (dpcm->state != SND_SOC_DPCM_LINK_STATE_FREE)
continue;
dev_dbg(fe->dev, "freed DSP %s path %s %s %s\n",
- stream ? "capture" : "playback", fe->dai_link->name,
+ snd_pcm_direction_name(stream), fe->dai_link->name,
stream ? "<-" : "->", dpcm->be->dai_link->name);
/* BEs still alive need new FE */
@@ -1441,10 +1441,10 @@ int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
if (paths > 0)
dev_dbg(fe->dev, "ASoC: found %d audio %s paths\n", paths,
- stream ? "capture" : "playback");
+ snd_pcm_direction_name(stream));
else if (paths == 0)
dev_dbg(fe->dev, "ASoC: %s no valid %s path\n", fe->dai_link->name,
- stream ? "capture" : "playback");
+ snd_pcm_direction_name(stream));
return paths;
}
@@ -1487,7 +1487,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
continue;
dev_dbg(fe->dev, "ASoC: pruning %s BE %s for %s\n",
- stream ? "capture" : "playback",
+ snd_pcm_direction_name(stream),
dpcm->be->dai_link->name, fe->dai_link->name);
dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
dpcm_set_be_update_state(dpcm->be, stream, SND_SOC_DPCM_UPDATE_BE);
@@ -1605,7 +1605,7 @@ void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream,
if (be->dpcm[stream].users == 0) {
dev_err(be->dev, "ASoC: no users %s at close - state %d\n",
- stream ? "capture" : "playback",
+ snd_pcm_direction_name(stream),
be->dpcm[stream].state);
continue;
}
@@ -1645,7 +1645,7 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
if (!be_substream) {
dev_err(be->dev, "ASoC: no backend %s stream\n",
- stream ? "capture" : "playback");
+ snd_pcm_direction_name(stream));
continue;
}
@@ -1656,7 +1656,7 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
/* first time the dpcm is open ? */
if (be->dpcm[stream].users == DPCM_MAX_BE_USERS) {
dev_err(be->dev, "ASoC: too many users %s at open %d\n",
- stream ? "capture" : "playback",
+ snd_pcm_direction_name(stream),
be->dpcm[stream].state);
continue;
}
@@ -1669,7 +1669,7 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
continue;
dev_dbg(be->dev, "ASoC: open %s BE %s\n",
- stream ? "capture" : "playback", be->dai_link->name);
+ snd_pcm_direction_name(stream), be->dai_link->name);
be_substream->runtime = fe_substream->runtime;
err = __soc_pcm_open(be, be_substream);
@@ -1677,7 +1677,7 @@ int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
be->dpcm[stream].users--;
if (be->dpcm[stream].users < 0)
dev_err(be->dev, "ASoC: no users %s at unwind %d\n",
- stream ? "capture" : "playback",
+ snd_pcm_direction_name(stream),
be->dpcm[stream].state);
be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
@@ -2388,14 +2388,6 @@ static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd)
break;
}
break;
- case SND_SOC_DPCM_TRIGGER_BESPOKE:
- /* bespoke trigger() - handles both FE and BEs */
-
- dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd %d\n",
- fe->dai_link->name, cmd);
-
- ret = snd_soc_pcm_dai_bespoke_trigger(substream, cmd);
- break;
default:
dev_err(fe->dev, "ASoC: invalid trigger cmd %d for %s\n", cmd,
fe->dai_link->name);
@@ -2525,26 +2517,12 @@ out:
static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
{
- struct snd_pcm_substream *substream =
- snd_soc_dpcm_get_substream(fe, stream);
- enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
int err;
dev_dbg(fe->dev, "ASoC: runtime %s close on FE %s\n",
- stream ? "capture" : "playback", fe->dai_link->name);
+ snd_pcm_direction_name(stream), fe->dai_link->name);
- if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) {
- /* call bespoke trigger - FE takes care of all BE triggers */
- dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd stop\n",
- fe->dai_link->name);
-
- err = snd_soc_pcm_dai_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_STOP);
- } else {
- dev_dbg(fe->dev, "ASoC: trigger FE %s cmd stop\n",
- fe->dai_link->name);
-
- err = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_STOP);
- }
+ err = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_STOP);
dpcm_be_dai_hw_free(fe, stream);
@@ -2558,14 +2536,11 @@ static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
{
- struct snd_pcm_substream *substream =
- snd_soc_dpcm_get_substream(fe, stream);
struct snd_soc_dpcm *dpcm;
- enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
int ret = 0;
dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n",
- stream ? "capture" : "playback", fe->dai_link->name);
+ snd_pcm_direction_name(stream), fe->dai_link->name);
/* Only start the BE if the FE is ready */
if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_HW_FREE ||
@@ -2605,23 +2580,9 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
fe->dpcm[stream].state == SND_SOC_DPCM_STATE_STOP)
return 0;
- if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) {
- /* call trigger on the frontend - FE takes care of all BE triggers */
- dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd start\n",
- fe->dai_link->name);
-
- ret = snd_soc_pcm_dai_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START);
- if (ret < 0)
- goto hw_free;
- } else {
- dev_dbg(fe->dev, "ASoC: trigger FE %s cmd start\n",
- fe->dai_link->name);
-
- ret = dpcm_be_dai_trigger(fe, stream,
- SNDRV_PCM_TRIGGER_START);
- if (ret < 0)
- goto hw_free;
- }
+ ret = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_START);
+ if (ret < 0)
+ goto hw_free;
return 0;
diff --git a/sound/soc/sof/amd/Kconfig b/sound/soc/sof/amd/Kconfig
index 2729c6eb3feb..848c031ed5fb 100644
--- a/sound/soc/sof/amd/Kconfig
+++ b/sound/soc/sof/amd/Kconfig
@@ -23,6 +23,7 @@ config SND_SOC_SOF_AMD_COMMON
select SND_AMD_ACP_CONFIG
select SND_SOC_SOF_XTENSA
select SND_SOC_SOF_ACP_PROBES
+ select SND_SOC_ACPI_AMD_MATCH
select SND_SOC_ACPI if ACPI
help
This option is not user-selectable but automatically handled by
diff --git a/sound/soc/sof/amd/acp-common.c b/sound/soc/sof/amd/acp-common.c
index 81bb93e98358..dbcaac84cb73 100644
--- a/sound/soc/sof/amd/acp-common.c
+++ b/sound/soc/sof/amd/acp-common.c
@@ -153,6 +153,7 @@ static struct snd_soc_acpi_mach *amd_sof_sdw_machine_select(struct snd_sof_dev *
break;
}
if (mach && mach->link_mask) {
+ mach->mach_params.subsystem_rev = acp_data->pci_rev;
mach->mach_params.links = mach->links;
mach->mach_params.link_mask = mach->link_mask;
mach->mach_params.platform = dev_name(sdev->dev);
@@ -173,6 +174,7 @@ static struct snd_soc_acpi_mach *amd_sof_sdw_machine_select(struct snd_sof_dev *
struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev)
{
struct snd_sof_pdata *sof_pdata = sdev->pdata;
+ struct acp_dev_data *acp_data = sdev->pdata->hw_pdata;
const struct sof_dev_desc *desc = sof_pdata->desc;
struct snd_soc_acpi_mach *mach = NULL;
@@ -186,6 +188,7 @@ struct snd_soc_acpi_mach *amd_sof_machine_select(struct snd_sof_dev *sdev)
}
}
+ mach->mach_params.subsystem_rev = acp_data->pci_rev;
sof_pdata->tplg_filename = mach->sof_tplg_filename;
sof_pdata->fw_filename = mach->fw_filename;
diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
index 74fd5f2b148b..7b122656efd1 100644
--- a/sound/soc/sof/amd/acp.c
+++ b/sound/soc/sof/amd/acp.c
@@ -695,6 +695,7 @@ int amd_sof_acp_probe(struct snd_sof_dev *sdev)
pci_set_master(pci);
adata->addr = addr;
adata->reg_range = chip->reg_end_addr - chip->reg_start_addr;
+ adata->pci_rev = pci->revision;
mutex_init(&adata->acp_lock);
sdev->pdata->hw_pdata = adata;
adata->smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, chip->host_bridge_id, NULL);
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index 87e79d500865..ec9170b3f068 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -251,6 +251,7 @@ struct acp_dev_data {
bool is_dram_in_use;
bool is_sram_in_use;
bool sdw_en_stat;
+ unsigned int pci_rev;
};
void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src, size_t bytes);
diff --git a/sound/soc/sof/amd/pci-acp63.c b/sound/soc/sof/amd/pci-acp63.c
index fc8984447365..54d42f83ce9e 100644
--- a/sound/soc/sof/amd/pci-acp63.c
+++ b/sound/soc/sof/amd/pci-acp63.c
@@ -48,6 +48,7 @@ static const struct sof_amd_acp_desc acp63_chip_info = {
static const struct sof_dev_desc acp63_desc = {
.machines = snd_soc_acpi_amd_acp63_sof_machines,
+ .alt_machines = snd_soc_acpi_amd_acp63_sof_sdw_machines,
.resindex_lpe_base = 0,
.resindex_pcicfg_base = -1,
.resindex_imr_base = -1,
diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig
index 3396bd46b778..2c43558d96b9 100644
--- a/sound/soc/sof/intel/Kconfig
+++ b/sound/soc/sof/intel/Kconfig
@@ -281,6 +281,23 @@ config SND_SOC_SOF_LUNARLAKE
Say Y if you have such a device.
If unsure select "N".
+config SND_SOC_SOF_INTEL_PTL
+ tristate
+ select SND_SOC_SOF_HDA_COMMON
+ select SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
+ select SND_SOC_SOF_IPC4
+ select SND_SOC_SOF_INTEL_LNL
+
+config SND_SOC_SOF_PANTHERLAKE
+ tristate "SOF support for Pantherlake"
+ default SND_SOC_SOF_PCI
+ select SND_SOC_SOF_INTEL_PTL
+ help
+ This adds support for Sound Open Firmware for Intel(R) platforms
+ using the Pantherlake processors.
+ Say Y if you have such a device.
+ If unsure select "N".
+
config SND_SOC_SOF_HDA_COMMON
tristate
diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile
index b56fa5530b8b..f40daa616803 100644
--- a/sound/soc/sof/intel/Makefile
+++ b/sound/soc/sof/intel/Makefile
@@ -34,6 +34,7 @@ snd-sof-pci-intel-icl-y := pci-icl.o icl.o
snd-sof-pci-intel-tgl-y := pci-tgl.o tgl.o
snd-sof-pci-intel-mtl-y := pci-mtl.o mtl.o
snd-sof-pci-intel-lnl-y := pci-lnl.o lnl.o
+snd-sof-pci-intel-ptl-y := pci-ptl.o
obj-$(CONFIG_SND_SOC_SOF_MERRIFIELD) += snd-sof-pci-intel-tng.o
obj-$(CONFIG_SND_SOC_SOF_INTEL_SKL) += snd-sof-pci-intel-skl.o
@@ -43,3 +44,4 @@ obj-$(CONFIG_SND_SOC_SOF_INTEL_ICL) += snd-sof-pci-intel-icl.o
obj-$(CONFIG_SND_SOC_SOF_INTEL_TGL) += snd-sof-pci-intel-tgl.o
obj-$(CONFIG_SND_SOC_SOF_INTEL_MTL) += snd-sof-pci-intel-mtl.o
obj-$(CONFIG_SND_SOC_SOF_INTEL_LNL) += snd-sof-pci-intel-lnl.o
+obj-$(CONFIG_SND_SOC_SOF_INTEL_PTL) += snd-sof-pci-intel-ptl.o
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index 1315f5bc3e31..4c88522d4048 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -69,6 +69,7 @@ static void hda_get_interfaces(struct snd_sof_dev *sdev, u32 *interface_mask)
interface_mask[SOF_DAI_HOST_ACCESS] = BIT(SOF_DAI_INTEL_HDA);
break;
case SOF_INTEL_ACE_2_0:
+ case SOF_INTEL_ACE_3_0:
interface_mask[SOF_DAI_DSP_ACCESS] =
BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) |
BIT(SOF_DAI_INTEL_HDA) | BIT(SOF_DAI_INTEL_ALH);
diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index 8213debde497..3ac63ce67ab1 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -216,9 +216,7 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags)
/* stream found ? */
if (!hext_stream) {
- dev_err(sdev->dev, "error: no free %s streams\n",
- direction == SNDRV_PCM_STREAM_PLAYBACK ?
- "playback" : "capture");
+ dev_err(sdev->dev, "error: no free %s streams\n", snd_pcm_direction_name(direction));
return hext_stream;
}
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 3c9e1d59e1ab..b74a472435b5 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -920,6 +920,7 @@ extern const struct sof_intel_dsp_desc adls_chip_info;
extern const struct sof_intel_dsp_desc mtl_chip_info;
extern const struct sof_intel_dsp_desc arl_s_chip_info;
extern const struct sof_intel_dsp_desc lnl_chip_info;
+extern const struct sof_intel_dsp_desc ptl_chip_info;
/* Probes support */
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
diff --git a/sound/soc/sof/intel/lnl.c b/sound/soc/sof/intel/lnl.c
index 4b5665f82170..3d5a1f8b17e5 100644
--- a/sound/soc/sof/intel/lnl.c
+++ b/sound/soc/sof/intel/lnl.c
@@ -22,6 +22,7 @@
/* LunarLake ops */
struct snd_sof_dsp_ops sof_lnl_ops;
+EXPORT_SYMBOL_NS(sof_lnl_ops, SND_SOC_SOF_INTEL_LNL);
static const struct snd_sof_debugfs_map lnl_dsp_debugfs[] = {
{"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS},
@@ -181,6 +182,7 @@ int sof_lnl_ops_init(struct snd_sof_dev *sdev)
return 0;
};
+EXPORT_SYMBOL_NS(sof_lnl_ops_init, SND_SOC_SOF_INTEL_LNL);
/* Check if an SDW IRQ occurred */
static bool lnl_dsp_check_sdw_irq(struct snd_sof_dev *sdev)
@@ -245,3 +247,28 @@ const struct sof_intel_dsp_desc lnl_chip_info = {
.disable_interrupts = lnl_dsp_disable_interrupts,
.hw_ip_version = SOF_INTEL_ACE_2_0,
};
+
+const struct sof_intel_dsp_desc ptl_chip_info = {
+ .cores_num = 5,
+ .init_core_mask = BIT(0),
+ .host_managed_cores_mask = BIT(0),
+ .ipc_req = MTL_DSP_REG_HFIPCXIDR,
+ .ipc_req_mask = MTL_DSP_REG_HFIPCXIDR_BUSY,
+ .ipc_ack = MTL_DSP_REG_HFIPCXIDA,
+ .ipc_ack_mask = MTL_DSP_REG_HFIPCXIDA_DONE,
+ .ipc_ctl = MTL_DSP_REG_HFIPCXCTL,
+ .rom_status_reg = LNL_DSP_REG_HFDSC,
+ .rom_init_timeout = 300,
+ .ssp_count = MTL_SSP_COUNT,
+ .d0i3_offset = MTL_HDA_VS_D0I3C,
+ .read_sdw_lcount = hda_sdw_check_lcount_ext,
+ .enable_sdw_irq = lnl_enable_sdw_irq,
+ .check_sdw_irq = lnl_dsp_check_sdw_irq,
+ .check_sdw_wakeen_irq = lnl_sdw_check_wakeen_irq,
+ .check_ipc_irq = mtl_dsp_check_ipc_irq,
+ .cl_init = mtl_dsp_cl_init,
+ .power_down_dsp = mtl_power_down_dsp,
+ .disable_interrupts = lnl_dsp_disable_interrupts,
+ .hw_ip_version = SOF_INTEL_ACE_3_0,
+};
+EXPORT_SYMBOL_NS(ptl_chip_info, SND_SOC_SOF_INTEL_LNL);
diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c
index 1bf274509ee6..2b9d22ccf345 100644
--- a/sound/soc/sof/intel/mtl.c
+++ b/sound/soc/sof/intel/mtl.c
@@ -245,6 +245,18 @@ int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev)
u32 cpa;
u32 pgs;
int ret;
+ u32 dsppwrctl;
+ u32 dsppwrsts;
+ const struct sof_intel_dsp_desc *chip;
+
+ chip = get_chip_info(sdev->pdata);
+ if (chip->hw_ip_version > SOF_INTEL_ACE_2_0) {
+ dsppwrctl = PTL_HFPWRCTL2;
+ dsppwrsts = PTL_HFPWRSTS2;
+ } else {
+ dsppwrctl = MTL_HFPWRCTL;
+ dsppwrsts = MTL_HFPWRSTS;
+ }
/* Set the DSP subsystem power on */
snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFDSSCS,
@@ -264,14 +276,14 @@ int mtl_dsp_pre_fw_run(struct snd_sof_dev *sdev)
}
/* Power up gated-DSP-0 domain in order to access the DSP shim register block. */
- snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, MTL_HFPWRCTL,
+ snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, dsppwrctl,
MTL_HFPWRCTL_WPDSPHPXPG, MTL_HFPWRCTL_WPDSPHPXPG);
usleep_range(1000, 1010);
/* poll with timeout to check if operation successful */
pgs = MTL_HFPWRSTS_DSPHPXPGS_MASK;
- ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, MTL_HFPWRSTS, dsphfpwrsts,
+ ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, dsppwrsts, dsphfpwrsts,
(dsphfpwrsts & pgs) == pgs,
HDA_DSP_REG_POLL_INTERVAL_US,
HDA_DSP_RESET_TIMEOUT_US);
diff --git a/sound/soc/sof/intel/mtl.h b/sound/soc/sof/intel/mtl.h
index 7acaa7e724f4..9ab4b21c960e 100644
--- a/sound/soc/sof/intel/mtl.h
+++ b/sound/soc/sof/intel/mtl.h
@@ -12,9 +12,11 @@
#define MTL_HFDSSCS_CPA_MASK BIT(24)
#define MTL_HFSNDWIE 0x114C
#define MTL_HFPWRCTL 0x1D18
+#define PTL_HFPWRCTL2 0x1D20
#define MTL_HfPWRCTL_WPIOXPG(x) BIT((x) + 8)
#define MTL_HFPWRCTL_WPDSPHPXPG BIT(0)
#define MTL_HFPWRSTS 0x1D1C
+#define PTL_HFPWRSTS2 0x1D24
#define MTL_HFPWRSTS_DSPHPXPGS_MASK BIT(0)
#define MTL_HFINTIPPTR 0x1108
#define MTL_IRQ_INTEN_L_HOST_IPC_MASK BIT(0)
diff --git a/sound/soc/sof/intel/pci-ptl.c b/sound/soc/sof/intel/pci-ptl.c
new file mode 100644
index 000000000000..69195b5e7b1a
--- /dev/null
+++ b/sound/soc/sof/intel/pci-ptl.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2024 Intel Corporation.
+//
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <sound/soc-acpi.h>
+#include <sound/soc-acpi-intel-match.h>
+#include <sound/sof.h>
+#include "../ops.h"
+#include "../sof-pci-dev.h"
+
+/* platform specific devices */
+#include "hda.h"
+#include "mtl.h"
+
+static const struct sof_dev_desc ptl_desc = {
+ .use_acpi_target_states = true,
+ .machines = snd_soc_acpi_intel_ptl_machines,
+ .alt_machines = snd_soc_acpi_intel_ptl_sdw_machines,
+ .resindex_lpe_base = 0,
+ .resindex_pcicfg_base = -1,
+ .resindex_imr_base = -1,
+ .irqindex_host_ipc = -1,
+ .chip_info = &ptl_chip_info,
+ .ipc_supported_mask = BIT(SOF_IPC_TYPE_4),
+ .ipc_default = SOF_IPC_TYPE_4,
+ .dspless_mode_supported = true,
+ .default_fw_path = {
+ [SOF_IPC_TYPE_4] = "intel/sof-ipc4/ptl",
+ },
+ .default_lib_path = {
+ [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/ptl",
+ },
+ .default_tplg_path = {
+ [SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg",
+ },
+ .default_fw_filename = {
+ [SOF_IPC_TYPE_4] = "sof-ptl.ri",
+ },
+ .nocodec_tplg_filename = "sof-ptl-nocodec.tplg",
+ .ops = &sof_lnl_ops,
+ .ops_init = sof_lnl_ops_init,
+};
+
+/* PCI IDs */
+static const struct pci_device_id sof_pci_ids[] = {
+ { PCI_DEVICE_DATA(INTEL, HDA_PTL, &ptl_desc) }, /* PTL */
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, sof_pci_ids);
+
+/* pci_driver definition */
+static struct pci_driver snd_sof_pci_intel_ptl_driver = {
+ .name = "sof-audio-pci-intel-ptl",
+ .id_table = sof_pci_ids,
+ .probe = hda_pci_intel_probe,
+ .remove = sof_pci_remove,
+ .shutdown = sof_pci_shutdown,
+ .driver = {
+ .pm = &sof_pci_pm,
+ },
+};
+module_pci_driver(snd_sof_pci_intel_ptl_driver);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("SOF support for PantherLake platforms");
+MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_GENERIC);
+MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON);
+MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_LNL);
+MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_MTL);
+MODULE_IMPORT_NS(SND_SOC_SOF_HDA_MLINK);
+MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV);
diff --git a/sound/soc/sof/intel/shim.h b/sound/soc/sof/intel/shim.h
index 9328d2bbfd03..8709b750a11e 100644
--- a/sound/soc/sof/intel/shim.h
+++ b/sound/soc/sof/intel/shim.h
@@ -22,6 +22,7 @@ enum sof_intel_hw_ip_version {
SOF_INTEL_CAVS_2_5, /* TigerLake, AlderLake */
SOF_INTEL_ACE_1_0, /* MeteorLake */
SOF_INTEL_ACE_2_0, /* LunarLake */
+ SOF_INTEL_ACE_3_0, /* PantherLake */
};
/*
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index baad4c1445aa..35a7462d8b69 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -100,7 +100,7 @@ sof_pcm_setup_connected_widgets(struct snd_sof_dev *sdev, struct snd_soc_pcm_run
dpcm_end_walk_at_be);
if (ret < 0) {
dev_err(sdev->dev, "error: dai %s has no valid %s path\n", dai->name,
- dir == SNDRV_PCM_STREAM_PLAYBACK ? "playback" : "capture");
+ snd_pcm_direction_name(dir));
return ret;
}
diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h
index 49be02234fc3..b9b8b64768b9 100644
--- a/sound/soc/sof/sof-audio.h
+++ b/sound/soc/sof/sof-audio.h
@@ -314,12 +314,12 @@ struct sof_token_info {
/**
* struct snd_sof_pcm_stream_pipeline_list - List of pipelines associated with a PCM stream
- * @count: number of pipeline widgets in the @pipe_widgets array
* @pipelines: array of pipelines
+ * @count: number of pipeline widgets in the @pipe_widgets array
*/
struct snd_sof_pcm_stream_pipeline_list {
- u32 count;
struct snd_sof_pipeline **pipelines;
+ u32 count;
};
/* PCM stream, mapped to FW component */
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 4d6a1517f9b3..843be3b6415d 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -132,16 +132,17 @@ struct snd_sof_pdata;
/**
* struct snd_sof_platform_stream_params - platform dependent stream parameters
- * @stream_tag: Stream tag to use
- * @use_phy_addr: Use the provided @phy_addr for configuration
* @phy_addr: Platform dependent address to be used, if @use_phy_addr
* is true
+ * @stream_tag: Stream tag to use
+ * @use_phy_addr: Use the provided @phy_addr for configuration
* @no_ipc_position: Disable position update IPC from firmware
+ * @cont_update_posn: Continuous position update.
*/
struct snd_sof_platform_stream_params {
+ u32 phy_addr;
u16 stream_tag;
bool use_phy_address;
- u32 phy_addr;
bool no_ipc_position;
bool cont_update_posn;
};
@@ -411,8 +412,8 @@ struct snd_sof_debugfs_map {
/* mailbox descriptor, used for host <-> DSP IPC */
struct snd_sof_mailbox {
- u32 offset;
size_t size;
+ u32 offset;
};
/* IPC message descriptor for host <-> DSP IO */
@@ -424,11 +425,12 @@ struct snd_sof_ipc_msg {
size_t reply_size;
int reply_error;
- /* notification, firmware initiated messages */
- void *rx_data;
+ bool ipc_complete;
wait_queue_head_t waitq;
- bool ipc_complete;
+
+ /* notification, firmware initiated messages */
+ void *rx_data;
};
/**
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c
index 46098e111142..a96aa308681a 100644
--- a/sound/soc/stm/stm32_i2s.c
+++ b/sound/soc/stm/stm32_i2s.c
@@ -823,7 +823,7 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
/* Enable i2s */
dev_dbg(cpu_dai->dev, "start I2S %s\n",
- playback_flg ? "playback" : "capture");
+ snd_pcm_direction_name(substream->stream));
cfg1_mask = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN;
regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG,
@@ -869,7 +869,7 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
dev_dbg(cpu_dai->dev, "stop I2S %s\n",
- playback_flg ? "playback" : "capture");
+ snd_pcm_direction_name(substream->stream));
if (playback_flg)
regmap_update_bits(i2s->regmap, STM32_I2S_IER_REG,
diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c
index fe4fde844d86..e93ceb7afb4c 100644
--- a/sound/soc/tegra/tegra210_i2s.c
+++ b/sound/soc/tegra/tegra210_i2s.c
@@ -85,7 +85,7 @@ static int tegra210_i2s_set_clock_rate(struct device *dev,
}
static int tegra210_i2s_sw_reset(struct snd_soc_component *compnt,
- bool is_playback)
+ int stream)
{
struct device *dev = compnt->dev;
struct tegra210_i2s *i2s = dev_get_drvdata(dev);
@@ -95,7 +95,7 @@ static int tegra210_i2s_sw_reset(struct snd_soc_component *compnt,
unsigned int cif_ctrl, stream_ctrl, i2s_ctrl, val;
int err;
- if (is_playback) {
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
reset_reg = TEGRA210_I2S_RX_SOFT_RESET;
cif_reg = TEGRA210_I2S_RX_CIF_CTRL;
stream_reg = TEGRA210_I2S_RX_CTRL;
@@ -118,7 +118,7 @@ static int tegra210_i2s_sw_reset(struct snd_soc_component *compnt,
10, 10000);
if (err) {
dev_err(dev, "timeout: failed to reset I2S for %s\n",
- is_playback ? "playback" : "capture");
+ snd_pcm_direction_name(stream));
return err;
}
@@ -137,16 +137,16 @@ static int tegra210_i2s_init(struct snd_soc_dapm_widget *w,
struct device *dev = compnt->dev;
struct tegra210_i2s *i2s = dev_get_drvdata(dev);
unsigned int val, status_reg;
- bool is_playback;
+ int stream;
int err;
switch (w->reg) {
case TEGRA210_I2S_RX_ENABLE:
- is_playback = true;
+ stream = SNDRV_PCM_STREAM_PLAYBACK;
status_reg = TEGRA210_I2S_RX_STATUS;
break;
case TEGRA210_I2S_TX_ENABLE:
- is_playback = false;
+ stream = SNDRV_PCM_STREAM_CAPTURE;
status_reg = TEGRA210_I2S_TX_STATUS;
break;
default:
@@ -159,11 +159,11 @@ static int tegra210_i2s_init(struct snd_soc_dapm_widget *w,
10, 10000);
if (err) {
dev_err(dev, "timeout: previous I2S %s is still active\n",
- is_playback ? "playback" : "capture");
+ snd_pcm_direction_name(stream));
return err;
}
- return tegra210_i2s_sw_reset(compnt, is_playback);
+ return tegra210_i2s_sw_reset(compnt, stream);
}
static int __maybe_unused tegra210_i2s_runtime_suspend(struct device *dev)
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 4bdbcd2635ef..05d59e03b1c5 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -213,7 +213,7 @@ int tegra_pcm_construct(struct snd_soc_component *component,
* Fallback for backwards-compatibility with older device trees that
* have the iommus property in the virtual, top-level "sound" node.
*/
- if (!of_get_property(dev->of_node, "iommus", NULL))
+ if (!of_property_present(dev->of_node, "iommus"))
dev = rtd->card->snd_card->dev;
return tegra_pcm_dma_allocate(dev, rtd, tegra_pcm_hardware.buffer_bytes_max);