ASoC: Updates for v6.12

This is a very large set of changes, almost all in drivers rather than
 the core.  Even with the addition of several quite large drivers the
 overall diffstat is negative thanks to the removal of some old Intel
 board support which has been obsoleted by the AVS driver, helped a bit
 by some factoring out into helpers (especially around the Soundwire
 machine drivers for x86).
 
 Highlights include:
 
  - More simplifications and cleanups throughout the subsystem from
    Morimoto-san.
  - Extensive cleanups and refactoring of the Soundwire drivers to make
    better use of helpers.
  - Removal of Intel machine support obsoleted by the AVS driver.
  - Lots of DT schema conversions.
  - Machine support for many AMD and Intel x86 platforms.
  - Support for AMD ACP 7.1, Mediatek MT6367 and MT8365, Realtek RTL1320
    SoundWire and rev C, and Texas Instruments TAS2563
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmbko34ACgkQJNaLcl1U
 h9CQiwf9HseC6VkNQ0ISVZ2UsSf8K/HsHsdBGl7/CRr0SEvS3pszYMkKPbhRggsF
 aQ4nfitXeN7Vo6S0tNXx63wzjpMPkjrHdV0XY+WJxfuCaeb3DHFEJ4uvlgv53aoh
 M+wz1aldvKWjDPwhkzcJEaneQ36U7OlUSBsbFHR82dBDguEm+h29tAxTuLlwL5Zb
 M8NuSfbh0cfY9Kk1cPGsqaHD8wjUeg6/Q5qnbDg2kAm0aF1fAxfyFKRX6Z5s9ekd
 LeU3EIdRbI8UlHv7Afl0UKDYtYqL1ubwmjDb45HnsE4FmNEmDEbf8c1adRumZAjm
 Js9yzswiaaHAvotCaEstFC6HYUL+oQ==
 =jugn
 -----END PGP SIGNATURE-----

Merge tag 'asoc-v6.12' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next

ASoC: Updates for v6.12

This is a very large set of changes, almost all in drivers rather than
the core.  Even with the addition of several quite large drivers the
overall diffstat is negative thanks to the removal of some old Intel
board support which has been obsoleted by the AVS driver, helped a bit
by some factoring out into helpers (especially around the Soundwire
machine drivers for x86).

Highlights include:

 - More simplifications and cleanups throughout the subsystem from
   Morimoto-san.
 - Extensive cleanups and refactoring of the Soundwire drivers to make
   better use of helpers.
 - Removal of Intel machine support obsoleted by the AVS driver.
 - Lots of DT schema conversions.
 - Machine support for many AMD and Intel x86 platforms.
 - Support for AMD ACP 7.1, Mediatek MT6367 and MT8365, Realtek RTL1320
   SoundWire and rev C, and Texas Instruments TAS2563
This commit is contained in:
Takashi Iwai 2024-09-14 09:09:59 +02:00
commit 1a529af6f8
432 changed files with 19665 additions and 27495 deletions

View File

@ -37,6 +37,24 @@ properties:
"#interrupt-cells":
const: 2
mediatek,hp-pull-down:
description:
Earphone driver positive output stage short to
the audio reference ground.
type: boolean
mediatek,micbias0-microvolt:
description: Selects MIC Bias 0 output voltage.
enum: [1700000, 1800000, 1900000, 2000000,
2100000, 2500000, 2600000, 2700000]
default: 1700000
mediatek,micbias1-microvolt:
description: Selects MIC Bias 1 output voltage.
enum: [1700000, 1800000, 1900000, 2000000,
2100000, 2500000, 2600000, 2700000]
default: 1700000
regulators:
type: object
$ref: /schemas/regulator/mediatek,mt6357-regulator.yaml
@ -83,6 +101,9 @@ examples:
interrupt-controller;
#interrupt-cells = <2>;
mediatek,micbias0-microvolt = <1700000>;
mediatek,micbias1-microvolt = <1700000>;
regulators {
mt6357_vproc_reg: buck-vproc {
regulator-name = "vproc";

View File

@ -26,6 +26,13 @@ properties:
A list off component DAPM widget. Each entry is a pair of strings,
the first being the widget type, the second being the widget name
clocks:
minItems: 1
maxItems: 3
description:
Base PLL clocks of audio susbsytem, used to configure base clock
frequencies for different audio use-cases.
patternProperties:
"^dai-link-[0-9]+$":
type: object

View File

@ -27,6 +27,13 @@ properties:
A list off component DAPM widget. Each entry is a pair of strings,
the first being the widget type, the second being the widget name
clocks:
minItems: 1
maxItems: 3
description:
Base PLL clocks of audio susbsytem, used to configure base clock
frequencies for different audio use-cases.
patternProperties:
"^dai-link-[0-9]+$":
type: object

View File

@ -0,0 +1,101 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/cirrus,cs4271.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Cirrus Logic CS4271 audio CODEC
maintainers:
- Alexander Sverdlin <alexander.sverdlin@gmail.com>
- Nikita Shubin <nikita.shubin@maquefel.me>
description:
The CS4271 is a stereo audio codec. This device supports both the I2C
and the SPI bus.
allOf:
- $ref: dai-common.yaml#
- $ref: /schemas/spi/spi-peripheral-props.yaml#
properties:
compatible:
const: cirrus,cs4271
reg:
maxItems: 1
spi-cpha: true
spi-cpol: true
'#sound-dai-cells':
const: 0
reset-gpios:
description:
This pin will be deasserted before communication to the codec starts.
maxItems: 1
va-supply:
description: Analog power supply.
vd-supply:
description: Digital power supply.
vl-supply:
description: Serial Control Port power supply.
port:
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
cirrus,amuteb-eq-bmutec:
description:
When given, the Codec's AMUTEB=BMUTEC flag is enabled.
type: boolean
cirrus,enable-soft-reset:
description: |
The CS4271 requires its LRCLK and MCLK to be stable before its RESET
line is de-asserted. That also means that clocks cannot be changed
without putting the chip back into hardware reset, which also requires
a complete re-initialization of all registers.
One (undocumented) workaround is to assert and de-assert the PDN bit
in the MODE2 register. This workaround can be enabled with this DT
property.
Note that this is not needed in case the clocks are stable
throughout the entire runtime of the codec.
type: boolean
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
codec@0 {
compatible = "cirrus,cs4271";
reg = <0>;
#sound-dai-cells = <0>;
spi-max-frequency = <6000000>;
spi-cpol;
spi-cpha;
reset-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
port {
endpoint {
remote-endpoint = <&i2s_ep>;
};
};
};
};
...

View File

@ -1,57 +0,0 @@
Cirrus Logic CS4271 DT bindings
This driver supports both the I2C and the SPI bus.
Required properties:
- compatible: "cirrus,cs4271"
For required properties on SPI, please consult
Documentation/devicetree/bindings/spi/spi-bus.txt
Required properties on I2C:
- reg: the i2c address
Optional properties:
- reset-gpio: a GPIO spec to define which pin is connected to the chip's
!RESET pin
- cirrus,amuteb-eq-bmutec: When given, the Codec's AMUTEB=BMUTEC flag
is enabled.
- cirrus,enable-soft-reset:
The CS4271 requires its LRCLK and MCLK to be stable before its RESET
line is de-asserted. That also means that clocks cannot be changed
without putting the chip back into hardware reset, which also requires
a complete re-initialization of all registers.
One (undocumented) workaround is to assert and de-assert the PDN bit
in the MODE2 register. This workaround can be enabled with this DT
property.
Note that this is not needed in case the clocks are stable
throughout the entire runtime of the codec.
- vd-supply: Digital power
- vl-supply: Logic power
- va-supply: Analog Power
Examples:
codec_i2c: cs4271@10 {
compatible = "cirrus,cs4271";
reg = <0x10>;
reset-gpio = <&gpio 23 0>;
vd-supply = <&vdd_3v3_reg>;
vl-supply = <&vdd_3v3_reg>;
va-supply = <&vdd_3v3_reg>;
};
codec_spi: cs4271@0 {
compatible = "cirrus,cs4271";
reg = <0x0>;
reset-gpio = <&gpio 23 0>;
spi-max-frequency = <6000000>;
};

View File

@ -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>;
};

View File

@ -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 <support.opensource@diasemi.com>
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>;
};
};

View File

@ -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 <shawnguo@kernel.org>
- Sascha Hauer <s.hauer@pengutronix.de>
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>;
};

View File

@ -0,0 +1,83 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/fsl,saif.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale MXS Serial Audio Interface (SAIF)
maintainers:
- Lukasz Majewski <lukma@denx.de>
allOf:
- $ref: dai-common.yaml#
description:
The SAIF is based on I2S module that is used to communicate with audio codecs,
but only with half-duplex manner (i.e. it can either transmit or receive PCM
audio).
properties:
compatible:
const: fsl,imx28-saif
reg:
maxItems: 1
"#sound-dai-cells":
const: 0
interrupts:
maxItems: 1
dmas:
maxItems: 1
dma-names:
const: rx-tx
"#clock-cells":
description: Configure the I2S device as MCLK clock provider.
const: 0
clocks:
maxItems: 1
fsl,saif-master:
description: Indicate that saif is a slave and its phandle points to master
$ref: /schemas/types.yaml#/definitions/phandle
required:
- compatible
- reg
- "#sound-dai-cells"
- interrupts
- dmas
- dma-names
- clocks
unevaluatedProperties: false
examples:
- |
saif0: saif@80042000 {
compatible = "fsl,imx28-saif";
reg = <0x80042000 2000>;
#sound-dai-cells = <0>;
interrupts = <59>;
dmas = <&dma_apbx 4>;
dma-names = "rx-tx";
#clock-cells = <0>;
clocks = <&clks 53>;
};
- |
saif1: saif@80046000 {
compatible = "fsl,imx28-saif";
reg = <0x80046000 2000>;
#sound-dai-cells = <0>;
interrupts = <58>;
dmas = <&dma_apbx 5>;
dma-names = "rx-tx";
clocks = <&clks 53>;
fsl,saif-master = <&saif0>;
};

View File

@ -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>;
};

View File

@ -0,0 +1,130 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/mediatek,mt8365-afe.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MediaTek Audio Front End PCM controller for MT8365
maintainers:
- Alexandre Mergnat <amergnat@baylibre.com>
properties:
compatible:
const: mediatek,mt8365-afe-pcm
reg:
maxItems: 1
"#sound-dai-cells":
const: 0
clocks:
items:
- description: 26M clock
- description: mux for audio clock
- description: audio i2s0 mck
- description: audio i2s1 mck
- description: audio i2s2 mck
- description: audio i2s3 mck
- description: engen 1 clock
- description: engen 2 clock
- description: audio 1 clock
- description: audio 2 clock
- description: mux for i2s0
- description: mux for i2s1
- description: mux for i2s2
- description: mux for i2s3
clock-names:
items:
- const: top_clk26m_clk
- const: top_audio_sel
- const: audio_i2s0_m
- const: audio_i2s1_m
- const: audio_i2s2_m
- const: audio_i2s3_m
- const: engen1
- const: engen2
- const: aud1
- const: aud2
- const: i2s0_m_sel
- const: i2s1_m_sel
- const: i2s2_m_sel
- const: i2s3_m_sel
interrupts:
maxItems: 1
power-domains:
maxItems: 1
mediatek,dmic-mode:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Indicates how many data pins are used to transmit two channels of PDM
signal. 1 means two wires, 0 means one wire. Default value is 0.
enum:
- 0 # one wire
- 1 # two wires
required:
- compatible
- reg
- clocks
- clock-names
- interrupts
- power-domains
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/mediatek,mt8365-clk.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/power/mediatek,mt8365-power.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
audio-controller@11220000 {
compatible = "mediatek,mt8365-afe-pcm";
reg = <0 0x11220000 0 0x1000>;
#sound-dai-cells = <0>;
clocks = <&clk26m>,
<&topckgen CLK_TOP_AUDIO_SEL>,
<&topckgen CLK_TOP_AUD_I2S0_M>,
<&topckgen CLK_TOP_AUD_I2S1_M>,
<&topckgen CLK_TOP_AUD_I2S2_M>,
<&topckgen CLK_TOP_AUD_I2S3_M>,
<&topckgen CLK_TOP_AUD_ENGEN1_SEL>,
<&topckgen CLK_TOP_AUD_ENGEN2_SEL>,
<&topckgen CLK_TOP_AUD_1_SEL>,
<&topckgen CLK_TOP_AUD_2_SEL>,
<&topckgen CLK_TOP_APLL_I2S0_SEL>,
<&topckgen CLK_TOP_APLL_I2S1_SEL>,
<&topckgen CLK_TOP_APLL_I2S2_SEL>,
<&topckgen CLK_TOP_APLL_I2S3_SEL>;
clock-names = "top_clk26m_clk",
"top_audio_sel",
"audio_i2s0_m",
"audio_i2s1_m",
"audio_i2s2_m",
"audio_i2s3_m",
"engen1",
"engen2",
"aud1",
"aud2",
"i2s0_m_sel",
"i2s1_m_sel",
"i2s2_m_sel",
"i2s3_m_sel";
interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_LOW>;
power-domains = <&spm MT8365_POWER_DOMAIN_AUDIO>;
mediatek,dmic-mode = <1>;
};
};
...

View File

@ -0,0 +1,107 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/mediatek,mt8365-mt6357.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MediaTek MT8365 ASoC sound card
maintainers:
- Alexandre Mergnat <amergnat@baylibre.com>
properties:
compatible:
const: mediatek,mt8365-mt6357
pinctrl-names:
minItems: 1
items:
- const: default
- const: dmic
- const: miso_off
- const: miso_on
- const: mosi_off
- const: mosi_on
mediatek,platform:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of MT8365 ASoC platform.
patternProperties:
"^dai-link-[0-9]+$":
type: object
description:
Container for dai-link level properties and CODEC sub-nodes.
properties:
codec:
type: object
description: Holds subnode which indicates codec dai.
properties:
sound-dai:
maxItems: 1
description: phandle of the codec DAI
additionalProperties: false
link-name:
description: Indicates dai-link name and PCM stream name
enum:
- I2S_IN_BE
- I2S_OUT_BE
- PCM1_BE
- PDM1_BE
- PDM2_BE
- PDM3_BE
- PDM4_BE
- SPDIF_IN_BE
- SPDIF_OUT_BE
- TDM_IN_BE
- TDM_OUT_BE
sound-dai:
maxItems: 1
description: phandle of the CPU DAI
required:
- link-name
- sound-dai
additionalProperties: false
required:
- compatible
- pinctrl-names
- mediatek,platform
additionalProperties: false
examples:
- |
sound {
compatible = "mediatek,mt8365-mt6357";
pinctrl-names = "default",
"dmic",
"miso_off",
"miso_on",
"mosi_off",
"mosi_on";
pinctrl-0 = <&aud_default_pins>;
pinctrl-1 = <&aud_dmic_pins>;
pinctrl-2 = <&aud_miso_off_pins>;
pinctrl-3 = <&aud_miso_on_pins>;
pinctrl-4 = <&aud_mosi_off_pins>;
pinctrl-5 = <&aud_mosi_on_pins>;
mediatek,platform = <&afe>;
/* hdmi interface */
dai-link-0 {
link-name = "I2S_OUT_BE";
sound-dai = <&afe>;
codec {
sound-dai = <&it66121hdmitx>;
};
};
};

View File

@ -13,6 +13,9 @@ description:
The Microchip Sony/Philips Digital Interface Receiver is a serial port
compliant with the IEC-60958 standard.
allOf:
- $ref: dai-common.yaml#
properties:
"#sound-dai-cells":
const: 0
@ -53,7 +56,7 @@ required:
- dmas
- dma-names
additionalProperties: false
unevaluatedProperties: false
examples:
- |

View File

@ -1,41 +0,0 @@
* Freescale MXS Serial Audio Interface (SAIF)
Required properties:
- compatible: Should be "fsl,<chip>-saif"
- reg: Should contain registers location and length
- interrupts: Should contain ERROR interrupt number
- dmas: DMA specifier, consisting of a phandle to DMA controller node
and SAIF DMA channel ID.
Refer to dma.txt and fsl-mxs-dma.txt for details.
- dma-names: Must be "rx-tx".
Optional properties:
- fsl,saif-master: phandle to the master SAIF. It's only required for
the slave SAIF.
Note: Each SAIF controller should have an alias correctly numbered
in "aliases" node.
Example:
aliases {
saif0 = &saif0;
saif1 = &saif1;
};
saif0: saif@80042000 {
compatible = "fsl,imx28-saif";
reg = <0x80042000 2000>;
interrupts = <59>;
dmas = <&dma_apbx 4>;
dma-names = "rx-tx";
};
saif1: saif@80046000 {
compatible = "fsl,imx28-saif";
reg = <0x80046000 2000>;
interrupts = <58>;
dmas = <&dma_apbx 5>;
dma-names = "rx-tx";
fsl,saif-master = <&saif0>;
};

View File

@ -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>;
};

View File

@ -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 <srinivas.kandagatla@linaro.org>
- Stephan Gerhold <stephan@gerhold.net>
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>;
};
};
};

View File

@ -64,6 +64,7 @@ allOf:
compatible:
enum:
- qcom,sc7280-lpass-wsa-macro
- qcom,sm8250-lpass-wsa-macro
- qcom,sm8450-lpass-wsa-macro
- qcom,sc8280xp-lpass-wsa-macro
then:
@ -79,24 +80,6 @@ allOf:
- const: dcodec
- const: fsgen
- if:
properties:
compatible:
enum:
- qcom,sm8250-lpass-wsa-macro
then:
properties:
clocks:
minItems: 6
clock-names:
items:
- const: mclk
- const: npl
- const: macro
- const: dcodec
- const: va
- const: fsgen
- if:
properties:
compatible:
@ -130,8 +113,7 @@ examples:
<&audiocc 0>,
<&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
<&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
<&aoncc LPASS_CDC_VA_MCLK>,
<&vamacro>;
clock-names = "mclk", "npl", "macro", "dcodec", "va", "fsgen";
clock-names = "mclk", "npl", "macro", "dcodec", "fsgen";
clock-output-names = "mclk";
};

View File

@ -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>;
};
};
};

View File

@ -30,6 +30,18 @@ properties:
reg:
maxItems: 1
clocks:
items:
- description: Master clock to the CODEC
clock-names:
items:
- const: mclk
port:
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
required:
- compatible
- reg

View File

@ -112,6 +112,12 @@ properties:
description: List of necessary clock names.
# details are defined below
post-init-providers:
description: At least if rsnd is using DPCM connection on Audio-Graph-Card2,
fw_devlink might doesn't have enough information to break the cycle. rsnd
driver will not be probed in such case. Same problem might occur with
Multi-CPU/Codec or Codec2Codec.
# ports is below
port:
$ref: audio-graph-port.yaml#/definitions/port-base

View File

@ -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

View File

@ -27,11 +27,6 @@ properties:
- const: samsung,odroid-xu4-audio
deprecated: true
assigned-clock-parents: true
assigned-clock-rates: true
assigned-clocks: true
clocks: true
cpu:
type: object
additionalProperties: false

View File

@ -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 <animeshagarwal28@gmail.com>
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>;
};
};

View File

@ -0,0 +1,127 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/ti,tlv320dac3100.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments - tlv320aic31xx Codec module
maintainers:
- Shenghao Ding <shenghao-ding@ti.com>
description: |
CODEC output pins:
* HPL
* HPR
* SPL, devices with stereo speaker amp
* SPR, devices with stereo speaker amp
* SPK, devices with mono speaker amp
* MICBIAS
CODEC input pins:
* MIC1LP, devices with ADC
* MIC1RP, devices with ADC
* MIC1LM, devices with ADC
* AIN1, devices without ADC
* AIN2, devices without ADC
The pins can be used in referring sound node's audio-routing property.
properties:
compatible:
enum:
- ti,tlv320aic310x # - Generic TLV320AIC31xx with mono speaker amp
- ti,tlv320aic311x # - Generic TLV320AIC31xx with stereo speaker amp
- ti,tlv320aic3100 # - TLV320AIC3100 (mono speaker amp, no MiniDSP)
- ti,tlv320aic3110 # - TLV320AIC3110 (stereo speaker amp, no MiniDSP)
- ti,tlv320aic3120 # - TLV320AIC3120 (mono speaker amp, MiniDSP)
- ti,tlv320aic3111 # - TLV320AIC3111 (stereo speaker amp, MiniDSP)
- ti,tlv320dac3100 # - TLV320DAC3100 (no ADC, mono speaker amp, no MiniDSP)
- ti,tlv320dac3101 # - TLV320DAC3101 (no ADC, stereo speaker amp, no MiniDSP)
reg:
maxItems: 1
'#sound-dai-cells':
const: 0
HPVDD-supply: true
SPRVDD-supply: true
SPLVDD-supply: true
AVDD-supply: true
IOVDD-supply: true
DVDD-supply: true
reset-gpios:
description: GPIO specification for the active low RESET input.
ai31xx-micbias-vg:
$ref: /schemas/types.yaml#/definitions/uint32
default: 1
enum: [1, 2, 3]
description: |
MicBias Voltage setting
1 or MICBIAS_2_0V - MICBIAS output is powered to 2.0V
2 or MICBIAS_2_5V - MICBIAS output is powered to 2.5V
3 or MICBIAS_AVDD - MICBIAS output is connected to AVDD
ai31xx-ocmv:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3]
description: |
output common-mode voltage setting
0 - 1.35V,
1 - 1.5V,
2 - 1.65V,
3 - 1.8V
gpio-reset:
description: gpio pin number used for codec reset
deprecated: true
required:
- compatible
- reg
- HPVDD-supply
- SPRVDD-supply
- SPLVDD-supply
- AVDD-supply
- IOVDD-supply
- DVDD-supply
allOf:
- $ref: dai-common.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/sound/tlv320aic31xx.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
sound@18 {
compatible = "ti,tlv320aic311x";
reg = <0x18>;
ai31xx-micbias-vg = <MICBIAS_2_0V>;
reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
HPVDD-supply = <&regulator>;
SPRVDD-supply = <&regulator>;
SPLVDD-supply = <&regulator>;
AVDD-supply = <&regulator>;
IOVDD-supply = <&regulator>;
DVDD-supply = <&regulator>;
};
};

View File

@ -0,0 +1,55 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/ti,tpa6130a2.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments - tpa6130a2 Codec module
maintainers:
- Sebastian Reichel <sre@kernel.org>
description:
Stereo, analog input headphone amplifier
properties:
compatible:
enum:
- ti,tpa6130a2
- ti,tpa6140a2
reg:
maxItems: 1
Vdd-supply:
description: power supply regulator
power-gpio:
description: gpio pin to power the device
required:
- compatible
- reg
- Vdd-supply
allOf:
- $ref: dai-common.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
amplifier@60 {
compatible = "ti,tpa6130a2";
reg = <0x60>;
Vdd-supply = <&vmmc2>;
power-gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>;
};
};

View File

@ -1,77 +0,0 @@
Texas Instruments - tlv320aic31xx Codec module
The tlv320aic31xx serial control bus communicates through I2C protocols
Required properties:
- compatible - "string" - One of:
"ti,tlv320aic310x" - Generic TLV320AIC31xx with mono speaker amp
"ti,tlv320aic311x" - Generic TLV320AIC31xx with stereo speaker amp
"ti,tlv320aic3100" - TLV320AIC3100 (mono speaker amp, no MiniDSP)
"ti,tlv320aic3110" - TLV320AIC3110 (stereo speaker amp, no MiniDSP)
"ti,tlv320aic3120" - TLV320AIC3120 (mono speaker amp, MiniDSP)
"ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP)
"ti,tlv320dac3100" - TLV320DAC3100 (no ADC, mono speaker amp, no MiniDSP)
"ti,tlv320dac3101" - TLV320DAC3101 (no ADC, stereo speaker amp, no MiniDSP)
- reg - <int> - I2C slave address
- HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply,
DVDD-supply : power supplies for the device as covered in
Documentation/devicetree/bindings/regulator/regulator.txt
Optional properties:
- reset-gpios - GPIO specification for the active low RESET input.
- ai31xx-micbias-vg - MicBias Voltage setting
1 or MICBIAS_2_0V - MICBIAS output is powered to 2.0V
2 or MICBIAS_2_5V - MICBIAS output is powered to 2.5V
3 or MICBIAS_AVDD - MICBIAS output is connected to AVDD
If this node is not mentioned or if the value is unknown, then
micbias is set to 2.0V.
- ai31xx-ocmv - output common-mode voltage setting
0 - 1.35V,
1 - 1.5V,
2 - 1.65V,
3 - 1.8V
Deprecated properties:
- gpio-reset - gpio pin number used for codec reset
CODEC output pins:
* HPL
* HPR
* SPL, devices with stereo speaker amp
* SPR, devices with stereo speaker amp
* SPK, devices with mono speaker amp
* MICBIAS
CODEC input pins:
* MIC1LP, devices with ADC
* MIC1RP, devices with ADC
* MIC1LM, devices with ADC
* AIN1, devices without ADC
* AIN2, devices without ADC
The pins can be used in referring sound node's audio-routing property.
Example:
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/sound/tlv320aic31xx.h>
tlv320aic31xx: tlv320aic31xx@18 {
compatible = "ti,tlv320aic311x";
reg = <0x18>;
ai31xx-micbias-vg = <MICBIAS_OFF>;
reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
HPVDD-supply = <&regulator>;
SPRVDD-supply = <&regulator>;
SPLVDD-supply = <&regulator>;
AVDD-supply = <&regulator>;
IOVDD-supply = <&regulator>;
DVDD-supply = <&regulator>;
};

View File

@ -1,27 +0,0 @@
Texas Instruments - tpa6130a2 Codec module
The tpa6130a2 serial control bus communicates through I2C protocols
Required properties:
- compatible - "string" - One of:
"ti,tpa6130a2" - TPA6130A2
"ti,tpa6140a2" - TPA6140A2
- reg - <int> - I2C slave address
- Vdd-supply - <phandle> - power supply regulator
Optional properties:
- power-gpio - gpio pin to power the device
Example:
tpa6130a2: tpa6130a2@60 {
compatible = "ti,tpa6130a2";
reg = <0x60>;
Vdd-supply = <&vmmc2>;
power-gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>;
};

View File

@ -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
@ -22578,12 +22579,11 @@ F: Documentation/devicetree/bindings/sound/tas2552.txt
F: Documentation/devicetree/bindings/sound/ti,tas2562.yaml
F: Documentation/devicetree/bindings/sound/ti,tas2770.yaml
F: Documentation/devicetree/bindings/sound/ti,tas27xx.yaml
F: Documentation/devicetree/bindings/sound/ti,tpa6130a2.yaml
F: Documentation/devicetree/bindings/sound/ti,pcm1681.yaml
F: Documentation/devicetree/bindings/sound/ti,pcm3168a.yaml
F: Documentation/devicetree/bindings/sound/ti,tlv320*.yaml
F: Documentation/devicetree/bindings/sound/ti,tlv320adcx140.yaml
F: Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
F: Documentation/devicetree/bindings/sound/tpa6130a2.txt
F: include/sound/tas2*.h
F: include/sound/tlv320*.h
F: include/sound/tpa6130a2-plat.h

View File

@ -222,6 +222,13 @@ static inline bool sdw_intel_sync_check_cmdsync_unlocked(struct sdw_intel *sdw)
return false;
}
static inline int sdw_intel_get_link_count(struct sdw_intel *sdw)
{
if (SDW_INTEL_CHECK_OPS(sdw, get_link_count))
return SDW_INTEL_OPS(sdw, get_link_count)(sdw);
return 4; /* default on older generations */
}
/* common bus management */
int intel_start_bus(struct sdw_intel *sdw);
int intel_start_bus_after_reset(struct sdw_intel *sdw);

View File

@ -706,10 +706,30 @@ static void intel_program_sdi(struct sdw_intel *sdw, int dev_num)
__func__, sdw->instance, dev_num);
}
static int intel_get_link_count(struct sdw_intel *sdw)
{
int ret;
ret = hdac_bus_eml_get_count(sdw->link_res->hbus, true, AZX_REG_ML_LEPTR_ID_SDW);
if (!ret) {
dev_err(sdw->cdns.dev, "%s: could not retrieve link count\n", __func__);
return -ENODEV;
}
if (ret > SDW_INTEL_MAX_LINKS) {
dev_err(sdw->cdns.dev, "%s: link count %d exceed max %d\n", __func__, ret, SDW_INTEL_MAX_LINKS);
return -EINVAL;
}
return ret;
}
const struct sdw_intel_hw_ops sdw_intel_lnl_hw_ops = {
.debugfs_init = intel_ace2x_debugfs_init,
.debugfs_exit = intel_ace2x_debugfs_exit,
.get_link_count = intel_get_link_count,
.register_dai = intel_register_dai,
.check_clock_stop = intel_check_clock_stop,

View File

@ -317,6 +317,20 @@ static int intel_link_probe(struct auxiliary_device *auxdev,
bus->link_id = auxdev->id;
bus->clk_stop_timeout = 1;
/*
* paranoia check: make sure ACPI-reported number of links is aligned with
* hardware capabilities.
*/
ret = sdw_intel_get_link_count(sdw);
if (ret < 0) {
dev_err(dev, "%s: sdw_intel_get_link_count failed: %d\n", __func__, ret);
return ret;
}
if (ret <= sdw->instance) {
dev_err(dev, "%s: invalid link id %d, link count %d\n", __func__, auxdev->id, ret);
return -EINVAL;
}
sdw_cdns_probe(cdns);
/* Set ops */

View File

@ -388,6 +388,7 @@ struct sdw_intel;
/* struct intel_sdw_hw_ops - SoundWire ops for Intel platforms.
* @debugfs_init: initialize all debugfs capabilities
* @debugfs_exit: close and cleanup debugfs capabilities
* @get_link_count: fetch link count from hardware registers
* @register_dai: read all PDI information and register DAIs
* @check_clock_stop: throw error message if clock is not stopped.
* @start_bus: normal start
@ -412,6 +413,8 @@ struct sdw_intel_hw_ops {
void (*debugfs_init)(struct sdw_intel *sdw);
void (*debugfs_exit)(struct sdw_intel *sdw);
int (*get_link_count)(struct sdw_intel *sdw);
int (*register_dai)(struct sdw_intel *sdw);
void (*check_clock_stop)(struct sdw_intel *sdw);
@ -447,4 +450,9 @@ extern const struct sdw_intel_hw_ops sdw_intel_lnl_hw_ops;
#define SDW_INTEL_DEV_NUM_IDA_MIN 6
/*
* Max number of links supported in hardware
*/
#define SDW_INTEL_MAX_LINKS 5
#endif

View File

@ -282,9 +282,9 @@ static inline bool cs35l56_is_otp_register(unsigned int reg)
return (reg >> 16) == 3;
}
extern struct regmap_config cs35l56_regmap_i2c;
extern struct regmap_config cs35l56_regmap_spi;
extern struct regmap_config cs35l56_regmap_sdw;
extern const struct regmap_config cs35l56_regmap_i2c;
extern const struct regmap_config cs35l56_regmap_spi;
extern const struct regmap_config cs35l56_regmap_sdw;
extern const struct cirrus_amp_cal_controls cs35l56_calibration_controls;

View File

@ -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

View File

@ -62,7 +62,6 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
* @platform: string used for HDAudio codec support
* @codec_mask: used for HDAudio support
* @dmic_num: number of SoC- or chipset-attached PDM digital microphones
* @common_hdmi_codec_drv: use commom HDAudio HDMI codec driver
* @link_mask: SoundWire links enabled on the board
* @links: array of SoundWire link _ADR descriptors, null terminated
* @i2s_link_mask: I2S/TDM links enabled on the board
@ -70,15 +69,16 @@ 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.
* @bt_link_mask: BT offload link enabled on the board
*/
struct snd_soc_acpi_mach_params {
u32 acpi_ipc_irq_index;
const char *platform;
u32 codec_mask;
u32 dmic_num;
bool common_hdmi_codec_drv;
u32 link_mask;
const struct snd_soc_acpi_link_adr *links;
u32 i2s_link_mask;
@ -86,7 +86,9 @@ 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;
u32 bt_link_mask;
};
/**

View File

@ -219,7 +219,6 @@ void snd_soc_dai_resume(struct snd_soc_dai *dai);
int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
struct snd_soc_pcm_runtime *rtd, int num);
bool snd_soc_dai_stream_valid(const struct snd_soc_dai *dai, int stream);
void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link);
void snd_soc_dai_action(struct snd_soc_dai *dai,
int stream, int action);
static inline void snd_soc_dai_activate(struct snd_soc_dai *dai,
@ -240,8 +239,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 +342,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.

View File

@ -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,
};
/*
@ -114,24 +113,6 @@ struct snd_soc_dpcm_runtime {
#define for_each_dpcm_be_rollback(fe, stream, _dpcm) \
list_for_each_entry_continue_reverse(_dpcm, &(fe)->dpcm[stream].be_clients, list_be)
/* can this BE stop and free */
int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe,
struct snd_soc_pcm_runtime *be, int stream);
/* can this BE perform a hw_params() */
int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
struct snd_soc_pcm_runtime *be, int stream);
/* can this BE perform prepare */
int snd_soc_dpcm_can_be_prepared(struct snd_soc_pcm_runtime *fe,
struct snd_soc_pcm_runtime *be, int stream);
/* is the current PCM operation for this FE ? */
int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream);
/* is the current PCM operation for this BE ? */
int snd_soc_dpcm_be_can_update(struct snd_soc_pcm_runtime *fe,
struct snd_soc_pcm_runtime *be, int stream);
/* get the substream for this BE */
struct snd_pcm_substream *

View File

@ -815,6 +815,7 @@ struct snd_soc_dai_link {
/* This DAI link can route to other DAI links at runtime (Frontend)*/
unsigned int dynamic:1;
/* REMOVE ME */
/* DPCM capture and Playback support */
unsigned int dpcm_capture:1;
unsigned int dpcm_playback:1;
@ -1206,11 +1207,11 @@ struct snd_soc_pcm_runtime {
/* bit field */
unsigned int pop_wait:1;
unsigned int fe_compr:1; /* for Dynamic PCM */
unsigned int initialized:1;
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() */

View File

@ -0,0 +1,247 @@
/* 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;
};
struct asoc_sdw_endpoint {
struct list_head list;
u32 link_mask;
const char *codec_name;
const char *name_prefix;
bool include_sidecar;
struct asoc_sdw_codec_info *codec_info;
const struct asoc_sdw_dai_info *dai_info;
};
struct asoc_sdw_dailink {
bool initialised;
u8 group_id;
u32 link_mask[SNDRV_PCM_STREAM_LAST + 1];
int num_devs[SNDRV_PCM_STREAM_LAST + 1];
struct list_head endpoints;
};
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_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends);
struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks,
const struct snd_soc_acpi_endpoint *new);
int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
struct asoc_sdw_dailink *soc_dais,
struct asoc_sdw_endpoint *soc_ends,
int *num_devs);
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

279
include/sound/tas2563-tlv.h Normal file
View File

@ -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 <shenghao-ding@ti.com>
//
#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 __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 */
{ 0X7F, 0XFF, 0XFF, 0XFF }, /* 6.0db */
};
#endif

View File

@ -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

View File

@ -49,12 +49,59 @@
/*I2C Checksum */
#define TASDEVICE_I2CChecksum TASDEVICE_REG(0x0, 0x0, 0x7E)
/* XM_340 */
#define TASDEVICE_XM_A1_REG TASDEVICE_REG(0x64, 0x63, 0x3c)
/* XM_341 */
#define TASDEVICE_XM_A2_REG TASDEVICE_REG(0x64, 0x63, 0x38)
/* Volume control */
#define TAS2563_DVC_LVL TASDEVICE_REG(0x00, 0x02, 0x0C)
#define TAS2781_DVC_LVL TASDEVICE_REG(0x0, 0x0, 0x1A)
#define TAS2781_AMP_LEVEL TASDEVICE_REG(0x0, 0x0, 0x03)
#define TAS2781_AMP_LEVEL_MASK GENMASK(5, 1)
#define TAS2563_IDLE TASDEVICE_REG(0x00, 0x00, 0x3e)
#define TAS2563_PRM_R0_REG TASDEVICE_REG(0x00, 0x0f, 0x34)
#define TAS2563_RUNTIME_RE_REG_TF TASDEVICE_REG(0x64, 0x02, 0x70)
#define TAS2563_RUNTIME_RE_REG TASDEVICE_REG(0x64, 0x02, 0x48)
#define TAS2563_PRM_ENFF_REG TASDEVICE_REG(0x00, 0x0d, 0x54)
#define TAS2563_PRM_DISTCK_REG TASDEVICE_REG(0x00, 0x0d, 0x58)
#define TAS2563_PRM_TE_SCTHR_REG TASDEVICE_REG(0x00, 0x0f, 0x60)
#define TAS2563_PRM_PLT_FLAG_REG TASDEVICE_REG(0x00, 0x0d, 0x74)
#define TAS2563_PRM_SINEGAIN_REG TASDEVICE_REG(0x00, 0x0d, 0x7c)
/* prm_Int_B0 */
#define TAS2563_TE_TA1_REG TASDEVICE_REG(0x00, 0x10, 0x0c)
/* prm_Int_A1 */
#define TAS2563_TE_TA1_AT_REG TASDEVICE_REG(0x00, 0x10, 0x10)
/* prm_TE_Beta */
#define TAS2563_TE_TA2_REG TASDEVICE_REG(0x00, 0x0f, 0x64)
/* prm_TE_Beta1 */
#define TAS2563_TE_AT_REG TASDEVICE_REG(0x00, 0x0f, 0x68)
/* prm_TE_1_Beta1 */
#define TAS2563_TE_DT_REG TASDEVICE_REG(0x00, 0x0f, 0x70)
#define TAS2781_PRM_INT_MASK_REG TASDEVICE_REG(0x00, 0x00, 0x3b)
#define TAS2781_PRM_CLK_CFG_REG TASDEVICE_REG(0x00, 0x00, 0x5c)
#define TAS2781_PRM_RSVD_REG TASDEVICE_REG(0x00, 0x01, 0x19)
#define TAS2781_PRM_TEST_57_REG TASDEVICE_REG(0x00, 0xfd, 0x39)
#define TAS2781_PRM_TEST_62_REG TASDEVICE_REG(0x00, 0xfd, 0x3e)
#define TAS2781_PRM_PVDD_UVLO_REG TASDEVICE_REG(0x00, 0x00, 0x71)
#define TAS2781_PRM_CHNL_0_REG TASDEVICE_REG(0x00, 0x00, 0x03)
#define TAS2781_PRM_NG_CFG0_REG TASDEVICE_REG(0x00, 0x00, 0x35)
#define TAS2781_PRM_IDLE_CH_DET_REG TASDEVICE_REG(0x00, 0x00, 0x66)
#define TAS2781_PRM_PLT_FLAG_REG TASDEVICE_REG(0x00, 0x14, 0x38)
#define TAS2781_PRM_SINEGAIN_REG TASDEVICE_REG(0x00, 0x14, 0x40)
#define TAS2781_PRM_SINEGAIN2_REG TASDEVICE_REG(0x00, 0x14, 0x44)
#define TAS2781_TEST_UNLOCK_REG TASDEVICE_REG(0x00, 0xFD, 0x0D)
#define TAS2781_TEST_PAGE_UNLOCK 0x0D
#define TAS2781_RUNTIME_LATCH_RE_REG TASDEVICE_REG(0x00, 0x00, 0x49)
#define TAS2781_RUNTIME_RE_REG_TF TASDEVICE_REG(0x64, 0x62, 0x48)
#define TAS2781_RUNTIME_RE_REG TASDEVICE_REG(0x64, 0x63, 0x44)
#define TASDEVICE_CMD_SING_W 0x1
#define TASDEVICE_CMD_BURST 0x2
#define TASDEVICE_CMD_DELAY 0x3
@ -70,7 +117,15 @@ enum device_catlog_id {
OTHERS
};
struct bulk_reg_val {
int reg;
unsigned char val[4];
unsigned char val_len;
bool is_locked;
};
struct tasdevice {
struct bulk_reg_val *cali_data_backup;
struct tasdevice_fw *cali_data_fmw;
unsigned int dev_addr;
unsigned int err_code;
@ -81,19 +136,23 @@ struct tasdevice {
bool is_loaderr;
};
struct tasdevice_irqinfo {
int irq_gpio;
int irq;
struct cali_reg {
unsigned int r0_reg;
unsigned int r0_low_reg;
unsigned int invr0_reg;
unsigned int pow_reg;
unsigned int tlimit_reg;
};
struct calidata {
unsigned char *data;
unsigned long total_sz;
struct cali_reg cali_reg_array;
unsigned int cali_dat_sz_per_dev;
};
struct tasdevice_priv {
struct tasdevice tasdevice[TASDEVICE_MAX_CHANNELS];
struct tasdevice_irqinfo irq_info;
struct tasdevice_rca rcabin;
struct calidata cali_data;
struct tasdevice_fw *fmw;
@ -115,6 +174,7 @@ struct tasdevice_priv {
unsigned int chip_id;
unsigned int sysclk;
int irq;
int cur_prog;
int cur_conf;
int fw_state;
@ -124,6 +184,7 @@ struct tasdevice_priv {
bool force_fwload_status;
bool playback_started;
bool isacpi;
bool is_user_space_calidata;
unsigned int global_addr;
int (*fw_parse_variable_header)(struct tasdevice_priv *tas_priv,
@ -150,6 +211,8 @@ int tasdevice_init(struct tasdevice_priv *tas_priv);
void tasdevice_remove(struct tasdevice_priv *tas_priv);
int tasdevice_save_calibration(struct tasdevice_priv *tas_priv);
void tasdevice_apply_calibration(struct tasdevice_priv *tas_priv);
int tasdev_chn_switch(struct tasdevice_priv *tas_priv,
unsigned short chn);
int tasdevice_dev_read(struct tasdevice_priv *tas_priv,
unsigned short chn, unsigned int reg, unsigned int *value);
int tasdevice_dev_write(struct tasdevice_priv *tas_priv,

View File

@ -56,10 +56,59 @@ static const struct config_entry config_table[] = {
},
#endif
/*
* Apollolake (Broxton-P)
* Skylake, Kabylake, Apollolake
* the legacy HDAudio driver is used except on Up Squared (SOF) and
* Chromebooks (SST), as well as devices based on the ES8336 codec
*/
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_AVS)
{
.flags = FLAG_SST,
.device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
.dmi_table = (const struct dmi_system_id []) {
{
.ident = "Google Chromebooks",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
}
},
{}
}
},
{
.flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
.device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
},
{
.flags = FLAG_SST,
.device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
.dmi_table = (const struct dmi_system_id []) {
{
.ident = "Google Chromebooks",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
}
},
{}
}
},
{
.flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
.device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
},
{
.flags = FLAG_SST,
.device = PCI_DEVICE_ID_INTEL_HDA_APL,
.dmi_table = (const struct dmi_system_id []) {
{
.ident = "Google Chromebooks",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
}
},
{}
}
},
#endif
#if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE)
{
.flags = FLAG_SOF,
@ -81,66 +130,6 @@ static const struct config_entry config_table[] = {
.codec_hid = &essx_83x6,
},
#endif
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL)
{
.flags = FLAG_SST,
.device = PCI_DEVICE_ID_INTEL_HDA_APL,
.dmi_table = (const struct dmi_system_id []) {
{
.ident = "Google Chromebooks",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
}
},
{}
}
},
#endif
/*
* Skylake and Kabylake use legacy HDAudio driver except for Google
* Chromebooks (SST)
*/
/* Sunrise Point-LP */
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL)
{
.flags = FLAG_SST,
.device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
.dmi_table = (const struct dmi_system_id []) {
{
.ident = "Google Chromebooks",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
}
},
{}
}
},
{
.flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
.device = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
},
#endif
/* Kabylake-LP */
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL)
{
.flags = FLAG_SST,
.device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
.dmi_table = (const struct dmi_system_id []) {
{
.ident = "Google Chromebooks",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
}
},
{}
}
},
{
.flags = FLAG_SST | FLAG_SST_ONLY_IF_DMIC,
.device = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
},
#endif
/*
* Geminilake uses legacy HDAudio driver except for Google

View File

@ -17,7 +17,6 @@
#include <linux/string.h>
#define SDW_LINK_TYPE 4 /* from Intel ACPI documentation */
#define SDW_MAX_LINKS 4
static int ctrl_link_mask;
module_param_named(sdw_link_mask, ctrl_link_mask, int, 0444);
@ -87,9 +86,9 @@ sdw_intel_scan_controller(struct sdw_intel_acpi_info *info)
}
/* Check count is within bounds */
if (count > SDW_MAX_LINKS) {
if (count > SDW_INTEL_MAX_LINKS) {
dev_err(&adev->dev, "Link count %d exceeds max %d\n",
count, SDW_MAX_LINKS);
count, SDW_INTEL_MAX_LINKS);
return -EINVAL;
}

View File

@ -818,7 +818,7 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
} else
return -ENODEV;
tas_hda->priv->irq_info.irq = clt->irq;
tas_hda->priv->irq = clt->irq;
ret = tas2781_read_acpi(tas_hda->priv, device_name);
if (ret)
return dev_err_probe(tas_hda->dev, ret,

View File

@ -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"

View File

@ -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/

View File

@ -264,8 +264,8 @@ static int axi_i2s_probe(struct platform_device *pdev)
goto err_clk_disable;
dev_info(&pdev->dev, "probed, capture %s, playback %s\n",
i2s->has_capture ? "enabled" : "disabled",
i2s->has_playback ? "enabled" : "disabled");
str_enabled_disabled(i2s->has_capture),
str_enabled_disabled(i2s->has_playback));
return 0;
@ -293,7 +293,7 @@ static struct platform_driver axi_i2s_driver = {
.of_match_table = axi_i2s_of_match,
},
.probe = axi_i2s_probe,
.remove_new = axi_i2s_dev_remove,
.remove = axi_i2s_dev_remove,
};
module_platform_driver(axi_i2s_driver);

View File

@ -258,7 +258,7 @@ static struct platform_driver axi_spdif_driver = {
.of_match_table = axi_spdif_of_match,
},
.probe = axi_spdif_probe,
.remove_new = axi_spdif_dev_remove,
.remove = axi_spdif_dev_remove,
};
module_platform_driver(axi_spdif_driver);

View File

@ -321,5 +321,17 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sof_machines[] = {
};
EXPORT_SYMBOL(snd_soc_acpi_amd_acp63_sof_machines);
struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sof_machines[] = {
{
.id = "AMDI1010",
.drv_name = "acp70-dsp",
.pdata = &acp_quirk_data,
.fw_filename = "sof-acp_7_0.ri",
.sof_tplg_filename = "sof-acp_7_0.tplg",
},
{},
};
EXPORT_SYMBOL(snd_soc_acpi_amd_acp70_sof_machines);
MODULE_DESCRIPTION("AMD ACP Machine Configuration Module");
MODULE_LICENSE("Dual BSD/GPL");

View File

@ -1426,7 +1426,7 @@ static const struct dev_pm_ops acp_pm_ops = {
static struct platform_driver acp_dma_driver = {
.probe = acp_audio_probe,
.remove_new = acp_audio_remove,
.remove = acp_audio_remove,
.driver = {
.name = DRV_NAME,
.pm = &acp_pm_ops,

View File

@ -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

View File

@ -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

View File

@ -60,6 +60,8 @@ static inline void acp_set_i2s_clk(struct acp_dev_data *adata, int dai_id)
switch (chip->acp_rev) {
case ACP63_DEV:
case ACP70_DEV:
case ACP71_DEV:
val |= FIELD_PREP(ACP63_LRCLK_DIV_FIELD, adata->lrclk_div);
val |= FIELD_PREP(ACP63_BCLK_DIV_FIELD, adata->bclk_div);
break;
@ -95,9 +97,11 @@ static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mas
{
struct device *dev = dai->component->dev;
struct acp_dev_data *adata = snd_soc_dai_get_drvdata(dai);
struct acp_chip_info *chip;
struct acp_stream *stream;
int slot_len, no_of_slots;
chip = dev_get_platdata(dev);
switch (slot_width) {
case SLOT_WIDTH_8:
slot_len = 8;
@ -116,6 +120,9 @@ static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mas
return -EINVAL;
}
switch (chip->acp_rev) {
case ACP3X_DEV:
case ACP6X_DEV:
switch (slots) {
case 1 ... 7:
no_of_slots = slots;
@ -127,17 +134,55 @@ static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mas
dev_err(dev, "Unsupported slots %d\n", slots);
return -EINVAL;
}
break;
case ACP63_DEV:
case ACP70_DEV:
case ACP71_DEV:
switch (slots) {
case 1 ... 31:
no_of_slots = slots;
break;
case 32:
no_of_slots = 0;
break;
default:
dev_err(dev, "Unsupported slots %d\n", slots);
return -EINVAL;
}
break;
default:
dev_err(dev, "Unknown chip revision %d\n", chip->acp_rev);
return -EINVAL;
}
slots = no_of_slots;
spin_lock_irq(&adata->acp_lock);
list_for_each_entry(stream, &adata->stream_list, list) {
switch (chip->acp_rev) {
case ACP3X_DEV:
case ACP6X_DEV:
if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK)
adata->tdm_tx_fmt[stream->dai_id - 1] =
FRM_LEN | (slots << 15) | (slot_len << 18);
else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE)
adata->tdm_rx_fmt[stream->dai_id - 1] =
FRM_LEN | (slots << 15) | (slot_len << 18);
break;
case ACP63_DEV:
case ACP70_DEV:
case ACP71_DEV:
if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK)
adata->tdm_tx_fmt[stream->dai_id - 1] =
FRM_LEN | (slots << 13) | (slot_len << 18);
else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE)
adata->tdm_rx_fmt[stream->dai_id - 1] =
FRM_LEN | (slots << 13) | (slot_len << 18);
break;
default:
dev_err(dev, "Unknown chip revision %d\n", chip->acp_rev);
return -EINVAL;
}
}
spin_unlock_irq(&adata->acp_lock);
return 0;
@ -296,6 +341,41 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_
default:
return -EINVAL;
}
switch (params_rate(params)) {
case 8000:
case 16000:
case 24000:
case 48000:
case 96000:
case 192000:
switch (params_channels(params)) {
case 2:
break;
case 4:
bclk_div_val = bclk_div_val >> 1;
lrclk_div_val = lrclk_div_val << 1;
break;
case 8:
bclk_div_val = bclk_div_val >> 2;
lrclk_div_val = lrclk_div_val << 2;
break;
case 16:
bclk_div_val = bclk_div_val >> 3;
lrclk_div_val = lrclk_div_val << 3;
break;
case 32:
bclk_div_val = bclk_div_val >> 4;
lrclk_div_val = lrclk_div_val << 4;
break;
default:
dev_err(dev, "Unsupported channels %#x\n",
params_channels(params));
}
break;
default:
break;
}
adata->lrclk_div = lrclk_div_val;
adata->bclk_div = bclk_div_val;
}
@ -321,16 +401,16 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
switch (dai->driver->id) {
case I2S_BT_INSTANCE:
water_val = ACP_BT_TX_INTR_WATERMARK_SIZE;
water_val = ACP_BT_TX_INTR_WATERMARK_SIZE(adata);
reg_val = ACP_BTTDM_ITER;
ier_val = ACP_BTTDM_IER;
buf_reg = ACP_BT_TX_RINGBUFSIZE;
buf_reg = ACP_BT_TX_RINGBUFSIZE(adata);
break;
case I2S_SP_INSTANCE:
water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE;
water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE(adata);
reg_val = ACP_I2STDM_ITER;
ier_val = ACP_I2STDM_IER;
buf_reg = ACP_I2S_TX_RINGBUFSIZE;
buf_reg = ACP_I2S_TX_RINGBUFSIZE(adata);
break;
case I2S_HS_INSTANCE:
water_val = ACP_HS_TX_INTR_WATERMARK_SIZE;
@ -345,16 +425,16 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
} else {
switch (dai->driver->id) {
case I2S_BT_INSTANCE:
water_val = ACP_BT_RX_INTR_WATERMARK_SIZE;
water_val = ACP_BT_RX_INTR_WATERMARK_SIZE(adata);
reg_val = ACP_BTTDM_IRER;
ier_val = ACP_BTTDM_IER;
buf_reg = ACP_BT_RX_RINGBUFSIZE;
buf_reg = ACP_BT_RX_RINGBUFSIZE(adata);
break;
case I2S_SP_INSTANCE:
water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE;
water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE(adata);
reg_val = ACP_I2STDM_IRER;
ier_val = ACP_I2STDM_IER;
buf_reg = ACP_I2S_RX_RINGBUFSIZE;
buf_reg = ACP_I2S_RX_RINGBUFSIZE(adata);
break;
case I2S_HS_INSTANCE:
water_val = ACP_HS_RX_INTR_WATERMARK_SIZE;
@ -367,6 +447,7 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
return -EINVAL;
}
}
writel(period_bytes, adata->acp_base + water_val);
writel(buf_size, adata->acp_base + buf_reg);
if (rsrc->soc_mclk)
@ -436,52 +517,67 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
{
struct device *dev = dai->component->dev;
struct acp_dev_data *adata = dev_get_drvdata(dev);
struct acp_chip_info *chip;
struct acp_resource *rsrc = adata->rsrc;
struct acp_stream *stream = substream->runtime->private_data;
u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0;
u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl;
unsigned int dir = substream->stream;
chip = dev_get_platdata(dev);
switch (dai->driver->id) {
case I2S_SP_INSTANCE:
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
reg_dma_size = ACP_I2S_TX_DMA_SIZE;
reg_dma_size = ACP_I2S_TX_DMA_SIZE(adata);
acp_fifo_addr = rsrc->sram_pte_offset +
SP_PB_FIFO_ADDR_OFFSET;
reg_fifo_addr = ACP_I2S_TX_FIFOADDR;
reg_fifo_size = ACP_I2S_TX_FIFOSIZE;
reg_fifo_addr = ACP_I2S_TX_FIFOADDR(adata);
reg_fifo_size = ACP_I2S_TX_FIFOSIZE(adata);
if (chip->acp_rev >= ACP70_DEV)
phy_addr = ACP7x_I2S_SP_TX_MEM_WINDOW_START;
else
phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR);
writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR(adata));
} else {
reg_dma_size = ACP_I2S_RX_DMA_SIZE;
reg_dma_size = ACP_I2S_RX_DMA_SIZE(adata);
acp_fifo_addr = rsrc->sram_pte_offset +
SP_CAPT_FIFO_ADDR_OFFSET;
reg_fifo_addr = ACP_I2S_RX_FIFOADDR;
reg_fifo_size = ACP_I2S_RX_FIFOSIZE;
reg_fifo_addr = ACP_I2S_RX_FIFOADDR(adata);
reg_fifo_size = ACP_I2S_RX_FIFOSIZE(adata);
if (chip->acp_rev >= ACP70_DEV)
phy_addr = ACP7x_I2S_SP_RX_MEM_WINDOW_START;
else
phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR);
writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR(adata));
}
break;
case I2S_BT_INSTANCE:
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
reg_dma_size = ACP_BT_TX_DMA_SIZE;
reg_dma_size = ACP_BT_TX_DMA_SIZE(adata);
acp_fifo_addr = rsrc->sram_pte_offset +
BT_PB_FIFO_ADDR_OFFSET;
reg_fifo_addr = ACP_BT_TX_FIFOADDR;
reg_fifo_size = ACP_BT_TX_FIFOSIZE;
reg_fifo_addr = ACP_BT_TX_FIFOADDR(adata);
reg_fifo_size = ACP_BT_TX_FIFOSIZE(adata);
if (chip->acp_rev >= ACP70_DEV)
phy_addr = ACP7x_I2S_BT_TX_MEM_WINDOW_START;
else
phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR);
writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR(adata));
} else {
reg_dma_size = ACP_BT_RX_DMA_SIZE;
reg_dma_size = ACP_BT_RX_DMA_SIZE(adata);
acp_fifo_addr = rsrc->sram_pte_offset +
BT_CAPT_FIFO_ADDR_OFFSET;
reg_fifo_addr = ACP_BT_RX_FIFOADDR;
reg_fifo_size = ACP_BT_RX_FIFOSIZE;
reg_fifo_addr = ACP_BT_RX_FIFOADDR(adata);
reg_fifo_size = ACP_BT_RX_FIFOSIZE(adata);
if (chip->acp_rev >= ACP70_DEV)
phy_addr = ACP7x_I2S_BT_RX_MEM_WINDOW_START;
else
phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR);
writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR(adata));
}
break;
case I2S_HS_INSTANCE:
@ -492,6 +588,9 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
reg_fifo_addr = ACP_HS_TX_FIFOADDR;
reg_fifo_size = ACP_HS_TX_FIFOSIZE;
if (chip->acp_rev >= ACP70_DEV)
phy_addr = ACP7x_I2S_HS_TX_MEM_WINDOW_START;
else
phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR);
} else {
@ -501,6 +600,9 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
reg_fifo_addr = ACP_HS_RX_FIFOADDR;
reg_fifo_size = ACP_HS_RX_FIFOSIZE;
if (chip->acp_rev >= ACP70_DEV)
phy_addr = ACP7x_I2S_HS_RX_MEM_WINDOW_START;
else
phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR);
}

View File

@ -113,40 +113,40 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
switch (dai->driver->id) {
case I2S_SP_INSTANCE:
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
reg_dma_size = ACP_I2S_TX_DMA_SIZE;
reg_dma_size = ACP_I2S_TX_DMA_SIZE(adata);
acp_fifo_addr = rsrc->sram_pte_offset +
SP_PB_FIFO_ADDR_OFFSET;
reg_fifo_addr = ACP_I2S_TX_FIFOADDR;
reg_fifo_size = ACP_I2S_TX_FIFOSIZE;
reg_fifo_addr = ACP_I2S_TX_FIFOADDR(adata);
reg_fifo_size = ACP_I2S_TX_FIFOSIZE(adata);
phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR);
writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR(adata));
} else {
reg_dma_size = ACP_I2S_RX_DMA_SIZE;
reg_dma_size = ACP_I2S_RX_DMA_SIZE(adata);
acp_fifo_addr = rsrc->sram_pte_offset +
SP_CAPT_FIFO_ADDR_OFFSET;
reg_fifo_addr = ACP_I2S_RX_FIFOADDR;
reg_fifo_size = ACP_I2S_RX_FIFOSIZE;
reg_fifo_addr = ACP_I2S_RX_FIFOADDR(adata);
reg_fifo_size = ACP_I2S_RX_FIFOSIZE(adata);
phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR);
writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR(adata));
}
break;
case I2S_BT_INSTANCE:
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
reg_dma_size = ACP_BT_TX_DMA_SIZE;
reg_dma_size = ACP_BT_TX_DMA_SIZE(adata);
acp_fifo_addr = rsrc->sram_pte_offset +
BT_PB_FIFO_ADDR_OFFSET;
reg_fifo_addr = ACP_BT_TX_FIFOADDR;
reg_fifo_size = ACP_BT_TX_FIFOSIZE;
reg_fifo_addr = ACP_BT_TX_FIFOADDR(adata);
reg_fifo_size = ACP_BT_TX_FIFOSIZE(adata);
phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR);
writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR(adata));
} else {
reg_dma_size = ACP_BT_RX_DMA_SIZE;
reg_dma_size = ACP_BT_RX_DMA_SIZE(adata);
acp_fifo_addr = rsrc->sram_pte_offset +
BT_CAPT_FIFO_ADDR_OFFSET;
reg_fifo_addr = ACP_BT_RX_FIFOADDR;
reg_fifo_size = ACP_BT_RX_FIFOSIZE;
reg_fifo_addr = ACP_BT_RX_FIFOADDR(adata);
reg_fifo_size = ACP_BT_RX_FIFOSIZE(adata);
phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR);
writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR(adata));
}
break;
case I2S_HS_INSTANCE:
@ -270,6 +270,7 @@ static int acp_power_on(struct acp_chip_info *chip)
acp_pgfsm_ctrl_reg = ACP63_PGFSM_CONTROL;
break;
case ACP70_DEV:
case ACP71_DEV:
acp_pgfsm_stat_reg = ACP70_PGFSM_STATUS;
acp_pgfsm_ctrl_reg = ACP70_PGFSM_CONTROL;
break;
@ -321,6 +322,8 @@ int acp_init(struct acp_chip_info *chip)
pr_err("ACP reset failed\n");
return ret;
}
if (chip->acp_rev >= ACP70_DEV)
writel(0, chip->base + ACP_ZSC_DSP_CTRL);
return 0;
}
EXPORT_SYMBOL_NS_GPL(acp_init, SND_SOC_ACP_COMMON);
@ -334,8 +337,10 @@ int acp_deinit(struct acp_chip_info *chip)
if (ret)
return ret;
if (chip->acp_rev != ACP70_DEV)
if (chip->acp_rev < ACP70_DEV)
writel(0, chip->base + ACP_CONTROL);
else
writel(0x01, chip->base + ACP_ZSC_DSP_CTRL);
return 0;
}
EXPORT_SYMBOL_NS_GPL(acp_deinit, SND_SOC_ACP_COMMON);
@ -456,6 +461,7 @@ void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip)
check_acp6x_config(chip);
break;
case ACP70_DEV:
case ACP71_DEV:
pdm_addr = ACP70_PDM_ADDR;
check_acp70_config(chip);
break;

View File

@ -242,11 +242,4 @@ module_platform_driver(acp_asoc_audio);
MODULE_IMPORT_NS(SND_SOC_AMD_MACH);
MODULE_DESCRIPTION("ACP chrome audio support");
MODULE_ALIAS("platform:acp3xalc56821019");
MODULE_ALIAS("platform:acp3xalc5682sm98360");
MODULE_ALIAS("platform:acp3xalc5682s1019");
MODULE_ALIAS("platform:acp3x-es83xx");
MODULE_ALIAS("platform:rmb-nau8825-max");
MODULE_ALIAS("platform:rmb-rt5682s-rt1019");
MODULE_ALIAS("platform:acp-pdm-mach");
MODULE_LICENSE("GPL v2");

View File

@ -1766,7 +1766,7 @@ int acp_legacy_dai_links_create(struct snd_soc_card *card)
} else if (drv_data->platform == ACP63) {
links[i].platforms = platform_acp63_component;
links[i].num_platforms = ARRAY_SIZE(platform_acp63_component);
} else if (drv_data->platform == ACP70) {
} else if ((drv_data->platform == ACP70) || (drv_data->platform == ACP71)) {
links[i].platforms = platform_acp70_component;
links[i].num_platforms = ARRAY_SIZE(platform_acp70_component);
} else {

View File

@ -56,6 +56,7 @@ enum platform_end_point {
REMBRANDT,
ACP63,
ACP70,
ACP71,
};
struct acp_mach_ops {

View File

@ -95,6 +95,10 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id
chip->name = "acp_asoc_acp70";
chip->acp_rev = ACP70_DEV;
break;
case 0x71:
chip->name = "acp_asoc_acp70";
chip->acp_rev = ACP71_DEV;
break;
default:
dev_err(dev, "Unsupported device revision:0x%x\n", pci->revision);
ret = -EINVAL;

View File

@ -31,9 +31,11 @@ static int acp_dmic_prepare(struct snd_pcm_substream *substream,
struct acp_stream *stream = substream->runtime->private_data;
struct device *dev = dai->component->dev;
struct acp_dev_data *adata = dev_get_drvdata(dev);
struct acp_chip_info *chip;
u32 physical_addr, size_dmic, period_bytes;
unsigned int dmic_ctrl;
chip = dev_get_platdata(dev);
/* Enable default DMIC clk */
writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL);
dmic_ctrl = readl(adata->acp_base + ACP_WOV_MISC_CTRL);
@ -45,6 +47,9 @@ static int acp_dmic_prepare(struct snd_pcm_substream *substream,
size_dmic = frames_to_bytes(substream->runtime,
substream->runtime->buffer_size);
if (chip->acp_rev >= ACP70_DEV)
physical_addr = ACP7x_DMIC_MEM_WINDOW_START;
else
physical_addr = stream->reg_offset + MEM_WINDOW_START;
/* Init DMIC Ring buffer */

View File

@ -68,6 +68,46 @@ static const struct snd_pcm_hardware acp_pcm_hardware_capture = {
.periods_max = CAPTURE_MAX_NUM_PERIODS,
};
static const struct snd_pcm_hardware acp6x_pcm_hardware_playback = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 32,
.rates = SNDRV_PCM_RATE_8000_192000,
.rate_min = 8000,
.rate_max = 192000,
.buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
.period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
.period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
.periods_min = PLAYBACK_MIN_NUM_PERIODS,
.periods_max = PLAYBACK_MAX_NUM_PERIODS,
};
static const struct snd_pcm_hardware acp6x_pcm_hardware_capture = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 32,
.rates = SNDRV_PCM_RATE_8000_192000,
.rate_min = 8000,
.rate_max = 192000,
.buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
.period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
.period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
.periods_min = CAPTURE_MIN_NUM_PERIODS,
.periods_max = CAPTURE_MAX_NUM_PERIODS,
};
int acp_machine_select(struct acp_dev_data *adata)
{
struct snd_soc_acpi_mach *mach;
@ -137,17 +177,20 @@ static irqreturn_t i2s_irq_handler(int irq, void *data)
void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream)
{
struct acp_resource *rsrc = adata->rsrc;
u32 pte_reg, pte_size, reg_val;
u32 reg_val;
/* Use ATU base Group5 */
pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_5;
pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5;
reg_val = rsrc->sram_pte_offset;
stream->reg_offset = 0x02000000;
/* Group Enable */
reg_val = rsrc->sram_pte_offset;
writel(reg_val | BIT(31), adata->acp_base + pte_reg);
writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + pte_size);
writel((reg_val + GRP1_OFFSET) | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
writel((reg_val + GRP2_OFFSET) | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_2);
writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2);
writel(reg_val | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_5);
writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5);
writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL);
}
EXPORT_SYMBOL_NS_GPL(config_pte_for_stream, SND_SOC_ACP_COMMON);
@ -161,7 +204,40 @@ void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int s
u32 low, high, val;
u16 page_idx;
switch (adata->platform) {
case ACP70:
case ACP71:
switch (stream->dai_id) {
case I2S_SP_INSTANCE:
if (stream->dir == SNDRV_PCM_STREAM_PLAYBACK)
val = 0x0;
else
val = 0x1000;
break;
case I2S_BT_INSTANCE:
if (stream->dir == SNDRV_PCM_STREAM_PLAYBACK)
val = 0x2000;
else
val = 0x3000;
break;
case I2S_HS_INSTANCE:
if (stream->dir == SNDRV_PCM_STREAM_PLAYBACK)
val = 0x4000;
else
val = 0x5000;
break;
case DMIC_INSTANCE:
val = 0x6000;
break;
default:
dev_err(adata->dev, "Invalid dai id %x\n", stream->dai_id);
return;
}
break;
default:
val = stream->pte_offset;
break;
}
for (page_idx = 0; page_idx < num_pages; page_idx++) {
/* Load the low address of page int ACP SRAM through SRBM */
@ -183,6 +259,7 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs
struct snd_pcm_runtime *runtime = substream->runtime;
struct device *dev = component->dev;
struct acp_dev_data *adata = dev_get_drvdata(dev);
struct acp_chip_info *chip;
struct acp_stream *stream;
int ret;
@ -191,11 +268,23 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs
return -ENOMEM;
stream->substream = substream;
chip = dev_get_platdata(dev);
switch (chip->acp_rev) {
case ACP63_DEV:
case ACP70_DEV:
case ACP71_DEV:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
runtime->hw = acp6x_pcm_hardware_playback;
else
runtime->hw = acp6x_pcm_hardware_capture;
break;
default:
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
runtime->hw = acp_pcm_hardware_playback;
else
runtime->hw = acp_pcm_hardware_capture;
break;
}
ret = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, DMA_SIZE);
if (ret) {

View File

@ -295,7 +295,7 @@ static const struct dev_pm_ops rmb_dma_pm_ops = {
static struct platform_driver rembrandt_driver = {
.probe = rembrandt_audio_probe,
.remove_new = rembrandt_audio_remove,
.remove = rembrandt_audio_remove,
.driver = {
.name = "acp_asoc_rembrandt",
.pm = &rmb_dma_pm_ops,

View File

@ -244,7 +244,7 @@ static const struct dev_pm_ops rn_dma_pm_ops = {
static struct platform_driver renoir_driver = {
.probe = renoir_audio_probe,
.remove_new = renoir_audio_remove,
.remove = renoir_audio_remove,
.driver = {
.name = "acp_asoc_renoir",
.pm = &rn_dma_pm_ops,

View File

@ -0,0 +1,509 @@
// 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,
};
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 asoc_sdw_dailink *sof_dai,
struct snd_soc_dai_link **dai_links,
int *be_id, struct snd_soc_codec_conf **codec_conf)
{
struct device *dev = card->dev;
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 asoc_sdw_endpoint *sof_end;
int cpu_pin_id;
int stream;
int ret;
list_for_each_entry(sof_end, &sof_dai->endpoints, list) {
if (sof_end->name_prefix) {
(*codec_conf)->dlc.name = sof_end->codec_name;
(*codec_conf)->name_prefix = sof_end->name_prefix;
(*codec_conf)++;
}
if (sof_end->include_sidecar) {
ret = sof_end->codec_info->add_sidecar(card, dai_links, codec_conf);
if (ret)
return ret;
}
}
for_each_pcm_streams(stream) {
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",
};
struct snd_soc_dai_link_ch_map *codec_maps;
struct snd_soc_dai_link_component *codecs;
struct snd_soc_dai_link_component *cpus;
int num_cpus = hweight32(sof_dai->link_mask[stream]);
int num_codecs = sof_dai->num_devs[stream];
int playback, capture;
int i = 0, j = 0;
char *name;
if (!sof_dai->num_devs[stream])
continue;
sof_end = list_first_entry(&sof_dai->endpoints,
struct asoc_sdw_endpoint, list);
*be_id = sof_end->dai_info->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(ffs(sof_end->link_mask - 1),
*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],
ffs(sof_end->link_mask) - 1,
cpu_pin_id,
type_strings[sof_end->dai_info->dai_type]);
} else {
name = devm_kasprintf(dev, GFP_KERNEL,
sdw_stream_name[stream],
ffs(sof_end->link_mask) - 1,
cpu_pin_id);
}
if (!name)
return -ENOMEM;
cpus = devm_kcalloc(dev, num_cpus, sizeof(*cpus), GFP_KERNEL);
if (!cpus)
return -ENOMEM;
codecs = devm_kcalloc(dev, num_codecs, sizeof(*codecs), GFP_KERNEL);
if (!codecs)
return -ENOMEM;
codec_maps = devm_kcalloc(dev, num_codecs, sizeof(*codec_maps), GFP_KERNEL);
if (!codec_maps)
return -ENOMEM;
list_for_each_entry(sof_end, &sof_dai->endpoints, list) {
if (!sof_end->dai_info->direction[stream])
continue;
int link_num = ffs(sof_end->link_mask) - 1;
cpus[i].dai_name = devm_kasprintf(dev, GFP_KERNEL,
"SDW%d Pin%d",
link_num, cpu_pin_id);
dev_dbg(dev, "cpu[%d].dai_name:%s\n", i, cpus[i].dai_name);
if (!cpus[i].dai_name)
return -ENOMEM;
codec_maps[j].cpu = i;
codec_maps[j].codec = j;
codecs[j].name = sof_end->codec_name;
codecs[j].dai_name = sof_end->dai_info->dai_name;
j++;
}
WARN_ON(j != num_codecs);
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, 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
* based on wait_for_completion(), tag them as 'nonatomic'.
*/
(*dai_links)->nonatomic = true;
(*dai_links)->ch_maps = codec_maps;
list_for_each_entry(sof_end, &sof_dai->endpoints, list) {
if (sof_end->dai_info->init)
sof_end->dai_info->init(card, *dai_links,
sof_end->codec_info,
playback);
}
(*dai_links)++;
}
return 0;
}
static int create_sdw_dailinks(struct snd_soc_card *card,
struct snd_soc_dai_link **dai_links, int *be_id,
struct asoc_sdw_dailink *sof_dais,
struct snd_soc_codec_conf **codec_conf)
{
int ret;
/* generate DAI links by each sdw link */
while (sof_dais->initialised) {
int current_be_id;
ret = create_sdw_dailink(card, sof_dais, dai_links,
&current_be_id, codec_conf);
if (ret)
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;
sof_dais++;
}
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;
struct snd_soc_codec_conf *codec_conf;
struct asoc_sdw_endpoint *sof_ends;
struct asoc_sdw_dailink *sof_dais;
struct snd_soc_dai_link *dai_links;
int num_devs = 0;
int num_ends = 0;
int num_links;
int be_id = 0;
int ret;
ret = asoc_sdw_count_sdw_endpoints(card, &num_devs, &num_ends);
if (ret < 0) {
dev_err(dev, "failed to count devices/endpoints: %d\n", ret);
return ret;
}
/* One per DAI link, worst case is a DAI link for every endpoint */
sof_dais = kcalloc(num_ends, sizeof(*sof_dais), GFP_KERNEL);
if (!sof_dais)
return -ENOMEM;
/* One per endpoint, ie. each DAI on each codec/amp */
sof_ends = kcalloc(num_ends, sizeof(*sof_ends), GFP_KERNEL);
if (!sof_ends) {
ret = -ENOMEM;
goto err_dai;
}
ret = asoc_sdw_parse_sdw_endpoints(card, sof_dais, sof_ends, &num_devs);
if (ret < 0)
goto err_end;
sdw_be_num = 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);
codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL);
if (!codec_conf) {
ret = -ENOMEM;
goto err_end;
}
/* 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) {
ret = -ENOMEM;
goto err_end;
}
card->codec_conf = codec_conf;
card->num_configs = num_devs;
card->dai_link = dai_links;
card->num_links = num_links;
/* SDW */
if (sdw_be_num) {
ret = create_sdw_dailinks(card, &dai_links, &be_id,
sof_dais, &codec_conf);
if (ret)
goto err_end;
}
/* dmic */
if (dmic_num > 0) {
if (ctx->ignore_internal_dmic) {
dev_warn(dev, "Ignoring ACP DMIC\n");
} else {
ret = create_dmic_dailinks(card, &dai_links, &be_id);
if (ret)
goto err_end;
}
}
WARN_ON(codec_conf != card->codec_conf + card->num_configs);
WARN_ON(dai_links != card->dai_link + card->num_links);
err_end:
kfree(sof_ends);
err_dai:
kfree(sof_dais);
return ret;
}
/* 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 = 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 <Vijendar.Mukunda@amd.com");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(SND_SOC_SDW_UTILS);

View File

@ -173,11 +173,4 @@ module_platform_driver(acp_asoc_audio);
MODULE_IMPORT_NS(SND_SOC_AMD_MACH);
MODULE_DESCRIPTION("ACP SOF Machine Driver");
MODULE_ALIAS("platform:rt5682-rt1019");
MODULE_ALIAS("platform:rt5682-max");
MODULE_ALIAS("platform:rt5682s-max");
MODULE_ALIAS("platform:rt5682s-rt1019");
MODULE_ALIAS("platform:nau8825-max");
MODULE_ALIAS("platform:rt5682s-hs-rt1019");
MODULE_ALIAS("platform:nau8821-max");
MODULE_LICENSE("GPL v2");

View File

@ -304,7 +304,7 @@ static const struct dev_pm_ops acp63_dma_pm_ops = {
static struct platform_driver acp63_driver = {
.probe = acp63_audio_probe,
.remove_new = acp63_audio_remove,
.remove = acp63_audio_remove,
.driver = {
.name = "acp_asoc_acp63",
.pm = &acp63_dma_pm_ops,

View File

@ -25,14 +25,17 @@
#define DRV_NAME "acp_asoc_acp70"
#define CLK7_CLK0_DFS_CNTL_N1 0X0006C1A4
#define CLK0_DIVIDER 0X19
static struct acp_resource rsrc = {
.offset = 0,
.no_of_ctrls = 2,
.irqp_used = 1,
.soc_mclk = true,
.irq_reg_offset = 0x1a00,
.scratch_reg_offset = 0x12800,
.sram_pte_offset = 0x03802800,
.scratch_reg_offset = 0x10000,
.sram_pte_offset = 0x03800000,
};
static struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_acp_machines[] = {
@ -49,23 +52,23 @@ static struct snd_soc_dai_driver acp70_dai[] = {
.id = I2S_SP_INSTANCE,
.playback = {
.stream_name = "I2S SP Playback",
.rates = SNDRV_PCM_RATE_8000_96000,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 8,
.channels_max = 32,
.rate_min = 8000,
.rate_max = 96000,
.rate_max = 192000,
},
.capture = {
.stream_name = "I2S SP Capture",
.rates = SNDRV_PCM_RATE_8000_48000,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 2,
.channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
.rate_max = 192000,
},
.ops = &asoc_acp_cpu_dai_ops,
},
@ -74,23 +77,23 @@ static struct snd_soc_dai_driver acp70_dai[] = {
.id = I2S_BT_INSTANCE,
.playback = {
.stream_name = "I2S BT Playback",
.rates = SNDRV_PCM_RATE_8000_96000,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 8,
.channels_max = 32,
.rate_min = 8000,
.rate_max = 96000,
.rate_max = 192000,
},
.capture = {
.stream_name = "I2S BT Capture",
.rates = SNDRV_PCM_RATE_8000_48000,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 2,
.channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
.rate_max = 192000,
},
.ops = &asoc_acp_cpu_dai_ops,
},
@ -99,23 +102,23 @@ static struct snd_soc_dai_driver acp70_dai[] = {
.id = I2S_HS_INSTANCE,
.playback = {
.stream_name = "I2S HS Playback",
.rates = SNDRV_PCM_RATE_8000_96000,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 8,
.channels_max = 32,
.rate_min = 8000,
.rate_max = 96000,
.rate_max = 192000,
},
.capture = {
.stream_name = "I2S HS Capture",
.rates = SNDRV_PCM_RATE_8000_48000,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 8,
.channels_max = 32,
.rate_min = 8000,
.rate_max = 48000,
.rate_max = 192000,
},
.ops = &asoc_acp_cpu_dai_ops,
},
@ -134,12 +137,36 @@ static struct snd_soc_dai_driver acp70_dai[] = {
},
};
static int acp70_i2s_master_clock_generate(struct acp_dev_data *adata)
{
struct pci_dev *smn_dev;
u32 device_id;
if (adata->platform == ACP70)
device_id = 0x1507;
else if (adata->platform == ACP71)
device_id = 0x1122;
else
return -ENODEV;
smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, device_id, NULL);
if (!smn_dev)
return -ENODEV;
/* Set clk7 DFS clock divider register value to get mclk as 196.608MHz*/
smn_write(smn_dev, CLK7_CLK0_DFS_CNTL_N1, CLK0_DIVIDER);
return 0;
}
static int acp_acp70_audio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct acp_chip_info *chip;
struct acp_dev_data *adata;
struct resource *res;
int ret;
chip = dev_get_platdata(&pdev->dev);
if (!chip || !chip->base) {
@ -147,7 +174,11 @@ static int acp_acp70_audio_probe(struct platform_device *pdev)
return -ENODEV;
}
if (chip->acp_rev != ACP70_DEV) {
switch (chip->acp_rev) {
case ACP70_DEV:
case ACP71_DEV:
break;
default:
dev_err(&pdev->dev, "Un-supported ACP Revision %d\n", chip->acp_rev);
return -ENODEV;
}
@ -178,11 +209,21 @@ static int acp_acp70_audio_probe(struct platform_device *pdev)
adata->num_dai = ARRAY_SIZE(acp70_dai);
adata->rsrc = &rsrc;
adata->machines = snd_soc_acpi_amd_acp70_acp_machines;
if (chip->acp_rev == ACP70_DEV)
adata->platform = ACP70;
else
adata->platform = ACP71;
adata->flag = chip->flag;
acp_machine_select(adata);
dev_set_drvdata(dev, adata);
ret = acp70_i2s_master_clock_generate(adata);
if (ret) {
dev_err(&pdev->dev, "Failed to set I2S master clock as 196.608MHz\n");
return ret;
}
acp_enable_interrupts(adata);
acp_platform_register(dev);
pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
@ -237,7 +278,7 @@ static const struct dev_pm_ops acp70_dma_pm_ops = {
static struct platform_driver acp70_driver = {
.probe = acp_acp70_audio_probe,
.remove_new = acp_acp70_audio_remove,
.remove = acp_acp70_audio_remove,
.driver = {
.name = "acp_asoc_acp70",
.pm = &acp70_dma_pm_ops,

View File

@ -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("Vijendar.Mukunda@amd.com");

View File

@ -22,6 +22,7 @@
#define ACP6X_DEV 6
#define ACP63_DEV 0x63
#define ACP70_DEV 0x70
#define ACP71_DEV 0x71
#define DMIC_INSTANCE 0x00
#define I2S_SP_INSTANCE 0x01
@ -61,6 +62,14 @@
#define I2S_HS_TX_MEM_WINDOW_START 0x40A0000
#define I2S_HS_RX_MEM_WINDOW_START 0x40C0000
#define ACP7x_I2S_SP_TX_MEM_WINDOW_START 0x4000000
#define ACP7x_I2S_SP_RX_MEM_WINDOW_START 0x4200000
#define ACP7x_I2S_BT_TX_MEM_WINDOW_START 0x4400000
#define ACP7x_I2S_BT_RX_MEM_WINDOW_START 0x4600000
#define ACP7x_I2S_HS_TX_MEM_WINDOW_START 0x4800000
#define ACP7x_I2S_HS_RX_MEM_WINDOW_START 0x4A00000
#define ACP7x_DMIC_MEM_WINDOW_START 0x4C00000
#define SP_PB_FIFO_ADDR_OFFSET 0x500
#define SP_CAPT_FIFO_ADDR_OFFSET 0x700
#define BT_PB_FIFO_ADDR_OFFSET 0x900
@ -103,6 +112,8 @@
#define ACP70_PGFSM_CONTROL ACP6X_PGFSM_CONTROL
#define ACP70_PGFSM_STATUS ACP6X_PGFSM_STATUS
#define ACP_ZSC_DSP_CTRL 0x0001014
#define ACP_ZSC_STS 0x0001018
#define ACP_SOFT_RST_DONE_MASK 0x00010001
#define ACP_PGFSM_CNTL_POWER_ON_MASK 0xffffffff
@ -256,12 +267,12 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
switch (dai_id) {
case I2S_BT_INSTANCE:
high = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH);
low = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW);
high = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH(adata));
low = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW(adata));
break;
case I2S_SP_INSTANCE:
high = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH);
low = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW);
high = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH(adata));
low = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW(adata));
break;
case I2S_HS_INSTANCE:
high = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH);
@ -274,12 +285,12 @@ static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int
} else {
switch (dai_id) {
case I2S_BT_INSTANCE:
high = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH);
low = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW);
high = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH(adata));
low = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW(adata));
break;
case I2S_SP_INSTANCE:
high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH);
low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW);
high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH(adata));
low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW(adata));
break;
case I2S_HS_INSTANCE:
high = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH);

View File

@ -12,9 +12,16 @@
#define _ACP_IP_OFFSET_HEADER
#define ACPAXI2AXI_ATU_CTRL 0xC40
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1 0xC00
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_1 0xC04
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2 0xC08
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_2 0xC0C
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5 0xC20
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0xC24
#define GRP1_OFFSET 0x0
#define GRP2_OFFSET 0x4000
#define ACP_PGFSM_CONTROL 0x141C
#define ACP_PGFSM_STATUS 0x1420
#define ACP_SOFT_RESET 0x1000
@ -32,42 +39,47 @@
/* Registers from ACP_AUDIO_BUFFERS block */
#define ACP_I2S_RX_RINGBUFADDR 0x2000
#define ACP_I2S_RX_RINGBUFSIZE 0x2004
#define ACP_I2S_RX_LINKPOSITIONCNTR 0x2008
#define ACP_I2S_RX_FIFOADDR 0x200C
#define ACP_I2S_RX_FIFOSIZE 0x2010
#define ACP_I2S_RX_DMA_SIZE 0x2014
#define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x2018
#define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW 0x201C
#define ACP_I2S_RX_INTR_WATERMARK_SIZE 0x2020
#define ACP_I2S_TX_RINGBUFADDR 0x2024
#define ACP_I2S_TX_RINGBUFSIZE 0x2028
#define ACP_I2S_TX_LINKPOSITIONCNTR 0x202C
#define ACP_I2S_TX_FIFOADDR 0x2030
#define ACP_I2S_TX_FIFOSIZE 0x2034
#define ACP_I2S_TX_DMA_SIZE 0x2038
#define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x203C
#define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW 0x2040
#define ACP_I2S_TX_INTR_WATERMARK_SIZE 0x2044
#define ACP_BT_RX_RINGBUFADDR 0x2048
#define ACP_BT_RX_RINGBUFSIZE 0x204C
#define ACP_BT_RX_LINKPOSITIONCNTR 0x2050
#define ACP_BT_RX_FIFOADDR 0x2054
#define ACP_BT_RX_FIFOSIZE 0x2058
#define ACP_BT_RX_DMA_SIZE 0x205C
#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH 0x2060
#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW 0x2064
#define ACP_BT_RX_INTR_WATERMARK_SIZE 0x2068
#define ACP_BT_TX_RINGBUFADDR 0x206C
#define ACP_BT_TX_RINGBUFSIZE 0x2070
#define ACP_BT_TX_LINKPOSITIONCNTR 0x2074
#define ACP_BT_TX_FIFOADDR 0x2078
#define ACP_BT_TX_FIFOSIZE 0x207C
#define ACP_BT_TX_DMA_SIZE 0x2080
#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x2084
#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x2088
#define ACP_BT_TX_INTR_WATERMARK_SIZE 0x208C
#define ACP_I2S_REG_ADDR(acp_adata, addr) \
((addr) + (acp_adata->rsrc->irqp_used * \
acp_adata->rsrc->irq_reg_offset))
#define ACP_I2S_RX_RINGBUFADDR(adata) ACP_I2S_REG_ADDR(adata, 0x2000)
#define ACP_I2S_RX_RINGBUFSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2004)
#define ACP_I2S_RX_LINKPOSITIONCNTR(adata) ACP_I2S_REG_ADDR(adata, 0x2008)
#define ACP_I2S_RX_FIFOADDR(adata) ACP_I2S_REG_ADDR(adata, 0x200C)
#define ACP_I2S_RX_FIFOSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2010)
#define ACP_I2S_RX_DMA_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2014)
#define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH(adata) ACP_I2S_REG_ADDR(adata, 0x2018)
#define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW(adata) ACP_I2S_REG_ADDR(adata, 0x201C)
#define ACP_I2S_RX_INTR_WATERMARK_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2020)
#define ACP_I2S_TX_RINGBUFADDR(adata) ACP_I2S_REG_ADDR(adata, 0x2024)
#define ACP_I2S_TX_RINGBUFSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2028)
#define ACP_I2S_TX_LINKPOSITIONCNTR(adata) ACP_I2S_REG_ADDR(adata, 0x202C)
#define ACP_I2S_TX_FIFOADDR(adata) ACP_I2S_REG_ADDR(adata, 0x2030)
#define ACP_I2S_TX_FIFOSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2034)
#define ACP_I2S_TX_DMA_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2038)
#define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH(adata) ACP_I2S_REG_ADDR(adata, 0x203C)
#define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW(adata) ACP_I2S_REG_ADDR(adata, 0x2040)
#define ACP_I2S_TX_INTR_WATERMARK_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2044)
#define ACP_BT_RX_RINGBUFADDR(adata) ACP_I2S_REG_ADDR(adata, 0x2048)
#define ACP_BT_RX_RINGBUFSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x204C)
#define ACP_BT_RX_LINKPOSITIONCNTR(adata) ACP_I2S_REG_ADDR(adata, 0x2050)
#define ACP_BT_RX_FIFOADDR(adata) ACP_I2S_REG_ADDR(adata, 0x2054)
#define ACP_BT_RX_FIFOSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2058)
#define ACP_BT_RX_DMA_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x205C)
#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH(adata) ACP_I2S_REG_ADDR(adata, 0x2060)
#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW(adata) ACP_I2S_REG_ADDR(adata, 0x2064)
#define ACP_BT_RX_INTR_WATERMARK_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2068)
#define ACP_BT_TX_RINGBUFADDR(adata) ACP_I2S_REG_ADDR(adata, 0x206C)
#define ACP_BT_TX_RINGBUFSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2070)
#define ACP_BT_TX_LINKPOSITIONCNTR(adata) ACP_I2S_REG_ADDR(adata, 0x2074)
#define ACP_BT_TX_FIFOADDR(adata) ACP_I2S_REG_ADDR(adata, 0x2078)
#define ACP_BT_TX_FIFOSIZE(adata) ACP_I2S_REG_ADDR(adata, 0x207C)
#define ACP_BT_TX_DMA_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x2080)
#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH(adata) ACP_I2S_REG_ADDR(adata, 0x2084)
#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW(adata) ACP_I2S_REG_ADDR(adata, 0x2088)
#define ACP_BT_TX_INTR_WATERMARK_SIZE(adata) ACP_I2S_REG_ADDR(adata, 0x208C)
#define ACP_HS_RX_RINGBUFADDR 0x3A90
#define ACP_HS_RX_RINGBUFSIZE 0x3A94
#define ACP_HS_RX_LINKPOSITIONCNTR 0x3A98

View File

@ -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

View File

@ -23,6 +23,8 @@ 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[];
extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sof_machines[];
struct config_entry {
u32 flags;

View File

@ -448,7 +448,7 @@ static const struct dev_pm_ops acp63_pdm_pm_ops = {
static struct platform_driver acp63_pdm_dma_driver = {
.probe = acp63_pdm_audio_probe,
.remove_new = acp63_pdm_audio_remove,
.remove = acp63_pdm_audio_remove,
.driver = {
.name = "acp_ps_pdm_dma",
.pm = &acp63_pdm_pm_ops,

View File

@ -551,7 +551,7 @@ static const struct dev_pm_ops acp63_pm_ops = {
static struct platform_driver acp63_sdw_dma_driver = {
.probe = acp63_sdw_platform_probe,
.remove_new = acp63_sdw_platform_remove,
.remove = acp63_sdw_platform_remove,
.driver = {
.name = "amd_ps_sdw_dma",
.pm = &acp63_pm_ops,

View File

@ -509,7 +509,7 @@ static const struct dev_pm_ops acp3x_pm_ops = {
static struct platform_driver acp3x_dma_driver = {
.probe = acp3x_audio_probe,
.remove_new = acp3x_audio_remove,
.remove = acp3x_audio_remove,
.driver = {
.name = "acp3x_rv_i2s_dma",
.pm = &acp3x_pm_ops,

View File

@ -489,7 +489,7 @@ static const struct dev_pm_ops acp_pdm_pm_ops = {
static struct platform_driver acp_pdm_dma_driver = {
.probe = acp_pdm_audio_probe,
.remove_new = acp_pdm_audio_remove,
.remove = acp_pdm_audio_remove,
.driver = {
.name = "acp_rn_pdm_dma",
.pm = &acp_pdm_pm_ops,

View File

@ -499,7 +499,7 @@ static const struct dev_pm_ops acp5x_pm_ops = {
static struct platform_driver acp5x_dma_driver = {
.probe = acp5x_audio_probe,
.remove_new = acp5x_audio_remove,
.remove = acp5x_audio_remove,
.driver = {
.name = "acp5x_i2s_dma",
.pm = &acp5x_pm_ops,

View File

@ -440,7 +440,7 @@ static const struct dev_pm_ops acp6x_pdm_pm_ops = {
static struct platform_driver acp6x_pdm_dma_driver = {
.probe = acp6x_pdm_audio_probe,
.remove_new = acp6x_pdm_audio_remove,
.remove = acp6x_pdm_audio_remove,
.driver = {
.name = "acp_yc_pdm_dma",
.pm = &acp6x_pdm_pm_ops,

View File

@ -1179,7 +1179,7 @@ static struct platform_driver apple_mca_driver = {
.of_match_table = apple_mca_of_match,
},
.probe = apple_mca_probe,
.remove_new = apple_mca_remove,
.remove = apple_mca_remove,
};
module_platform_driver(apple_mca_driver);

View File

@ -733,7 +733,7 @@ static struct platform_driver atmel_i2s_driver = {
.of_match_table = atmel_i2s_dt_ids,
},
.probe = atmel_i2s_probe,
.remove_new = atmel_i2s_remove,
.remove = atmel_i2s_remove,
};
module_platform_driver(atmel_i2s_driver);

View File

@ -187,7 +187,7 @@ static struct platform_driver atmel_asoc_wm8904_driver = {
.pm = &snd_soc_pm_ops,
},
.probe = atmel_asoc_wm8904_probe,
.remove_new = atmel_asoc_wm8904_remove,
.remove = atmel_asoc_wm8904_remove,
};
module_platform_driver(atmel_asoc_wm8904_driver);

View File

@ -221,6 +221,15 @@
#define MCHP_I2SMCC_MAX_CHANNELS 8
#define MCHP_I2MCC_TDM_SLOT_WIDTH 32
/*
* ---- DMA chunk size allowed ----
*/
#define MCHP_I2SMCC_DMA_8_WORD_CHUNK 8
#define MCHP_I2SMCC_DMA_4_WORD_CHUNK 4
#define MCHP_I2SMCC_DMA_2_WORD_CHUNK 2
#define MCHP_I2SMCC_DMA_1_WORD_CHUNK 1
#define DMA_BURST_ALIGNED(_p, _s, _w) !(_p % (_s * _w))
static const struct regmap_config mchp_i2s_mcc_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@ -504,12 +513,30 @@ static int mchp_i2s_mcc_is_running(struct mchp_i2s_mcc_dev *dev)
return !!(sr & (MCHP_I2SMCC_SR_TXEN | MCHP_I2SMCC_SR_RXEN));
}
static inline int mchp_i2s_mcc_period_to_maxburst(int period_size, int sample_size)
{
int p_size = period_size;
int s_size = sample_size;
if (DMA_BURST_ALIGNED(p_size, s_size, MCHP_I2SMCC_DMA_8_WORD_CHUNK))
return MCHP_I2SMCC_DMA_8_WORD_CHUNK;
if (DMA_BURST_ALIGNED(p_size, s_size, MCHP_I2SMCC_DMA_4_WORD_CHUNK))
return MCHP_I2SMCC_DMA_4_WORD_CHUNK;
if (DMA_BURST_ALIGNED(p_size, s_size, MCHP_I2SMCC_DMA_2_WORD_CHUNK))
return MCHP_I2SMCC_DMA_2_WORD_CHUNK;
return MCHP_I2SMCC_DMA_1_WORD_CHUNK;
}
static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
unsigned long rate = 0;
struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai);
int sample_bytes = params_physical_width(params) / 8;
int period_bytes = params_period_size(params) *
params_channels(params) * sample_bytes;
int maxburst;
u32 mra = 0;
u32 mrb = 0;
unsigned int channels = params_channels(params);
@ -519,9 +546,9 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
int ret;
bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u\n",
dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u period_bytes=%d\n",
__func__, params_rate(params), params_format(params),
params_width(params), params_channels(params));
params_width(params), params_channels(params), period_bytes);
switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
@ -630,11 +657,12 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
* We must have the same burst size configured
* in the DMA transfer and in out IP
*/
mrb |= MCHP_I2SMCC_MRB_DMACHUNK(channels);
maxburst = mchp_i2s_mcc_period_to_maxburst(period_bytes, sample_bytes);
mrb |= MCHP_I2SMCC_MRB_DMACHUNK(maxburst);
if (is_playback)
dev->playback.maxburst = 1 << (fls(channels) - 1);
dev->playback.maxburst = maxburst;
else
dev->capture.maxburst = 1 << (fls(channels) - 1);
dev->capture.maxburst = maxburst;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S8:
@ -908,14 +936,14 @@ static const struct snd_soc_dai_ops mchp_i2s_mcc_dai_ops = {
static struct snd_soc_dai_driver mchp_i2s_mcc_dai = {
.playback = {
.stream_name = "I2SMCC-Playback",
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 8,
.rates = MCHP_I2SMCC_RATES,
.formats = MCHP_I2SMCC_FORMATS,
},
.capture = {
.stream_name = "I2SMCC-Capture",
.stream_name = "Capture",
.channels_min = 1,
.channels_max = 8,
.rates = MCHP_I2SMCC_RATES,
@ -1101,7 +1129,7 @@ static struct platform_driver mchp_i2s_mcc_driver = {
.of_match_table = mchp_i2s_mcc_dt_ids,
},
.probe = mchp_i2s_mcc_probe,
.remove_new = mchp_i2s_mcc_remove,
.remove = mchp_i2s_mcc_remove,
};
module_platform_driver(mchp_i2s_mcc_driver);

View File

@ -90,6 +90,15 @@
#define MCHP_PDMC_DS_NO 2
#define MCHP_PDMC_EDGE_NO 2
/*
* ---- DMA chunk size allowed ----
*/
#define MCHP_PDMC_DMA_8_WORD_CHUNK 8
#define MCHP_PDMC_DMA_4_WORD_CHUNK 4
#define MCHP_PDMC_DMA_2_WORD_CHUNK 2
#define MCHP_PDMC_DMA_1_WORD_CHUNK 1
#define DMA_BURST_ALIGNED(_p, _s, _w) !(_p % (_s * _w))
struct mic_map {
int ds_pos;
int clk_edge;
@ -115,6 +124,7 @@ struct mchp_pdmc {
int mic_no;
int sinc_order;
bool audio_filter_en;
atomic_t busy_stream;
};
static const char *const mchp_pdmc_sinc_filter_order_text[] = {
@ -158,6 +168,10 @@ static int mchp_pdmc_sinc_order_put(struct snd_kcontrol *kcontrol,
return -EINVAL;
val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
if (atomic_read(&dd->busy_stream))
return -EBUSY;
if (val == dd->sinc_order)
return 0;
@ -184,6 +198,9 @@ static int mchp_pdmc_af_put(struct snd_kcontrol *kcontrol,
struct mchp_pdmc *dd = snd_soc_component_get_drvdata(component);
bool af = uvalue->value.integer.value[0] ? true : false;
if (atomic_read(&dd->busy_stream))
return -EBUSY;
if (dd->audio_filter_en == af)
return 0;
@ -370,52 +387,10 @@ static const struct snd_kcontrol_new mchp_pdmc_snd_controls[] = {
},
};
static int mchp_pdmc_close(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
return snd_soc_add_component_controls(component, mchp_pdmc_snd_controls,
ARRAY_SIZE(mchp_pdmc_snd_controls));
}
static int mchp_pdmc_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
int i;
/* remove controls that can't be changed at runtime */
for (i = 0; i < ARRAY_SIZE(mchp_pdmc_snd_controls); i++) {
const struct snd_kcontrol_new *control = &mchp_pdmc_snd_controls[i];
struct snd_ctl_elem_id id;
int err;
if (component->name_prefix)
snprintf(id.name, sizeof(id.name), "%s %s", component->name_prefix,
control->name);
else
strscpy(id.name, control->name, sizeof(id.name));
id.numid = 0;
id.iface = control->iface;
id.device = control->device;
id.subdevice = control->subdevice;
id.index = control->index;
err = snd_ctl_remove_id(component->card->snd_card, &id);
if (err < 0)
dev_err(component->dev, "%d: Failed to remove %s\n", err,
control->name);
}
return 0;
}
static const struct snd_soc_component_driver mchp_pdmc_dai_component = {
.name = "mchp-pdmc",
.controls = mchp_pdmc_snd_controls,
.num_controls = ARRAY_SIZE(mchp_pdmc_snd_controls),
.open = &mchp_pdmc_open,
.close = &mchp_pdmc_close,
.legacy_dai_naming = 1,
.trigger_start = SND_SOC_TRIGGER_ORDER_LDC,
};
static const unsigned int mchp_pdmc_1mic[] = {1};
@ -511,15 +486,18 @@ static u32 mchp_pdmc_mr_set_osr(int audio_filter_en, unsigned int osr)
return 0;
}
static inline int mchp_pdmc_period_to_maxburst(int period_size)
static inline int mchp_pdmc_period_to_maxburst(int period_size, int sample_size)
{
if (!(period_size % 8))
return 8;
if (!(period_size % 4))
return 4;
if (!(period_size % 2))
return 2;
return 1;
int p_size = period_size;
int s_size = sample_size;
if (DMA_BURST_ALIGNED(p_size, s_size, MCHP_PDMC_DMA_8_WORD_CHUNK))
return MCHP_PDMC_DMA_8_WORD_CHUNK;
if (DMA_BURST_ALIGNED(p_size, s_size, MCHP_PDMC_DMA_4_WORD_CHUNK))
return MCHP_PDMC_DMA_4_WORD_CHUNK;
if (DMA_BURST_ALIGNED(p_size, s_size, MCHP_PDMC_DMA_2_WORD_CHUNK))
return MCHP_PDMC_DMA_2_WORD_CHUNK;
return MCHP_PDMC_DMA_1_WORD_CHUNK;
}
static struct snd_pcm_chmap_elem mchp_pdmc_std_chmaps[] = {
@ -547,14 +525,18 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
unsigned int channels = params_channels(params);
unsigned int osr = 0, osr_start;
unsigned int fs = params_rate(params);
int sample_bytes = params_physical_width(params) / 8;
int period_bytes = params_period_size(params) *
params_channels(params) * sample_bytes;
int maxburst;
u32 mr_val = 0;
u32 cfgr_val = 0;
int i;
int ret;
dev_dbg(comp->dev, "%s() rate=%u format=%#x width=%u channels=%u\n",
dev_dbg(comp->dev, "%s() rate=%u format=%#x width=%u channels=%u period_bytes=%d\n",
__func__, params_rate(params), params_format(params),
params_width(params), params_channels(params));
params_width(params), params_channels(params), period_bytes);
if (channels > dd->mic_no) {
dev_err(comp->dev, "more channels %u than microphones %d\n",
@ -571,6 +553,11 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
cfgr_val |= MCHP_PDMC_CFGR_BSSEL(i);
}
/*
* from these point forward, we consider the controller busy, so the
* audio filter and SINC order can't be changed
*/
atomic_set(&dd->busy_stream, 1);
for (osr_start = dd->audio_filter_en ? 64 : 8;
osr_start <= 256 && best_diff_rate; osr_start *= 2) {
long round_rate;
@ -608,7 +595,8 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
mr_val |= FIELD_PREP(MCHP_PDMC_MR_SINCORDER_MASK, dd->sinc_order);
dd->addr.maxburst = mchp_pdmc_period_to_maxburst(snd_pcm_lib_period_bytes(substream));
maxburst = mchp_pdmc_period_to_maxburst(period_bytes, sample_bytes);
dd->addr.maxburst = maxburst;
mr_val |= FIELD_PREP(MCHP_PDMC_MR_CHUNK_MASK, dd->addr.maxburst);
dev_dbg(comp->dev, "maxburst set to %d\n", dd->addr.maxburst);
@ -760,6 +748,7 @@ static const struct snd_soc_dai_ops mchp_pdmc_dai_ops = {
};
static struct snd_soc_dai_driver mchp_pdmc_dai = {
.name = "mchp-pdmc",
.capture = {
.stream_name = "Capture",
.channels_min = 1,
@ -1125,6 +1114,8 @@ static void mchp_pdmc_remove(struct platform_device *pdev)
{
struct mchp_pdmc *dd = platform_get_drvdata(pdev);
atomic_set(&dd->busy_stream, 0);
if (!pm_runtime_status_suspended(dd->dev))
mchp_pdmc_runtime_suspend(dd->dev);
@ -1153,7 +1144,7 @@ static struct platform_driver mchp_pdmc_driver = {
.pm = pm_ptr(&mchp_pdmc_pm_ops),
},
.probe = mchp_pdmc_probe,
.remove_new = mchp_pdmc_remove,
.remove = mchp_pdmc_remove,
};
module_platform_driver(mchp_pdmc_driver);

View File

@ -1194,7 +1194,7 @@ static void mchp_spdifrx_remove(struct platform_device *pdev)
static struct platform_driver mchp_spdifrx_driver = {
.probe = mchp_spdifrx_probe,
.remove_new = mchp_spdifrx_remove,
.remove = mchp_spdifrx_remove,
.driver = {
.name = "mchp_spdifrx",
.of_match_table = mchp_spdifrx_dt_ids,

View File

@ -888,7 +888,7 @@ static void mchp_spdiftx_remove(struct platform_device *pdev)
static struct platform_driver mchp_spdiftx_driver = {
.probe = mchp_spdiftx_probe,
.remove_new = mchp_spdiftx_remove,
.remove = mchp_spdiftx_remove,
.driver = {
.name = "mchp_spdiftx",
.of_match_table = mchp_spdiftx_dt_ids,

View File

@ -207,7 +207,7 @@ static struct platform_driver at91sam9g20ek_audio_driver = {
.of_match_table = of_match_ptr(at91sam9g20ek_wm8731_dt_ids),
},
.probe = at91sam9g20ek_audio_probe,
.remove_new = at91sam9g20ek_audio_remove,
.remove = at91sam9g20ek_audio_remove,
};
module_platform_driver(at91sam9g20ek_audio_driver);

View File

@ -196,7 +196,7 @@ static struct platform_driver sam9x5_wm8731_driver = {
.of_match_table = of_match_ptr(sam9x5_wm8731_of_match),
},
.probe = sam9x5_wm8731_driver_probe,
.remove_new = sam9x5_wm8731_driver_remove,
.remove = sam9x5_wm8731_driver_remove,
};
module_platform_driver(sam9x5_wm8731_driver);

View File

@ -431,7 +431,7 @@ static struct platform_driver tse850_driver = {
.of_match_table = tse850_dt_ids,
},
.probe = tse850_probe,
.remove_new = tse850_remove,
.remove = tse850_remove,
};
module_platform_driver(tse850_driver);

View File

@ -336,7 +336,7 @@ static struct platform_driver au1xac97c_driver = {
.pm = AU1XPSCAC97_PMOPS,
},
.probe = au1xac97c_drvprobe,
.remove_new = au1xac97c_drvremove,
.remove = au1xac97c_drvremove,
};
module_platform_driver(au1xac97c_driver);

View File

@ -313,7 +313,7 @@ static struct platform_driver au1xi2s_driver = {
.pm = AU1XI2SC_PMOPS,
},
.probe = au1xi2s_drvprobe,
.remove_new = au1xi2s_drvremove,
.remove = au1xi2s_drvremove,
};
module_platform_driver(au1xi2s_driver);

View File

@ -486,7 +486,7 @@ static struct platform_driver au1xpsc_ac97_driver = {
.pm = AU1XPSCAC97_PMOPS,
},
.probe = au1xpsc_ac97_drvprobe,
.remove_new = au1xpsc_ac97_drvremove,
.remove = au1xpsc_ac97_drvremove,
};
module_platform_driver(au1xpsc_ac97_driver);

View File

@ -404,7 +404,7 @@ static struct platform_driver au1xpsc_i2s_driver = {
.pm = AU1XPSCI2S_PMOPS,
},
.probe = au1xpsc_i2s_drvprobe,
.remove_new = au1xpsc_i2s_drvremove,
.remove = au1xpsc_i2s_drvremove,
};
module_platform_driver(au1xpsc_i2s_driver);

View File

@ -293,7 +293,7 @@ static struct platform_driver bcm63xx_i2s_driver = {
.of_match_table = of_match_ptr(snd_soc_bcm_audio_match),
},
.probe = bcm63xx_i2s_dev_probe,
.remove_new = bcm63xx_i2s_dev_remove,
.remove = bcm63xx_i2s_dev_remove,
};
module_platform_driver(bcm63xx_i2s_driver);

View File

@ -1390,7 +1390,7 @@ MODULE_DEVICE_TABLE(of, cygnus_ssp_of_match);
static struct platform_driver cygnus_ssp_driver = {
.probe = cygnus_ssp_probe,
.remove_new = cygnus_ssp_remove,
.remove = cygnus_ssp_remove,
.driver = {
.name = "cygnus-ssp",
.of_match_table = cygnus_ssp_of_match,

View File

@ -105,7 +105,7 @@ static struct platform_driver edb93xx_driver = {
.name = "edb93xx-audio",
},
.probe = edb93xx_probe,
.remove_new = edb93xx_remove,
.remove = edb93xx_remove,
};
module_platform_driver(edb93xx_driver);

View File

@ -523,7 +523,7 @@ MODULE_DEVICE_TABLE(of, ep93xx_i2s_of_ids);
static struct platform_driver ep93xx_i2s_driver = {
.probe = ep93xx_i2s_probe,
.remove_new = ep93xx_i2s_remove,
.remove = ep93xx_i2s_remove,
.driver = {
.name = "ep93xx-i2s",
.of_match_table = ep93xx_i2s_of_ids,

View File

@ -157,6 +157,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_MC13783
imply SND_SOC_ML26124
imply SND_SOC_MT6351
imply SND_SOC_MT6357
imply SND_SOC_MT6358
imply SND_SOC_MT6359
imply SND_SOC_MT6660
@ -2501,6 +2502,12 @@ config SND_SOC_ML26124
config SND_SOC_MT6351
tristate "MediaTek MT6351 Codec"
config SND_SOC_MT6357
tristate "MediaTek MT6357 Codec"
help
Enable support for the platform which uses MT6357 as
external codec device.
config SND_SOC_MT6358
tristate "MediaTek MT6358 Codec"
help

View File

@ -177,6 +177,7 @@ snd-soc-ml26124-y := ml26124.o
snd-soc-msm8916-analog-y := msm8916-wcd-analog.o
snd-soc-msm8916-digital-y := msm8916-wcd-digital.o
snd-soc-mt6351-y := mt6351.o
snd-soc-mt6357-y := mt6357.o
snd-soc-mt6358-y := mt6358.o
snd-soc-mt6359-y := mt6359.o
snd-soc-mt6359-accdet-y := mt6359-accdet.o
@ -578,6 +579,7 @@ obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o
obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o
obj-$(CONFIG_SND_SOC_MT6351) += snd-soc-mt6351.o
obj-$(CONFIG_SND_SOC_MT6357) += snd-soc-mt6357.o
obj-$(CONFIG_SND_SOC_MT6358) += snd-soc-mt6358.o
obj-$(CONFIG_SND_SOC_MT6359) += snd-soc-mt6359.o
obj-$(CONFIG_SND_SOC_MT6359_ACCDET) += mt6359-accdet.o

View File

@ -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;
}

View File

@ -515,6 +515,49 @@ static void cs_amp_lib_test_get_efi_cal_zero_not_matched_test(struct kunit *test
kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable);
}
/*
* If an entry has a timestamp of 0 it should be ignored even if it has
* a matching target UID.
*/
static void cs_amp_lib_test_get_efi_cal_empty_entry_test(struct kunit *test)
{
struct cs_amp_lib_test_priv *priv = test->priv;
struct cirrus_amp_cal_data result_data;
u64 uid;
cs_amp_lib_test_init_dummy_cal_blob(test, 8);
/* Mark the 3rd entry invalid by zeroing calTime */
priv->cal_blob->data[2].calTime[0] = 0;
priv->cal_blob->data[2].calTime[1] = 0;
/* Get the UID value of the 3rd entry */
uid = priv->cal_blob->data[2].calTarget[1];
uid <<= 32;
uid |= priv->cal_blob->data[2].calTarget[0];
/* Redirect calls to get EFI data */
kunit_activate_static_stub(test,
cs_amp_test_hooks->get_efi_variable,
cs_amp_lib_test_get_efi_variable);
/* Lookup by UID should not find it */
KUNIT_EXPECT_EQ(test,
cs_amp_get_efi_calibration_data(&priv->amp_pdev.dev,
uid, -1,
&result_data),
-ENOENT);
/* Get by index should ignore it */
KUNIT_EXPECT_EQ(test,
cs_amp_get_efi_calibration_data(&priv->amp_pdev.dev,
0, 2,
&result_data),
-ENOENT);
kunit_deactivate_static_stub(test, cs_amp_test_hooks->get_efi_variable);
}
static const struct cirrus_amp_cal_controls cs_amp_lib_test_calibration_controls = {
.alg_id = 0x9f210,
.mem_region = WMFW_ADSP2_YM,
@ -696,6 +739,7 @@ static struct kunit_case cs_amp_lib_test_cases[] = {
cs_amp_lib_test_get_cal_gen_params),
KUNIT_CASE_PARAM(cs_amp_lib_test_get_efi_cal_by_index_fallback_test,
cs_amp_lib_test_get_cal_gen_params),
KUNIT_CASE(cs_amp_lib_test_get_efi_cal_empty_entry_test),
/* Tests for writing calibration data */
KUNIT_CASE(cs_amp_lib_test_write_cal_data_test),

Some files were not shown because too many files have changed in this diff Show More