Merge asoc/for-7.4 into asoc-next

This commit is contained in:
Mark Brown 2026-10-14 17:38:24 +01:00
commit ac32e27bac
575 changed files with 25427 additions and 4348 deletions

View File

@ -52,11 +52,11 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
audio-codec@3c {
compatible = "adi,adau1372";
reg = <0x3c>;
#sound-dai-cells = <0>;
clock-names = "mclk";
clocks = <&adau1372z_xtal>;
compatible = "adi,adau1372";
reg = <0x3c>;
#sound-dai-cells = <0>;
clock-names = "mclk";
clocks = <&adau1372z_xtal>;
};
};

View File

@ -68,20 +68,20 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
adau7118_codec: audio-codec@14 {
compatible = "adi,adau7118";
reg = <0x14>;
#sound-dai-cells = <0>;
iovdd-supply = <&supply>;
dvdd-supply = <&supply>;
adi,pdm-clk-map = <1 1 0 0>;
adi,decimation-ratio = <16>;
compatible = "adi,adau7118";
reg = <0x14>;
#sound-dai-cells = <0>;
iovdd-supply = <&supply>;
dvdd-supply = <&supply>;
adi,pdm-clk-map = <1 1 0 0>;
adi,decimation-ratio = <16>;
};
};
/* example with hw standalone mode */
adau7118_codec_hw: adau7118-codec-hw {
compatible = "adi,adau7118";
#sound-dai-cells = <0>;
iovdd-supply = <&supply>;
dvdd-supply = <&supply>;
compatible = "adi,adau7118";
#sound-dai-cells = <0>;
iovdd-supply = <&supply>;
dvdd-supply = <&supply>;
};

View File

@ -0,0 +1,41 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/airoha,an7581-afe.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Airoha AFE PCM controller for AN7581
maintainers:
- Christian Marangi <ansuelsmth@gmail.com>
properties:
compatible:
const: airoha,an7581-afe
reg:
maxItems: 1
interrupts:
maxItems: 1
required:
- compatible
- reg
- interrupts
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
afe@1fbe2200 {
compatible = "airoha,an7581-afe";
reg = <0x1fbe2200 0x9000>;
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
};
...

View File

@ -0,0 +1,71 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/airoha,an7581-wm8960.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Airoha AN7581 sound card with WM8960 codec
maintainers:
- Christian Marangi <ansuelsmth@gmail.com>
allOf:
- $ref: sound-card-common.yaml#
properties:
compatible:
const: airoha,an7581-wm8960-sound
platform:
type: object
additionalProperties: false
properties:
sound-dai:
items:
- description: The phandle of AN7581 platform.
required:
- sound-dai
codec:
type: object
additionalProperties: false
properties:
sound-dai:
items:
- description: The phandle of WM8960 i2c codec.
required:
- sound-dai
required:
- compatible
- audio-routing
- platform
- codec
unevaluatedProperties: false
examples:
- |
sound {
compatible = "airoha,an7581-wm8960-sound";
model = "an7581-wm8960";
audio-routing =
"Headphone", "HP_L",
"Headphone", "HP_R",
"LINPUT1", "AMIC",
"RINPUT1", "AMIC";
platform {
sound-dai = <&afe>;
};
codec {
sound-dai = <&wm8960>;
};
};

View File

@ -94,20 +94,20 @@ examples:
audio-routing = "I2S ENCODER I2S IN", "I2S FIFO Playback";
dai-link-0 {
sound-dai = <&i2s_fifo>;
sound-dai = <&i2s_fifo>;
};
dai-link-1 {
sound-dai = <&i2s_encoder>;
dai-format = "i2s";
mclk-fs = <256>;
sound-dai = <&i2s_encoder>;
dai-format = "i2s";
mclk-fs = <256>;
codec-0 {
sound-dai = <&codec0>;
};
codec-0 {
sound-dai = <&codec0>;
};
codec-1 {
sound-dai = <&codec1>;
};
codec-1 {
sound-dai = <&codec1>;
};
};
};

View File

@ -34,6 +34,12 @@ properties:
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
powerdown-gpios:
maxItems: 1
description:
GPIO connected to the 'PDN' pin, if any. Needs to be set low to
power down the codec, hence the GPIO must be GPIO_ACTIVE_LOW.
required:
- compatible
- reg
@ -42,6 +48,8 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
@ -49,14 +57,16 @@ examples:
compatible = "asahi-kasei,ak4619";
reg = <0x10>;
powerdown-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
clocks = <&rcar_sound>;
clock-names = "mclk";
#sound-dai-cells = <0>;
port {
ak4619_endpoint: endpoint {
remote-endpoint = <&rsnd_endpoint>;
};
ak4619_endpoint: endpoint {
remote-endpoint = <&rsnd_endpoint>;
};
};
};
};

View File

@ -39,6 +39,7 @@ definitions:
allOf:
- $ref: /schemas/graph.yaml#/$defs/endpoint-base
- $ref: /schemas/sound/dai-params.yaml#
- $ref: /schemas/sound/tdm-slot.yaml#
properties:
mclk-fs:
$ref: simple-card.yaml#/definitions/mclk-fs
@ -48,6 +49,9 @@ definitions:
bitclock-inversion:
description: dai-link uses bit clock inversion
$ref: /schemas/types.yaml#/definitions/flag
continuous-clock:
description: dai-link bit clock runs continuously rather than gated
$ref: /schemas/types.yaml#/definitions/flag
frame-master:
description: Indicates dai-link frame master.
oneOf:
@ -82,12 +86,6 @@ definitions:
- msb
- lsb
dai-tdm-slot-num:
description: Number of slots in use.
$ref: /schemas/types.yaml#/definitions/uint32
dai-tdm-slot-width:
description: Width in bits for each slot.
$ref: /schemas/types.yaml#/definitions/uint32
dai-tdm-slot-width-map:
description: Mapping of sample widths to slot widths. For hardware
that cannot support a fixed slot width or a slot width always

View File

@ -53,6 +53,76 @@ properties:
maximum: 3
default: 2
cirrus,sync-lsw-txid:
description:
Transmitter ID to use for long software (LSW) data packets
on the SYNC bus.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 7
default: 0
cirrus,sync-sw-txid:
description:
Transmitter ID to use for short software (SW) data packets
on the SYNC bus.
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 7
default: 0
cirrus,ldpm-group1-boost-select:
type: boolean
description:
When in a valid group 1 level dependent power management (LDPM) state
the integrated boost converter will enter the configured low power mode.
cirrus,boost-low-power-mode:
description:
Configures the integrated boost converter reaction to a low power mode
request.
0 = No reaction
1 = Force boost DCM low power mode
2 = Force boost static bypass
$ref: /schemas/types.yaml#/definitions/uint32
default: 2
enum:
- 0
- 1
- 2
cirrus,ldpm-group1-amp-select:
type: boolean
description:
When in a valid group 1 level dependent power management (LDPM) state
the amplifier will enter the configured low power mode.
cirrus,amplifier-low-power-mode:
description:
Configures the amplifier output stage reaction to a low power mode
request.
0 = Stop output switching (noise gate mode)
1 = Noise floor reduction mode
$ref: /schemas/types.yaml#/definitions/uint32
default: 1
enum:
- 0
- 1
cirrus,ldpm-group2-vmon-select:
type: boolean
description:
When in a valid group 2 level dependent power management (LDPM) state
the voltage monitor (VMON) circuit is put into a low power operational
state.
cirrus,ldpm-group2-imon-select:
type: boolean
description:
When in a valid group 2 level dependent power management (LDPM) state
the current monitor (IMON) circuit is put into a low power operational
state.
patternProperties:
"^cirrus,gpio-ctrl[1-3]$":
description:
@ -121,6 +191,30 @@ patternProperties:
minimum: 0
maximum: 7
default: 0
"^cirrus,ldpm-group[1-2]-pcm-threshold-db$":
description:
Amplifier level dependent power management (LDPM) threshold. Input
referred threshold of the PCM audio signal in which the level is low
enough for the LDPM group to engage after entry delay. A value of dB
-2147483648 is assumed to mean true zero data with an LSB dither.
$ref: /schemas/types.yaml#/definitions/int32-array
minItems: 1
maxItems: 1
items:
enum: [-2147483648, -102, -96, -90, -84, -78, -72, -66]
"^cirrus,ldpm-group[1-2]-delay-ms$":
description:
Amplifier level dependent power management (LDPM) state entry delay.
Time that the incoming audio signal must be below the PCM threshold
before the LDPM group engages.
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
maxItems: 1
items:
enum: [5, 10, 25, 50, 100, 250, 500, 1000]
required:
- compatible
- reg
@ -135,25 +229,37 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
cs35l45: cs35l45@2 {
#sound-dai-cells = <1>;
compatible = "cirrus,cs35l45";
reg = <2>;
spi-max-frequency = <5000000>;
vdd-a-supply = <&dummy_vreg>;
vdd-batt-supply = <&dummy_vreg>;
reset-gpios = <&gpio 110 0>;
cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED |
CS35L45_ASP_TX_HIZ_DISABLED)>;
cirrus,gpio-ctrl1 {
gpio-ctrl = <0x2>;
};
cirrus,gpio-ctrl2 {
gpio-ctrl = <0x2>;
};
cirrus,gpio-ctrl3 {
gpio-ctrl = <0x1>;
gpio-dir = <0x1>;
};
cs35l45: audio-codec@2 {
#sound-dai-cells = <1>;
compatible = "cirrus,cs35l45";
reg = <2>;
spi-max-frequency = <5000000>;
vdd-a-supply = <&dummy_vreg>;
vdd-batt-supply = <&dummy_vreg>;
reset-gpios = <&gpio 110 0>;
cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED |
CS35L45_ASP_TX_HIZ_DISABLED)>;
cirrus,sync-lsw-txid = <0x1>;
cirrus,sync-sw-txid = <0x1>;
cirrus,ldpm-group1-pcm-threshold-db = <(-66)>;
cirrus,ldpm-group1-delay-ms = <500>;
cirrus,ldpm-group1-boost-select;
cirrus,boost-low-power-mode = <CS35L45_BST_LPMODE_DCM_MODE>;
cirrus,ldpm-group1-amp-select;
cirrus,amplifier-low-power-mode = <CS35L45_AMP_LPMODE_NFR_MODE>;
cirrus,ldpm-group2-pcm-threshold-db = <(-102)>;
cirrus,ldpm-group2-delay-ms = <1000>;
cirrus,ldpm-group2-vmon-select;
cirrus,ldpm-group2-imon-select;
cirrus,gpio-ctrl1 {
gpio-ctrl = <0x2>;
};
cirrus,gpio-ctrl2 {
gpio-ctrl = <0x2>;
};
cirrus,gpio-ctrl3 {
gpio-ctrl = <0x1>;
gpio-dir = <0x1>;
};
};
};

View File

@ -49,11 +49,11 @@ unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
codec@48 {
compatible = "cirrus,cs4270";
reg = <0x48>;
};
codec@48 {
compatible = "cirrus,cs4270";
reg = <0x48>;
};
};

View File

@ -199,28 +199,28 @@ examples:
- |
#include <dt-bindings/sound/cs42l42.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
cs42l42: cs42l42@48 {
compatible = "cirrus,cs42l42";
reg = <0x48>;
VA-supply = <&dummy_vreg>;
VP-supply = <&dummy_vreg>;
VCP-supply = <&dummy_vreg>;
VD_FILT-supply = <&dummy_vreg>;
VL-supply = <&dummy_vreg>;
audio-codec@48 {
compatible = "cirrus,cs42l42";
reg = <0x48>;
VA-supply = <&dummy_vreg>;
VP-supply = <&dummy_vreg>;
VCP-supply = <&dummy_vreg>;
VD_FILT-supply = <&dummy_vreg>;
VL-supply = <&dummy_vreg>;
reset-gpios = <&axi_gpio_0 1 0>;
interrupt-parent = <&gpio0>;
interrupts = <55 8>;
reset-gpios = <&axi_gpio_0 1 0>;
interrupt-parent = <&gpio0>;
interrupts = <55 8>;
cirrus,ts-inv = <CS42L42_TS_INV_DIS>;
cirrus,ts-dbnc-rise = <CS42L42_TS_DBNCE_1000>;
cirrus,ts-dbnc-fall = <CS42L42_TS_DBNCE_0>;
cirrus,btn-det-init-dbnce = <100>;
cirrus,btn-det-event-dbnce = <10>;
cirrus,bias-lvls = <0x0F 0x08 0x04 0x01>;
cirrus,hs-bias-ramp-rate = <CS42L42_HSBIAS_RAMP_SLOW>;
};
cirrus,ts-inv = <CS42L42_TS_INV_DIS>;
cirrus,ts-dbnc-rise = <CS42L42_TS_DBNCE_1000>;
cirrus,ts-dbnc-fall = <CS42L42_TS_DBNCE_0>;
cirrus,btn-det-init-dbnce = <100>;
cirrus,btn-det-event-dbnce = <10>;
cirrus,bias-lvls = <0x0F 0x08 0x04 0x01>;
cirrus,hs-bias-ramp-rate = <CS42L42_HSBIAS_RAMP_SLOW>;
};
};

View File

@ -43,14 +43,14 @@ examples:
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
jack_codec: codec@4b {
compatible = "cirrus,cs42l84";
reg = <0x4b>;
reset-gpios = <&pinctrl_nub 4 GPIO_ACTIVE_LOW>;
interrupts-extended = <&pinctrl_ap 180 IRQ_TYPE_LEVEL_LOW>;
#sound-dai-cells = <0>;
};
jack_codec: codec@4b {
compatible = "cirrus,cs42l84";
reg = <0x4b>;
reset-gpios = <&pinctrl_nub 4 GPIO_ACTIVE_LOW>;
interrupts-extended = <&pinctrl_ap 180 IRQ_TYPE_LEVEL_LOW>;
#sound-dai-cells = <0>;
};
};

View File

@ -75,37 +75,37 @@ unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
codec@48 {
compatible = "cirrus,cs42888";
reg = <0x48>;
clocks = <&codec_mclk 0>;
clock-names = "mclk";
VA-supply = <&reg_audio>;
VD-supply = <&reg_audio>;
VLS-supply = <&reg_audio>;
VLC-supply = <&reg_audio>;
reset-gpios = <&gpio 1>;
};
codec@48 {
compatible = "cirrus,cs42888";
reg = <0x48>;
clocks = <&codec_mclk 0>;
clock-names = "mclk";
VA-supply = <&reg_audio>;
VD-supply = <&reg_audio>;
VLS-supply = <&reg_audio>;
VLC-supply = <&reg_audio>;
reset-gpios = <&gpio 1>;
};
};
spi {
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <&gpio 8 0>;
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <&gpio 8 0>;
codec@0 {
compatible = "cirrus,cs42888";
reg = <0>;
spi-max-frequency = <6000000>;
clocks = <&codec_mclk 0>;
clock-names = "mclk";
VA-supply = <&reg_audio>;
VD-supply = <&reg_audio>;
VLS-supply = <&reg_audio>;
VLC-supply = <&reg_audio>;
reset-gpios = <&gpio 1>;
};
codec@0 {
compatible = "cirrus,cs42888";
reg = <0>;
spi-max-frequency = <6000000>;
clocks = <&codec_mclk 0>;
clock-names = "mclk";
VA-supply = <&reg_audio>;
VD-supply = <&reg_audio>;
VLS-supply = <&reg_audio>;
VLC-supply = <&reg_audio>;
reset-gpios = <&gpio 1>;
};
};

View File

@ -1,49 +0,0 @@
* Texas Instruments SoC audio setups with TLV320AIC3X Codec
Required properties:
- compatible : "ti,da830-evm-audio" : forDM365/DA8xx/OMAPL1x/AM33xx
- ti,model : The user-visible name of this sound complex.
- ti,audio-codec : The phandle of the TLV320AIC3x audio codec
- ti,mcasp-controller : The phandle of the McASP controller
- ti,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 for sources and
sinks are the codec's pins, and the jacks on the board:
Optional properties:
- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec.
- clocks : Reference to the master clock
- clock-names : The clock should be named "mclk"
- Either codec-clock-rate or the codec-clock reference has to be defined. If
the both are defined the driver attempts to set referenced clock to the
defined rate and takes the rate from the clock reference.
Board connectors:
* Headphone Jack
* Line Out
* Mic Jack
* Line In
Example:
sound {
compatible = "ti,da830-evm-audio";
ti,model = "DA830 EVM";
ti,audio-codec = <&tlv320aic3x>;
ti,mcasp-controller = <&mcasp1>;
ti,codec-clock-rate = <12000000>;
ti,audio-routing =
"Headphone Jack", "HPLOUT",
"Headphone Jack", "HPROUT",
"Line Out", "LLOUT",
"Line Out", "RLOUT",
"MIC3L", "Mic Bias 2V",
"MIC3R", "Mic Bias 2V",
"Mic Bias 2V", "Mic Jack",
"LINE1L", "Line In",
"LINE2L", "Line In",
"LINE1R", "Line In",
"LINE2R", "Line In";
};

View File

@ -195,44 +195,44 @@ examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
codec: da7219@1a {
compatible = "dlg,da7219";
reg = <0x1a>;
codec: audio-codec@1a {
compatible = "dlg,da7219";
reg = <0x1a>;
interrupt-parent = <&gpio6>;
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
interrupt-parent = <&gpio6>;
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
VDD-supply = <&vdd_reg>;
VDDMIC-supply = <&vddmic_reg>;
VDDIO-supply = <&vddio_reg>;
VDD-supply = <&vdd_reg>;
VDDMIC-supply = <&vddmic_reg>;
VDDIO-supply = <&vddio_reg>;
#clock-cells = <1>;
clock-output-names = "da7219-dai-wclk", "da7219-dai-bclk";
#clock-cells = <1>;
clock-output-names = "da7219-dai-wclk", "da7219-dai-bclk";
clocks = <&clks 201>;
clock-names = "mclk";
clocks = <&clks 201>;
clock-names = "mclk";
dlg,micbias-lvl = <2600>;
dlg,mic-amp-in-sel = "diff";
dlg,micbias-lvl = <2600>;
dlg,mic-amp-in-sel = "diff";
da7219_aad {
dlg,btn-cfg = <50>;
dlg,mic-det-thr = <500>;
dlg,jack-ins-deb = <20>;
dlg,jack-ins-det-pty = "low";
dlg,jack-det-rate = "32_64";
dlg,jack-rem-deb = <1>;
da7219_aad {
dlg,btn-cfg = <50>;
dlg,mic-det-thr = <500>;
dlg,jack-ins-deb = <20>;
dlg,jack-ins-det-pty = "low";
dlg,jack-det-rate = "32_64";
dlg,jack-rem-deb = <1>;
dlg,a-d-btn-thr = <0xa>;
dlg,d-b-btn-thr = <0x16>;
dlg,b-c-btn-thr = <0x21>;
dlg,c-mic-btn-thr = <0x3E>;
dlg,a-d-btn-thr = <0xa>;
dlg,d-b-btn-thr = <0x16>;
dlg,b-c-btn-thr = <0x21>;
dlg,c-mic-btn-thr = <0x3E>;
dlg,btn-avg = <4>;
dlg,adc-1bit-rpt = <1>;
};
};
dlg,btn-avg = <4>;
dlg,adc-1bit-rpt = <1>;
};
};
};

View File

@ -0,0 +1,94 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/esstech,es9039q2m.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ESS Technology ES9039Q2M audio DAC
maintainers:
- Karl Asseily <karl@asseily.com>
description:
The ES9039Q2M is a 32-bit two-channel audio DAC supporting PCM to 768 kHz,
DSD64 to DSD1024, DoP and S/PDIF. It is controlled over I2C or SPI when the
MODE pin selects software mode; this binding covers the I2C interface. The
part contains an asynchronous sample rate converter, so the system clock need
not be synchronous with the audio bit or frame clocks.
The four supplies are all nominally 3.3V and the datasheet requires a set
order - AVDD first, then VCCA about 200us later, then AVCC_DAC1 and
AVCC_DAC2, and the reverse on the way down. DVDD, the part's 1.2V rail, is
on-chip and needs only its decoupling capacitor - it is not a supply input
and has no property here.
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
const: esstech,es9039q2m
reg:
description:
I2C address, selected by the ADDR0 and ADDR1 pins - 0x48, 0x49, 0x4a or
0x4b for GND/GND, GND/AVDD, AVDD/GND and AVDD/AVDD respectively.
enum: [ 0x48, 0x49, 0x4a, 0x4b ]
clocks:
maxItems: 1
clock-names:
const: mclk
avdd-supply:
description:
3.3V supply for the part's internal digital regulator, pin AVDD. It is
the first rail up and the last down, per the ordering described above.
vcca-supply:
description: 3.3V analogue supply, pin VCCA.
avcc-dac1-supply:
description:
3.3V reference supply for the channel 1 analogue output stage, pin
AVCC_DAC1. The datasheet allows this rail to move by up to 15% where a
calibrating regulator tracks the DAC's output impedance.
avcc-dac2-supply:
description:
3.3V reference supply for the channel 2 analogue output stage, pin
AVCC_DAC2, with the same 15% allowance as channel 1.
"#sound-dai-cells":
const: 0
required:
- compatible
- reg
- avdd-supply
- vcca-supply
- avcc-dac1-supply
- avcc-dac2-supply
- "#sound-dai-cells"
unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
audio-codec@48 {
compatible = "esstech,es9039q2m";
reg = <0x48>;
#sound-dai-cells = <0>;
clocks = <&dac_mclk>;
clock-names = "mclk";
avdd-supply = <&dac_3v3>;
vcca-supply = <&dac_3v3>;
avcc-dac1-supply = <&dac_avcc1>;
avcc-dac2-supply = <&dac_avcc2>;
};
};

View File

@ -84,6 +84,11 @@ properties:
"#sound-dai-cells":
const: 0
everest,jack-detect-inverted:
$ref: /schemas/types.yaml#/definitions/flag
description:
Defined to invert the jack detection.
required:
- compatible
- reg

View File

@ -63,7 +63,7 @@ properties:
a. Register initialization settings
b. DSP effect parameters
c. Multi-scene sound effect configurations(optional)
It's gernerated by FourSemi's tuning tool.
It's generated by FourSemi's tuning tool.
required:
- compatible

View File

@ -55,6 +55,14 @@ properties:
- const: imx/easrc/easrc-imx8mn.bin
description: The coefficient table for the filters
ports:
$ref: /schemas/graph.yaml#/properties/ports
patternProperties:
"^port@[0-3]$":
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
description: port for an independent conversion path
fsl,asrc-rate:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 8000
@ -106,4 +114,41 @@ examples:
firmware-name = "imx/easrc/easrc-imx8mn.bin";
fsl,asrc-rate = <8000>;
fsl,asrc-format = <2>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
playback-only;
endpoint {
remote-endpoint = <&fe00_ep>;
};
};
port@1 {
reg = <1>;
playback-only;
endpoint {
remote-endpoint = <&fe01_ep>;
};
};
port@2 {
reg = <2>;
capture-only;
endpoint {
remote-endpoint = <&fe02_ep>;
};
};
port@3 {
reg = <3>;
capture-only;
endpoint {
remote-endpoint = <&fe03_ep>;
};
};
};
};

View File

@ -78,9 +78,19 @@ properties:
power-domains:
maxItems: 1
ports:
$ref: /schemas/graph.yaml#/properties/ports
patternProperties:
"^port@[0-2]$":
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
description: port for an independent conversion path
port:
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
deprecated: true
description: deprecated, use ports instead
fsl,asrc-rate:
$ref: /schemas/types.yaml#/definitions/uint32
@ -125,6 +135,10 @@ required:
- fsl,asrc-width
allOf:
- not:
required:
- port
- ports
- $ref: dai-common.yaml#
- if:
properties:
@ -180,11 +194,32 @@ examples:
fsl,asrc-rate = <48000>;
fsl,asrc-width = <16>;
port {
playback-only;
ports {
#address-cells = <1>;
#size-cells = <0>;
asrc_endpoint: endpoint {
remote-endpoint = <&fe00_ep>;
port@0 {
reg = <0>;
playback-only;
endpoint {
remote-endpoint = <&fe00_ep>;
};
};
};
port@1 {
reg = <1>;
capture-only;
endpoint {
remote-endpoint = <&fe01_ep>;
};
};
port@2 {
reg = <2>;
capture-only;
endpoint {
remote-endpoint = <&fe02_ep>;
};
};
};
};

View File

@ -260,13 +260,13 @@ examples:
playback-only;
sai1_endpoint0: endpoint {
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
dai-tdm-slot-width-map = <32 8 32>;
dai-format = "dsp_a";
bitclock-master;
frame-master;
remote-endpoint = <&mcodec01_ep>;
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
dai-tdm-slot-width-map = <32 8 32>;
dai-format = "dsp_a";
bitclock-master;
frame-master;
remote-endpoint = <&mcodec01_ep>;
};
};

View File

@ -48,6 +48,10 @@ properties:
The dai cell indexes reference the following interfaces:
0: S2 interface
ports:
$ref: audio-graph-port.yaml#/definitions/ports
unevaluatedProperties: false
required:
- compatible
- reg

View File

@ -105,10 +105,10 @@ examples:
format = "i2s";
fsl,mclk-equal-bclk;
cpu {
sound-dai = <&sai1>;
sound-dai = <&sai1>;
};
codec {
sound-dai = <&ak4458_1>, <&ak4458_2>;
sound-dai = <&ak4458_1>, <&ak4458_2>;
};
};
fe-dai-link {

View File

@ -101,10 +101,10 @@ examples:
mux-ssi1 {
fsl,audmux-port = <0>;
fsl,port-config = <
IMX_AUDMUX_V2_PTCR_SYN 0
IMX_AUDMUX_V2_PTCR_TFSEL(2) 0
IMX_AUDMUX_V2_PTCR_TCSEL(2) 0
IMX_AUDMUX_V2_PTCR_TFSDIR 0
IMX_AUDMUX_V2_PTCR_SYN 0
IMX_AUDMUX_V2_PTCR_TFSEL(2) 0
IMX_AUDMUX_V2_PTCR_TCSEL(2) 0
IMX_AUDMUX_V2_PTCR_TFSDIR 0
IMX_AUDMUX_V2_PTCR_TCLKDIR IMX_AUDMUX_V2_PDCR_RXDSEL(2)
>;
};

View File

@ -42,10 +42,10 @@ examples:
compatible = "invensense,ics43432";
port {
endpoint {
remote-endpoint = <&i2s1_endpoint>;
dai-format = "i2s";
};
endpoint {
remote-endpoint = <&i2s1_endpoint>;
dai-format = "i2s";
};
};
};

View File

@ -79,7 +79,7 @@ examples:
sound-dai = <&i2s>;
};
codec {
sound-dai = <&es8323>;
sound-dai = <&es8323>;
};
};
@ -104,6 +104,6 @@ examples:
};
codec {
sound-dai = <&es8388>;
sound-dai = <&es8388>;
};
};

View File

@ -32,7 +32,7 @@ properties:
maxItems: 1
clocks:
minItems: 34
minItems: 33
items:
- description: audio infra sys clock
- description: top audio mux 1
@ -74,7 +74,7 @@ properties:
- description: audio APLL root pd
clock-names:
minItems: 34
minItems: 33
items:
- const: infra_sys_audio_clk
- const: top_audio_mux1_sel
@ -132,8 +132,10 @@ allOf:
then:
properties:
clocks:
maxItems: 34
minItems: 33
maxItems: 33
clock-names:
maxItems: 34
minItems: 33
maxItems: 33
additionalProperties: false

View File

@ -84,15 +84,15 @@ examples:
<&topckgen CLK_TOP_I2S2_M_SEL>,
<&topckgen CLK_TOP_I2S3_M_SEL>,
<&topckgen CLK_TOP_I2S3_B_SEL>;
clock-names = "infra_sys_audio_clk",
"top_pdn_audio",
"top_pdn_aud_intbus",
"bck0",
"bck1",
"i2s0_m",
"i2s1_m",
"i2s2_m",
"i2s3_m",
"i2s3_b";
memory-region = <&afe_dma_mem>;
clock-names = "infra_sys_audio_clk",
"top_pdn_audio",
"top_pdn_aud_intbus",
"bck0",
"bck1",
"i2s0_m",
"i2s1_m",
"i2s2_m",
"i2s3_m",
"i2s3_b";
memory-region = <&afe_dma_mem>;
};

View File

@ -182,47 +182,47 @@ examples:
<&topckgen CLK_TOP_APLL12_DIV4>,
<&topckgen CLK_TOP_APLL12_DIVB>,
<&clk26m>;
clock-names = "aud_afe_clk",
"aud_dac_clk",
"aud_dac_predis_clk",
"aud_adc_clk",
"aud_adc_adda6_clk",
"aud_apll22m_clk",
"aud_apll24m_clk",
"aud_apll1_tuner_clk",
"aud_apll2_tuner_clk",
"aud_i2s1_bclk_sw",
"aud_i2s2_bclk_sw",
"aud_i2s3_bclk_sw",
"aud_i2s4_bclk_sw",
"aud_tdm_clk",
"aud_tml_clk",
"aud_infra_clk",
"mtkaif_26m_clk",
"top_mux_audio",
"top_mux_aud_intbus",
"top_syspll_d2_d4",
"top_mux_aud_1",
"top_apll1_ck",
"top_mux_aud_2",
"top_apll2_ck",
"top_mux_aud_eng1",
"top_apll1_d8",
"top_mux_aud_eng2",
"top_apll2_d8",
"top_i2s0_m_sel",
"top_i2s1_m_sel",
"top_i2s2_m_sel",
"top_i2s3_m_sel",
"top_i2s4_m_sel",
"top_i2s5_m_sel",
"top_apll12_div0",
"top_apll12_div1",
"top_apll12_div2",
"top_apll12_div3",
"top_apll12_div4",
"top_apll12_divb",
"top_clk26m_clk";
clock-names = "aud_afe_clk",
"aud_dac_clk",
"aud_dac_predis_clk",
"aud_adc_clk",
"aud_adc_adda6_clk",
"aud_apll22m_clk",
"aud_apll24m_clk",
"aud_apll1_tuner_clk",
"aud_apll2_tuner_clk",
"aud_i2s1_bclk_sw",
"aud_i2s2_bclk_sw",
"aud_i2s3_bclk_sw",
"aud_i2s4_bclk_sw",
"aud_tdm_clk",
"aud_tml_clk",
"aud_infra_clk",
"mtkaif_26m_clk",
"top_mux_audio",
"top_mux_aud_intbus",
"top_syspll_d2_d4",
"top_mux_aud_1",
"top_apll1_ck",
"top_mux_aud_2",
"top_apll2_ck",
"top_mux_aud_eng1",
"top_apll1_d8",
"top_mux_aud_eng2",
"top_apll2_d8",
"top_i2s0_m_sel",
"top_i2s1_m_sel",
"top_i2s2_m_sel",
"top_i2s3_m_sel",
"top_i2s4_m_sel",
"top_i2s5_m_sel",
"top_apll12_div0",
"top_apll12_div1",
"top_apll12_div2",
"top_apll12_div3",
"top_apll12_div4",
"top_apll12_divb",
"top_clk26m_clk";
};
...

View File

@ -167,30 +167,30 @@ examples:
"HDMI1", "TX";
hs-playback-dai-link {
link-name = "I2S0";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&da7219>;
};
link-name = "I2S0";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&da7219>;
};
};
hs-capture-dai-link {
link-name = "I2S1";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&da7219>;
};
link-name = "I2S1";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&da7219>;
};
};
spk-dp-playback-dai-link {
link-name = "I2S3";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&anx_bridge_dp>, <&max98357a>;
};
link-name = "I2S3";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&anx_bridge_dp>, <&max98357a>;
};
};
};

View File

@ -171,30 +171,30 @@ examples:
"HDMI1", "TX";
hs-playback-dai-link {
link-name = "I2S0";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt5682s 0>;
};
link-name = "I2S0";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt5682s 0>;
};
};
hs-capture-dai-link {
link-name = "I2S1";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt5682s 0>;
};
link-name = "I2S1";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt5682s 0>;
};
};
spk-hdmi-playback-dai-link {
link-name = "I2S3";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&it6505dptx>, <&rt1019p>;
};
link-name = "I2S3";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&it6505dptx>, <&rt1019p>;
};
};
};

View File

@ -165,38 +165,38 @@ examples:
"Speakers", "Speaker";
spk-playback-dai-link {
link-name = "I2S3";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt1015p>;
};
link-name = "I2S3";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt1015p>;
};
};
hs-playback-dai-link {
link-name = "I2S8";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt5682 0>;
};
link-name = "I2S8";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt5682 0>;
};
};
hs-capture-dai-link {
link-name = "I2S9";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt5682 0>;
};
link-name = "I2S9";
dai-format = "i2s";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&rt5682 0>;
};
};
displayport-dai-link {
link-name = "TDM";
dai-format = "dsp_a";
codec {
sound-dai = <&anx_bridge_dp>;
};
link-name = "TDM";
dai-format = "dsp_a";
codec {
sound-dai = <&anx_bridge_dp>;
};
};
};

View File

@ -156,46 +156,46 @@ examples:
"Ext Spk", "Speaker";
mm-dai-link {
link-name = "ETDM1_IN_BE";
mediatek,clk-provider = "cpu";
link-name = "ETDM1_IN_BE";
mediatek,clk-provider = "cpu";
};
hs-playback-dai-link {
link-name = "ETDM1_OUT_BE";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&headset_codec>;
};
link-name = "ETDM1_OUT_BE";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&headset_codec>;
};
};
hs-capture-dai-link {
link-name = "ETDM2_IN_BE";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&headset_codec>;
};
link-name = "ETDM2_IN_BE";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&headset_codec>;
};
};
spk-playback-dai-link {
link-name = "ETDM2_OUT_BE";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&spk_amplifier>;
};
link-name = "ETDM2_OUT_BE";
mediatek,clk-provider = "cpu";
codec {
sound-dai = <&spk_amplifier>;
};
};
hdmi-dai-link {
link-name = "ETDM3_OUT_BE";
codec {
sound-dai = <&hdmi_tx>;
};
link-name = "ETDM3_OUT_BE";
codec {
sound-dai = <&hdmi_tx>;
};
};
displayport-dai-link {
link-name = "DPTX_BE";
codec {
sound-dai = <&dp_tx>;
};
link-name = "DPTX_BE";
codec {
sound-dai = <&dp_tx>;
};
};
};

View File

@ -0,0 +1,115 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/nuvoton,nau8360.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Nuvoton NAU83G60 Stereo Class-D Amplifier with DSP
description:
Stereo Class-D Amplifier with DSP and I/V-sense.
This device supports I2C.
maintainers:
- Neo Chang <YLCHANG2@nuvoton.com>
properties:
compatible:
enum:
- nuvoton,nau8360
reg:
description: The I2C address is determined by the hardware pins.
enum: [0x1a, 0x1b, 0x4a, 0x4b]
"#sound-dai-cells":
const: 0
clocks:
maxItems: 1
clock-names:
const: mclk
firmware-name:
description:
List of DSP core firmware filenames. Both Left and Right DSP firmware
must be provided and loaded. In PBTL mode, the Left DSP must use the
same binary file as the Right DSP.
items:
- description: Left DSP core firmware filename.
- description: Right DSP core firmware filename.
nuvoton,pbtl-enable:
type: boolean
description: NAU83G60 supports PBTL mode for mono output.
nuvoton,dac-cur-enable:
type: boolean
description:
Adjust DAC output current to match speaker impedance and prevent
hardware damage. +3.2dB when present, 0dB by default.
nuvoton,dsp-rx-slot-mapping:
description:
Configures the TDM slot routing for DSP RX functions.
Each integer assigns a specific DSP internal function to a TDM slot.
The indices of the array correspond to the following hardware functions
(0) DACL
(1) DACR
(2) ANCL
(3) ANCR
Assigned slots must be unique, except 255 which disables the function.
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 4
maxItems: 4
items:
enum: [ 0, 1, 2, 3, 4, 5, 6, 7, 255 ]
nuvoton,dsp-tx-slot-mapping:
description:
Configures the TDM slot routing for DSP TX functions.
Each integer assigns a specific DSP internal function to a TDM slot.
The indices of the array correspond to the following hardware functions
(0) AECL (Acoustic echo cancellation left)
(1) AECR (Acoustic echo cancellation right)
(2) ISNSL (Current sense left)
(3) ISNSR (Current sense right)
(4) VSNSL (Voltage sense left)
(5) VSNSR (Voltage sense right)
(6) TJ (Junction temperature)
(7) VBAT (Battery voltage)
Assigned slots must be unique, except 255 which disables the function.
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 8
maxItems: 8
items:
enum: [ 0, 1, 2, 3, 4, 5, 6, 7, 255 ]
required:
- compatible
- reg
- firmware-name
allOf:
- $ref: dai-common.yaml#
unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
codec@1a {
compatible = "nuvoton,nau8360";
reg = <0x1a>;
#sound-dai-cells = <0>;
firmware-name = "NAU83G60.kcs.bin.l", "NAU83G60.kcs.bin.r";
nuvoton,dac-cur-enable;
nuvoton,pbtl-enable;
nuvoton,dsp-rx-slot-mapping = <0 1 2 3>;
nuvoton,dsp-tx-slot-mapping = <0 1 2 3 4 5 6 7>;
};
};

View File

@ -1,88 +0,0 @@
NVIDIA Tegra30 AHUB (Audio Hub)
Required properties:
- compatible : For Tegra30, must contain "nvidia,tegra30-ahub". For Tegra114,
must contain "nvidia,tegra114-ahub". For Tegra124, must contain
"nvidia,tegra124-ahub". Otherwise, must contain "nvidia,<chip>-ahub",
plus at least one of the above, where <chip> is tegra132.
- reg : Should contain the register physical address and length for each of
the AHUB's register blocks.
- Tegra30 requires 2 entries, for the APBIF and AHUB/AUDIO register blocks.
- Tegra114 requires an additional entry, for the APBIF2 register block.
- interrupts : Should contain AHUB interrupt
- clocks : Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.
- clock-names : Must include the following entries:
- d_audio
- apbif
- resets : Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
Tegra30 and later:
- d_audio
- apbif
- i2s0
- i2s1
- i2s2
- i2s3
- i2s4
- dam0
- dam1
- dam2
- spdif
Tegra114 and later additionally require:
- amx
- adx
Tegra124 and later additionally require:
- amx1
- adx1
- afc0
- afc1
- afc2
- afc3
- afc4
- afc5
- ranges : The bus address mapping for the configlink register bus.
Can be empty since the mapping is 1:1.
- dmas : Must contain an entry for each entry in clock-names.
See ../dma/dma.txt for details.
- dma-names : Must include the following entries:
- rx0 .. rx<n>
- tx0 .. tx<n>
... where n is:
Tegra30: 3
Tegra114, Tegra124: 9
- #address-cells : For the configlink bus. Should be <1>;
- #size-cells : For the configlink bus. Should be <1>.
AHUB client modules need to specify the IDs of their CIFs (Client InterFaces).
For RX CIFs, the numbers indicate the register number within AHUB routing
register space (APBIF 0..3 RX, I2S 0..5 RX, DAM 0..2 RX 0..1, SPDIF RX 0..1).
For TX CIFs, the numbers indicate the bit position within the AHUB routing
registers (APBIF 0..3 TX, I2S 0..5 TX, DAM 0..2 TX, SPDIF TX 0..1).
Example:
ahub@70080000 {
compatible = "nvidia,tegra30-ahub";
reg = <0x70080000 0x200 0x70080200 0x100>;
interrupts = < 0 103 0x04 >;
nvidia,dma-request-selector = <&apbdma 1>;
clocks = <&tegra_car 106>, <&tegra_car 107>;
clock-names = "d_audio", "apbif";
resets = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>,
<&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>,
<&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>,
<&tegra_car 110>, <&tegra_car 10>;
reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
"i2s3", "i2s4", "dam0", "dam1", "dam2",
"spdif";
dmas = <&apbdma 1>, <&apbdma 1>;
<&apbdma 2>, <&apbdma 2>;
<&apbdma 3>, <&apbdma 3>;
<&apbdma 4>, <&apbdma 4>;
dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2", "rx3", "tx3";
ranges;
#address-cells = <1>;
#size-cells = <1>;
};

View File

@ -0,0 +1,289 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/nvidia,tegra30-ahub.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NVIDIA Tegra30 AHUB (Audio Hub)
maintainers:
- Thierry Reding <thierry.reding@gmail.com>
- Jon Hunter <jonathanh@nvidia.com>
description:
AHUB client modules need to specify the IDs of their CIFs (Client
InterFaces). For RX CIFs, the numbers indicate the register number within
AHUB routing register space (APBIF 0..3 RX, I2S 0..5 RX, DAM 0..2 RX 0..1,
SPDIF RX 0..1). For TX CIFs, the numbers indicate the bit position within
the AHUB routing registers (APBIF 0..3 TX, I2S 0..5 TX, DAM 0..2 TX, SPDIF
TX 0..1).
properties:
compatible:
oneOf:
- const: nvidia,tegra30-ahub
- const: nvidia,tegra114-ahub
- const: nvidia,tegra124-ahub
- items:
- const: nvidia,tegra132-ahub
- const: nvidia,tegra124-ahub
reg:
minItems: 2
maxItems: 3
interrupts:
maxItems: 1
clocks:
items:
- description: digital audio clock
- description: module clock
clock-names:
items:
- const: d_audio
- const: apbif
resets:
minItems: 11
maxItems: 21
reset-names:
minItems: 11
maxItems: 21
ranges: true
dmas:
minItems: 8
maxItems: 20
dma-names:
minItems: 8
maxItems: 20
"#address-cells":
enum: [1, 2]
"#size-cells":
enum: [1, 2]
patternProperties:
"^i2s@[0-9a-f]+$":
type: object
required:
- compatible
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- resets
- reset-names
- ranges
- dmas
- dma-names
- "#address-cells"
- "#size-cells"
allOf:
- if:
properties:
compatible:
const: nvidia,tegra30-ahub
then:
properties:
reg:
items:
- description: APBIF registers
- description: AHUB/AUDIO registers
resets:
maxItems: 11
reset-names:
items:
- const: d_audio
- const: apbif
- const: i2s0
- const: i2s1
- const: i2s2
- const: i2s3
- const: i2s4
- const: dam0
- const: dam1
- const: dam2
- const: spdif
dmas:
maxItems: 8
dma-names:
items:
- const: rx0
- const: tx0
- const: rx1
- const: tx1
- const: rx2
- const: tx2
- const: rx3
- const: tx3
- if:
properties:
compatible:
const: nvidia,tegra114-ahub
then:
properties:
reg:
items:
- description: APBIF registers
- description: AHUB/AUDIO registers
- description: APBIF2 registers
resets:
minItems: 13
maxItems: 13
reset-names:
items:
- const: d_audio
- const: apbif
- const: i2s0
- const: i2s1
- const: i2s2
- const: i2s3
- const: i2s4
- const: dam0
- const: dam1
- const: dam2
- const: spdif
- const: amx
- const: adx
dmas:
minItems: 20
dma-names:
items:
- const: rx0
- const: tx0
- const: rx1
- const: tx1
- const: rx2
- const: tx2
- const: rx3
- const: tx3
- const: rx4
- const: tx4
- const: rx5
- const: tx5
- const: rx6
- const: tx6
- const: rx7
- const: tx7
- const: rx8
- const: tx8
- const: rx9
- const: tx9
- if:
properties:
compatible:
contains:
const: nvidia,tegra124-ahub
then:
properties:
reg:
items:
- description: APBIF registers
- description: AHUB/AUDIO registers
- description: APBIF2 registers
resets:
minItems: 21
reset-names:
items:
- const: d_audio
- const: apbif
- const: i2s0
- const: i2s1
- const: i2s2
- const: i2s3
- const: i2s4
- const: dam0
- const: dam1
- const: dam2
- const: spdif
- const: amx
- const: amx1
- const: adx
- const: adx1
- const: afc0
- const: afc1
- const: afc2
- const: afc3
- const: afc4
- const: afc5
dmas:
minItems: 20
dma-names:
items:
- const: rx0
- const: tx0
- const: rx1
- const: tx1
- const: rx2
- const: tx2
- const: rx3
- const: tx3
- const: rx4
- const: tx4
- const: rx5
- const: tx5
- const: rx6
- const: tx6
- const: rx7
- const: tx7
- const: rx8
- const: tx8
- const: rx9
- const: tx9
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/tegra30-car.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
ahub@70080000 {
compatible = "nvidia,tegra30-ahub";
reg = <0x70080000 0x200>,
<0x70080200 0x100>;
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA30_CLK_D_AUDIO>,
<&tegra_car TEGRA30_CLK_APBIF>;
clock-names = "d_audio", "apbif";
resets = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>,
<&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>,
<&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>,
<&tegra_car 110>, <&tegra_car 10>;
reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
"i2s3", "i2s4", "dam0", "dam1", "dam2",
"spdif";
dmas = <&apbdma 1>, <&apbdma 1>,
<&apbdma 2>, <&apbdma 2>,
<&apbdma 3>, <&apbdma 3>,
<&apbdma 4>, <&apbdma 4>;
dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2", "rx3", "tx3";
ranges;
#address-cells = <1>;
#size-cells = <1>;
};

View File

@ -18,6 +18,7 @@ properties:
- items:
- enum:
- qcom,sdm660-wcd-digital-codec
- qcom,sdm670-wcd-digital-codec
- const: qcom,msm8916-wcd-digital-codec
- const: qcom,msm8916-wcd-digital-codec

View File

@ -20,9 +20,24 @@ properties:
minItems: 1
maxItems: 2
memory-region:
minItems: 1
items:
- description:
Control-path buffer (audio_heap_mem) for platforms where the DSP
runs in a stage-2 protected context (e.g. modem-DSP).
- description:
Data-path buffer pool from which per-stream DMA buffers are
allocated.
required:
- compatible
- iommus
oneOf:
- required:
- iommus
- required:
- memory-region
additionalProperties: false

View File

@ -75,11 +75,11 @@ examples:
#size-cells = <0>;
dai@10 {
reg = <PRIMARY_MI2S_RX>;
clocks = <&q6prmcc LPASS_CLK_ID_PRI_MI2S_IBIT
LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
<&q6prmcc LPASS_CLK_ID_MCLK_1
LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
clock-names = "bclk", "mclk";
reg = <PRIMARY_MI2S_RX>;
clocks = <&q6prmcc LPASS_CLK_ID_PRI_MI2S_IBIT
LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
<&q6prmcc LPASS_CLK_ID_MCLK_1
LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
clock-names = "bclk", "mclk";
};
};

View File

@ -108,10 +108,15 @@ patternProperties:
properties:
reg:
contains:
# TDM DAI ID range from PRIMARY_TDM_RX_0 - QUINARY_TDM_TX_7
# TDM DAI ID range from PRIMARY_TDM_RX_0 - QUINARY_TDM_TX_7 and
# AIF_TDM_RX_0 - AIF_TDM_TX_12
items:
minimum: 24
maximum: 103
oneOf:
- minimum: 24
maximum: 103
- minimum: 179
maximum: 204
then:
required:
- qcom,tdm-sync-mode
@ -127,7 +132,8 @@ patternProperties:
contains:
# MI2S DAI ID range PRIMARY_MI2S_RX - QUATERNARY_MI2S_TX and
# QUINARY_MI2S_RX - QUINARY_MI2S_TX and
# LPI_MI2S_RX_0 - LPI_MI2S_TX_6
# LPI_MI2S_RX_0 - LPI_MI2S_TX_6 and
# AIF_MI2S_RX_0 - AIF_MI2S_TX_12
items:
oneOf:
- minimum: 16
@ -136,6 +142,8 @@ patternProperties:
maximum: 128
- minimum: 137
maximum: 152
- minimum: 153
maximum: 178
then:
required:
- qcom,sd-lines

View File

@ -54,6 +54,7 @@ properties:
- qcom,sm8250-sndcard
- qcom,sm8450-sndcard
- qcom,x1e80100-sndcard
- thundercomm,qcs6490-rubikpi3-sndcard
audio-routing:
$ref: /schemas/types.yaml#/definitions/non-unique-string-array

View File

@ -0,0 +1,105 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/qcom,wcd9378-sdw.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm WCD9378 (Tambora) SoundWire codec
maintainers:
- Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
description:
Qualcomm WCD9378 (Tambora) SoundWire codec. The same silicon can be
fused for a mobile (non-SDCA) mode or an SDCA-compliant mode; the
qcom,sdca-compliant property selects the latter and is required by
this driver.
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
const: sdw20217011000
reg:
maxItems: 1
qcom,sdca-compliant:
description:
Present when the codec is fused as SDCA-compliant. The mobile
(non-SDCA) variant carries the same class-ID compatible and is
handled by a different driver.
type: boolean
qcom,port-mapping:
description:
Each entry maps a slave data port to a master data port.
Entries are in order starting from slave port 1; slave port 0
is reserved and not represented. SDCA-compliant mode uses 8
entries covering DP1..DP8.
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 8
maxItems: 8
reset-gpios:
description: GPIO used to release the codec from reset.
maxItems: 1
vdd-buck-supply:
description: 1.8 V analog buck supply.
vdd-rxtx-supply:
description: 1.8 V RX/TX supply.
vdd-io-supply:
description: Digital I/O supply.
vdd-mic-bias-supply:
description: Mic bias supply.
'#sound-dai-cells':
const: 1
required:
- compatible
- reg
- qcom,sdca-compliant
- qcom,port-mapping
- reset-gpios
- vdd-buck-supply
- vdd-rxtx-supply
- vdd-io-supply
- vdd-mic-bias-supply
- '#sound-dai-cells'
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
soundwire@7630000 {
reg = <0x07630000 0x10000>;
#address-cells = <2>;
#size-cells = <0>;
wcd9378c_sdw: audio-codec@0,3 {
compatible = "sdw20217011000";
reg = <0 3>;
qcom,sdca-compliant;
qcom,port-mapping = <2 2 3 4 5 6 7 8>;
reset-gpios = <&tlmm 191 GPIO_ACTIVE_LOW>;
vdd-buck-supply = <&vreg_l15b_1p8>;
vdd-rxtx-supply = <&vreg_l15b_1p8>;
vdd-io-supply = <&vreg_l18b_1p2>;
vdd-mic-bias-supply = <&vreg_bob1>;
#sound-dai-cells = <1>;
};
};
...

View File

@ -44,6 +44,14 @@ properties:
'#gpio-cells':
const: 2
clocks:
items:
- description: phandle and clock specifier for the codec MCLK1 input.
clock-names:
items:
- const: mclk1
realtek,pow-ldo2-gpio:
maxItems: 1
description: CODEC's POW_LDO2 pin.
@ -127,6 +135,8 @@ examples:
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;
clocks = <&osc>;
clock-names = "mclk1";
realtek,pow-ldo2-gpio = <&gpio 3 GPIO_ACTIVE_HIGH>;
realtek,reset-gpio = <&gpio 3 GPIO_ACTIVE_LOW>;
realtek,in1-differential;

View File

@ -432,14 +432,14 @@ examples:
"ssi.1", "ssi.0";
rcar_sound,dvc {
dvc0: dvc-0 {
dmas = <&audma0 0xbc>;
dma-names = "tx";
};
dvc1: dvc-1 {
dmas = <&audma0 0xbe>;
dma-names = "tx";
};
dvc0: dvc-0 {
dmas = <&audma0 0xbc>;
dma-names = "tx";
};
dvc1: dvc-1 {
dmas = <&audma0 0xbe>;
dma-names = "tx";
};
};
rcar_sound,mix {

View File

@ -95,20 +95,20 @@ examples:
ssi0: ssi@10049c00 {
compatible = "renesas,r9a07g044-ssi",
"renesas,rz-ssi";
reg = <0x10049c00 0x400>;
interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 327 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 328 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "int_req", "dma_rx", "dma_tx";
clocks = <&cpg CPG_MOD R9A07G044_SSI0_PCLK2>,
<&cpg CPG_MOD R9A07G044_SSI0_PCLK_SFR>,
<&audio_clk1>,
<&audio_clk2>;
clock-names = "ssi", "ssi_sfr", "audio_clk1", "audio_clk2";
power-domains = <&cpg>;
resets = <&cpg R9A07G044_SSI0_RST_M2_REG>;
dmas = <&dmac 0x2655>,
<&dmac 0x2656>;
dma-names = "tx", "rx";
#sound-dai-cells = <0>;
reg = <0x10049c00 0x400>;
interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 327 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 328 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "int_req", "dma_rx", "dma_tx";
clocks = <&cpg CPG_MOD R9A07G044_SSI0_PCLK2>,
<&cpg CPG_MOD R9A07G044_SSI0_PCLK_SFR>,
<&audio_clk1>,
<&audio_clk2>;
clock-names = "ssi", "ssi_sfr", "audio_clk1", "audio_clk2";
power-domains = <&cpg>;
resets = <&cpg R9A07G044_SSI0_RST_M2_REG>;
dmas = <&dmac 0x2655>,
<&dmac 0x2656>;
dma-names = "tx", "rx";
#sound-dai-cells = <0>;
};

View File

@ -0,0 +1,96 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/stericsson,ux500-msp-i2s.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ST-Ericsson Ux500 Multichannel Serial Port
maintainers:
- Linus Walleij <linusw@kernel.org>
description:
The Ux500 Multichannel Serial Port (MSP) is a synchronous serial audio
interface supporting I2S and PCM/TDM protocols. Data is transferred to and
from memory using the Ux500 DMA controller.
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
const: stericsson,ux500-msp-i2s
reg:
maxItems: 1
interrupts:
maxItems: 1
v-ape-supply:
description: Analog power engine supply
dmas:
minItems: 1
maxItems: 2
dma-names:
minItems: 1
maxItems: 2
items:
enum: [ rx, tx ]
clocks:
items:
- description: MSP functional clock
- description: MSP APB bus clock
clock-names:
items:
- const: msp
- const: apb_pclk
resets:
maxItems: 1
'#sound-dai-cells':
const: 0
port:
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
required:
- compatible
- reg
- interrupts
- v-ape-supply
- dmas
- dma-names
- clocks
- clock-names
- resets
- '#sound-dai-cells'
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/reset/stericsson,db8500-prcc-reset.h>
msp@80123000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80123000 0x1000>;
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
v-ape-supply = <&db8500_vape_reg>;
dmas = <&dma 31 0 0x12>, <&dma 31 0 0x10>;
dma-names = "rx", "tx";
clocks = <&prcc_kclk 1 3>, <&prcc_pclk 1 3>;
clock-names = "msp", "apb_pclk";
resets = <&prcc_reset DB8500_PRCC_1 DB8500_PRCC_1_RESET_MSP0>;
#sound-dai-cells = <0>;
};
...

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/ti,da830-evm-audio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments SoC audio setups with TLV320AIC3X Codec
maintainers:
- Eduard Bostina <egbostina@gmail.com>
properties:
compatible:
const: ti,da830-evm-audio
ti,model:
$ref: /schemas/types.yaml#/definitions/string
description: The user-visible name of this sound complex.
ti,audio-codec:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of the TLV320AIC3x audio codec
ti,mcasp-controller:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of the McASP controller
ti,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 for sources and sinks
are the codec's pins, and the jacks on the board (Headphone Jack,
Line Out, Mic Jack, Line In).
ti,codec-clock-rate:
$ref: /schemas/types.yaml#/definitions/uint32
description: The Codec Clock rate (in Hz) applied to the Codec.
clocks:
maxItems: 1
description: Reference to the master clock
clock-names:
const: mclk
required:
- compatible
- ti,model
- ti,audio-codec
- ti,mcasp-controller
- ti,audio-routing
anyOf:
- required:
- ti,codec-clock-rate
- required:
- clocks
additionalProperties: false
examples:
- |
sound {
compatible = "ti,da830-evm-audio";
ti,model = "DA830 EVM";
ti,audio-codec = <&tlv320aic3x>;
ti,mcasp-controller = <&mcasp1>;
ti,codec-clock-rate = <12000000>;
ti,audio-routing =
"Headphone Jack", "HPLOUT",
"Headphone Jack", "HPROUT",
"Line Out", "LLOUT",
"Line Out", "RLOUT",
"MIC3L", "Mic Bias 2V",
"MIC3R", "Mic Bias 2V",
"Mic Bias 2V", "Mic Jack",
"LINE1L", "Line In",
"LINE2L", "Line In",
"LINE1R", "Line In",
"LINE2R", "Line In";
};

View File

@ -219,9 +219,7 @@ allOf:
- if:
properties:
compatible:
contains:
enum:
- ti,tas2781
const: ti,tas2781
then:
properties:
reg:

View File

@ -45,13 +45,13 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
tas5805m: tas5805m@2c {
reg = <0x2c>;
compatible = "ti,tas5805m";
reg = <0x2c>;
compatible = "ti,tas5805m";
pvdd-supply = <&audiopwr>;
pdn-gpios = <&tlmm 160 0>;
pvdd-supply = <&audiopwr>;
pdn-gpios = <&tlmm 160 0>;
ti,dsp-config-name = "mono_pbtl_48khz";
ti,dsp-config-name = "mono_pbtl_48khz";
};
};
...

View File

@ -121,6 +121,6 @@ examples:
AVDD-supply = <&regulator>;
IOVDD-supply = <&regulator>;
DVDD-supply = <&regulator>;
};
};
};

View File

@ -50,6 +50,6 @@ examples:
reg = <0x60>;
Vdd-supply = <&vmmc2>;
power-gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>;
};
};
};

View File

@ -1,39 +0,0 @@
* MOP500 Audio Machine Driver
This node is responsible for linking together all ux500 Audio Driver components.
Required properties:
- compatible : "stericsson,snd-soc-mop500"
Non-standard properties:
- stericsson,cpu-dai : Phandle to the CPU-side DAI
- stericsson,audio-codec : Phandle to the Audio CODEC
- stericsson,card-name : Over-ride default card name
Example:
sound {
compatible = "stericsson,snd-soc-mop500";
stericsson,cpu-dai = <&msp1 &msp3>;
stericsson,audio-codec = <&codec>;
};
msp1: msp@80124000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80124000 0x1000>;
interrupts = <0 62 0x4>;
v-ape-supply = <&db8500_vape_reg>;
};
msp3: msp@80125000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80125000 0x1000>;
interrupts = <0 62 0x4>;
v-ape-supply = <&db8500_vape_reg>;
};
codec: ab8500-codec {
compatible = "stericsson,ab8500-codec";
stericsson,earpeice-cmv = <950>; /* Units in mV. */
};

View File

@ -1,42 +0,0 @@
* ux500 MSP (CPU-side Digital Audio Interface)
Required properties:
- compatible :"stericsson,ux500-msp-i2s"
- reg : Physical base address and length of the device's registers.
Optional properties:
- interrupts : The interrupt output from the device.
- <name>-supply : Phandle to the regulator <name> supply
Example:
sound {
compatible = "stericsson,snd-soc-mop500";
stericsson,platform-pcm-dma = <&pcm>;
stericsson,cpu-dai = <&msp1 &msp3>;
stericsson,audio-codec = <&codec>;
};
pcm: ux500-pcm {
compatible = "stericsson,ux500-pcm";
};
msp1: msp@80124000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80124000 0x1000>;
interrupts = <0 62 0x4>;
v-ape-supply = <&db8500_vape_reg>;
};
msp3: msp@80125000 {
compatible = "stericsson,ux500-msp-i2s";
reg = <0x80125000 0x1000>;
interrupts = <0 62 0x4>;
v-ape-supply = <&db8500_vape_reg>;
};
codec: ab8500-codec {
compatible = "stericsson,ab8500-codec";
stericsson,earpeice-cmv = <950>; /* Units in mV. */
};

View File

@ -559,6 +559,8 @@ patternProperties:
description: Seiko Epson Corp.
"^esp,.*":
description: Espressif Systems Co. Ltd.
"^esstech,.*":
description: ESS Technology, Inc.
"^est,.*":
description: ESTeem Wireless Modems
"^eswin,.*":

View File

@ -767,6 +767,14 @@ F: Documentation/devicetree/bindings/phy/airoha,en7581-pcie-phy.yaml
F: drivers/phy/phy-airoha-pcie-regs.h
F: drivers/phy/phy-airoha-pcie.c
AIROHA SOUND DRIVER
M: Christian Marangi <ansuelsmth@gmail.com>
L: linux-sound@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/sound/airoha,an7581-afe.yaml
F: Documentation/devicetree/bindings/sound/airoha,an7581-wm8960.yaml
F: sound/soc/mediatek/an7581/*
AIROHA SPI SNFI DRIVER
M: Lorenzo Bianconi <lorenzo@kernel.org>
M: Ray Liu <ray.liu@airoha.com>
@ -9702,6 +9710,13 @@ S: Maintained
F: include/linux/errseq.h
F: lib/errseq.c
ES9039Q2M AUDIO CODEC DRIVER
M: Karl Asseily <karl@asseily.com>
L: linux-sound@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/sound/esstech,es9039q2m.yaml
F: sound/soc/codecs/es9039q2m.c
ESD CAN NETWORK DRIVERS
M: Stefan Mätje <stefan.maetje@esd.eu>
R: socketcan@esd.eu
@ -30205,9 +30220,12 @@ F: tools/testing/selftests/cgroup/test_zswap.c
SENARYTECH AUDIO CODEC DRIVER
M: bo liu <bo.liu@senarytech.com>
M: qianghua.wang <qianghua.wang@senarytech.com>
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
F: sound/hda/codecs/senarytech.c
F: sound/soc/codecs/sn624x*
F: sound/soc/sdw_utils/soc_sdw_senary*
ZTE DINGHAI ETHERNET DRIVER
M: Junyang Han <han.junyang@zte.com.cn>

View File

@ -322,6 +322,7 @@ static inline unsigned int regcache_get_index_by_order(const struct regmap *map,
}
struct regmap_ram_data {
unsigned int base_reg;
unsigned int *vals; /* Allocatd by caller */
bool *read;
bool *written;

View File

@ -963,7 +963,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
return 0;
err_domain:
/* Should really dispose of the domain but... */
irq_domain_remove(d->domain);
err_mutex:
mutex_destroy(&d->lock);
lockdep_unregister_key(&d->lock_key);

View File

@ -11,6 +11,8 @@
#define BLOCK_TEST_SIZE 12
#define HIGH_BIT_REG ((UINT_MAX / 2) - 3)
KUNIT_DEFINE_ACTION_WRAPPER(regmap_exit_action, regmap_exit, struct regmap *);
struct regmap_test_priv {
@ -23,6 +25,7 @@ struct regmap_test_param {
enum regcache_type cache;
enum regmap_endian val_endian;
unsigned int base_reg;
unsigned int from_reg;
bool fast_io;
};
@ -204,7 +207,8 @@ static struct regmap *gen_regmap(struct kunit *test,
config->max_register += (BLOCK_TEST_SIZE * config->reg_stride);
}
size = array_size(config->max_register + 1, sizeof(*buf));
size = array_size(config->max_register - param->base_reg + 1,
sizeof(*buf));
buf = kmalloc(size, GFP_KERNEL);
if (!buf)
return ERR_PTR(-ENOMEM);
@ -215,6 +219,7 @@ static struct regmap *gen_regmap(struct kunit *test,
if (!(*data))
goto out_free;
(*data)->vals = buf;
(*data)->base_reg = param->base_reg;
if (config->num_reg_defaults) {
defaults = kunit_kcalloc(test,
@ -227,8 +232,8 @@ static struct regmap *gen_regmap(struct kunit *test,
config->reg_defaults = defaults;
for (i = 0; i < config->num_reg_defaults; i++) {
defaults[i].reg = param->from_reg + (i * config->reg_stride);
defaults[i].def = buf[param->from_reg + (i * config->reg_stride)];
defaults[i].reg = param->from_reg - param->base_reg + (i * config->reg_stride);
defaults[i].def = buf[param->from_reg - param->base_reg + (i * config->reg_stride)];
}
}
@ -1648,6 +1653,92 @@ static void cache_write_zero(struct kunit *test)
KUNIT_ASSERT_FALSE(test, regcache_reg_cached(map, 1));
}
static const struct regmap_test_param high_bit_cache_types_list[] = {
{ .cache = REGCACHE_RBTREE, .from_reg = HIGH_BIT_REG,
.base_reg = HIGH_BIT_REG },
{ .cache = REGCACHE_MAPLE, .from_reg = HIGH_BIT_REG,
.base_reg = HIGH_BIT_REG },
};
KUNIT_ARRAY_PARAM(high_bit_cache_types, high_bit_cache_types_list, param_to_desc);
/*
* Dynamically allocated cache types should support registers with the
* high bit set, the backend will return an error for any operation on
* a register below the expected window.
*/
static void cache_high_bit_reg(struct kunit *test)
{
const struct regmap_test_param *param = test->param_value;
struct regmap_ram_data *data;
struct regmap_config config;
struct regmap *map;
unsigned int val[BLOCK_TEST_SIZE], rval;
int i;
config = test_regmap_config;
map = gen_regmap(test, &config, &data);
KUNIT_ASSERT_FALSE(test, IS_ERR(map));
if (IS_ERR(map))
return;
get_random_bytes(&val, sizeof(val));
/* No defaults so no registers cached */
for (i = 0; i < BLOCK_TEST_SIZE; i++)
KUNIT_EXPECT_FALSE(test, regcache_reg_cached(map, param->from_reg + i));
/* Writes should reach the device */
for (i = 0; i < BLOCK_TEST_SIZE; i++)
KUNIT_EXPECT_EQ(test, 0, regmap_write(map, param->from_reg + i,
val[i]));
for (i = 0; i < BLOCK_TEST_SIZE; i++) {
KUNIT_EXPECT_TRUE(test, data->written[i]);
KUNIT_EXPECT_EQ(test, val[i], data->vals[i]);
}
/* Reads should be satisfied from the cache */
for (i = 0; i < BLOCK_TEST_SIZE; i++) {
KUNIT_EXPECT_TRUE(test, regcache_reg_cached(map, param->from_reg + i));
KUNIT_EXPECT_EQ(test, 0, regmap_read(map, param->from_reg + i,
&rval));
KUNIT_EXPECT_EQ(test, val[i], rval);
KUNIT_EXPECT_FALSE(test, data->read[i]);
}
/* Trash the data on the device then resync */
regcache_mark_dirty(map);
for (i = 0; i < BLOCK_TEST_SIZE; i++) {
data->vals[i] = 0;
data->written[i] = false;
}
KUNIT_EXPECT_EQ(test, 0, regcache_sync(map));
/* Did we just write the correct data out? */
for (i = 0; i < BLOCK_TEST_SIZE; i++) {
KUNIT_EXPECT_TRUE(test, data->written[i]);
KUNIT_EXPECT_EQ(test, val[i], data->vals[i]);
}
/* Drop some registers */
KUNIT_EXPECT_EQ(test, 0, regcache_drop_region(map, param->from_reg + 3,
param->from_reg + 5));
for (i = 0; i < BLOCK_TEST_SIZE; i++)
KUNIT_EXPECT_EQ(test, i < 3 || i > 5,
regcache_reg_cached(map, param->from_reg + i));
/* Reread and check only the dropped registers hit the device */
for (i = 0; i < BLOCK_TEST_SIZE; i++)
data->read[i] = false;
for (i = 0; i < BLOCK_TEST_SIZE; i++) {
KUNIT_EXPECT_EQ(test, 0, regmap_read(map, param->from_reg + i,
&rval));
KUNIT_EXPECT_EQ(test, val[i], rval);
KUNIT_EXPECT_EQ(test, i >= 3 && i <= 5, data->read[i]);
}
}
/* Check that caching the window register works with sync */
static void cache_range_window_reg(struct kunit *test)
{
@ -2168,6 +2259,7 @@ static struct kunit_case regmap_test_cases[] = {
KUNIT_CASE_PARAM(cache_drop_all_and_sync_has_defaults, sparse_cache_types_gen_params),
KUNIT_CASE_PARAM(cache_present, sparse_cache_types_gen_params),
KUNIT_CASE_PARAM(cache_write_zero, sparse_cache_types_gen_params),
KUNIT_CASE_PARAM(cache_high_bit_reg, high_bit_cache_types_gen_params),
KUNIT_CASE_PARAM(cache_range_window_reg, real_cache_types_only_gen_params),
KUNIT_CASE_PARAM(raw_read_defaults_single, raw_test_types_gen_params),

View File

@ -20,8 +20,11 @@ static int regmap_ram_write(void *context, unsigned int reg, unsigned int val)
{
struct regmap_ram_data *data = context;
data->vals[reg] = val;
data->written[reg] = true;
if (reg < data->base_reg)
return -EINVAL;
data->vals[reg - data->base_reg] = val;
data->written[reg - data->base_reg] = true;
return 0;
}
@ -30,8 +33,11 @@ static int regmap_ram_read(void *context, unsigned int reg, unsigned int *val)
{
struct regmap_ram_data *data = context;
*val = data->vals[reg];
data->read[reg] = true;
if (reg < data->base_reg)
return -EINVAL;
*val = data->vals[reg - data->base_reg];
data->read[reg - data->base_reg] = true;
return 0;
}
@ -60,17 +66,25 @@ struct regmap *__regmap_init_ram(struct device *dev,
const char *lock_name)
{
struct regmap *map;
unsigned int num_regs;
if (!config->max_register) {
pr_crit("No max_register specified for RAM regmap\n");
return ERR_PTR(-EINVAL);
}
data->read = kzalloc_objs(bool, config->max_register + 1);
if (data->base_reg > config->max_register) {
pr_crit("base_reg above max_register for RAM regmap\n");
return ERR_PTR(-EINVAL);
}
num_regs = config->max_register - data->base_reg + 1;
data->read = kzalloc_objs(bool, num_regs);
if (!data->read)
return ERR_PTR(-ENOMEM);
data->written = kzalloc_objs(bool, config->max_register + 1);
data->written = kzalloc_objs(bool, num_regs);
if (!data->written) {
kfree(data->read);
return ERR_PTR(-ENOMEM);

View File

@ -16,14 +16,17 @@
#include "internal.h"
static unsigned int decode_reg(enum regmap_endian endian, const void *reg)
static unsigned int decode_reg(struct regmap_ram_data *data, const void *reg)
{
const u16 *r = reg;
unsigned int decode;
if (endian == REGMAP_ENDIAN_BIG)
return be16_to_cpu(*r);
if (data->reg_endian == REGMAP_ENDIAN_BIG)
decode = be16_to_cpu(*r);
else
return le16_to_cpu(*r);
decode = le16_to_cpu(*r);
return decode - data->base_reg;
}
static int regmap_raw_ram_gather_write(void *context,
@ -40,7 +43,7 @@ static int regmap_raw_ram_gather_write(void *context,
if (val_len % 2)
return -EINVAL;
r = decode_reg(data->reg_endian, reg);
r = decode_reg(data, reg);
if (data->noinc_reg && data->noinc_reg(data, r)) {
memcpy(&our_buf[r], val + val_len - 2, 2);
data->written[r] = true;
@ -74,7 +77,7 @@ static int regmap_raw_ram_read(void *context,
if (val_len % 2)
return -EINVAL;
r = decode_reg(data->reg_endian, reg);
r = decode_reg(data, reg);
if (data->noinc_reg && data->noinc_reg(data, r)) {
for (i = 0; i < val_len; i += 2)
memcpy(val + i, &our_buf[r], 2);
@ -114,6 +117,7 @@ struct regmap *__regmap_init_raw_ram(struct device *dev,
const char *lock_name)
{
struct regmap *map;
unsigned int regs;
if (config->reg_bits != 16)
return ERR_PTR(-EINVAL);
@ -123,11 +127,12 @@ struct regmap *__regmap_init_raw_ram(struct device *dev,
return ERR_PTR(-EINVAL);
}
data->read = kzalloc_objs(bool, config->max_register + 1);
regs = config->max_register - data->base_reg + 1;
data->read = kzalloc_objs(bool, regs);
if (!data->read)
return ERR_PTR(-ENOMEM);
data->written = kzalloc_objs(bool, config->max_register + 1);
data->written = kzalloc_objs(bool, regs);
if (!data->written)
return ERR_PTR(-ENOMEM);

View File

@ -2722,7 +2722,7 @@ EXPORT_SYMBOL_GPL(regmap_multi_reg_write_bypassed);
* If supported by the underlying bus the write will be scheduled
* asynchronously, helping maximise I/O speed on higher speed buses
* like SPI. regmap_async_complete() can be called to ensure that all
* asynchrnous writes have been completed.
* asynchronous writes have been completed.
*
* A value of zero will be returned on success, a negative errno will
* be returned in error cases.

View File

@ -2960,6 +2960,8 @@ int cs_dsp_run(struct cs_dsp *dsp)
return 0;
err:
dsp->running = false;
if (dsp->ops->stop_core)
dsp->ops->stop_core(dsp);
if (dsp->ops->disable_core)
@ -3505,7 +3507,7 @@ EXPORT_SYMBOL_NS_GPL(cs_dsp_chunk_write, "FW_CS_DSP");
*
* As cs_dsp_chunk_write only writes data when a whole DSP word is ready to
* be written out it is possible that some data will remain in the cache, this
* function will pad that data with zeros upto a whole DSP word and write out.
* function will pad that data with zeros up to a whole DSP word and write out.
*
* Return: Zero for success, a negative number on error.
*/

View File

@ -36,6 +36,8 @@ struct cs_dsp_test_local {
int num_post_stop;
int num_watchdog_expired;
bool fail_post_run;
struct cs_dsp_coeff_ctl *passed_ctl[16];
struct cs_dsp *passed_dsp;
};
@ -106,6 +108,9 @@ static int cs_dsp_test_post_run_callback(struct cs_dsp *dsp)
local->passed_dsp = dsp;
local->num_post_run++;
if (local->fail_post_run)
return -EIO;
return 0;
}
@ -198,6 +203,33 @@ static void cs_dsp_test_run_stop_callbacks(struct kunit *test)
local->passed_dsp = NULL;
}
static void cs_dsp_test_run_error_clears_running(struct kunit *test)
{
struct cs_dsp_test *priv = test->priv;
struct cs_dsp_test_local *local = priv->local;
struct firmware *wmfw;
wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder);
KUNIT_EXPECT_EQ(test,
cs_dsp_power_up(priv->dsp, wmfw, "wmfw", NULL, NULL, "misc"),
0);
/*
* By the time the post_run hook runs, the core has been started. A
* failure there stops and disables the core again, so the DSP must not
* be left looking like it is running.
*/
local->fail_post_run = true;
KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), -EIO);
KUNIT_EXPECT_FALSE(test, priv->dsp->running);
/* and the next run must be able to start it again */
local->fail_post_run = false;
KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), 0);
KUNIT_EXPECT_TRUE(test, priv->dsp->running);
}
static void cs_dsp_test_ctl_v1_callbacks(struct kunit *test)
{
struct cs_dsp_test *priv = test->priv;
@ -609,6 +641,7 @@ KUNIT_ARRAY_PARAM(cs_dsp_no_callbacks,
static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv1_test_cases[] = {
KUNIT_CASE_PARAM(cs_dsp_test_run_stop_callbacks, cs_dsp_callbacks_ops_gen_params),
KUNIT_CASE_PARAM(cs_dsp_test_run_error_clears_running, cs_dsp_callbacks_ops_gen_params),
KUNIT_CASE_PARAM(cs_dsp_test_ctl_v1_callbacks, cs_dsp_callbacks_ops_gen_params),
KUNIT_CASE_PARAM(cs_dsp_test_no_callbacks, cs_dsp_no_callbacks_gen_params),
@ -617,6 +650,7 @@ static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv1_test_cases[] = {
static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv2_test_cases[] = {
KUNIT_CASE_PARAM(cs_dsp_test_run_stop_callbacks, cs_dsp_callbacks_ops_gen_params),
KUNIT_CASE_PARAM(cs_dsp_test_run_error_clears_running, cs_dsp_callbacks_ops_gen_params),
KUNIT_CASE_PARAM(cs_dsp_test_ctl_v2_callbacks, cs_dsp_callbacks_ops_gen_params),
KUNIT_CASE_PARAM(cs_dsp_test_no_callbacks, cs_dsp_no_callbacks_gen_params),
@ -625,6 +659,7 @@ static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv2_test_cases[] = {
static struct kunit_case cs_dsp_callbacks_halo_test_cases[] = {
KUNIT_CASE_PARAM(cs_dsp_test_run_stop_callbacks, cs_dsp_callbacks_ops_gen_params),
KUNIT_CASE_PARAM(cs_dsp_test_run_error_clears_running, cs_dsp_callbacks_ops_gen_params),
KUNIT_CASE_PARAM(cs_dsp_test_ctl_v2_callbacks, cs_dsp_callbacks_ops_gen_params),
KUNIT_CASE_PARAM(cs_dsp_test_no_callbacks, cs_dsp_no_callbacks_gen_params),

View File

@ -1458,11 +1458,15 @@ static int fmh_gpib_attach_impl(struct gpib_board *board, const struct gpib_boar
e_priv->irq = irq;
if (acquire_dma) {
e_priv->dma_channel = dma_request_slave_channel(board->dev, "rxtx");
if (!e_priv->dma_channel) {
struct dma_chan *tmp_chan;
tmp_chan = dma_request_chan(board->dev, "rxtx");
retval = PTR_ERR_OR_ZERO(tmp_chan);
if (retval) {
dev_err(board->dev, "failed to acquire dma channel \"rxtx\".\n");
return -EIO;
return retval;
}
e_priv->dma_channel = tmp_chan;
}
/*
* in the future we might want to know the half-fifo size

View File

@ -17,6 +17,33 @@
#define CS35L45_ASP_TX_HIZ_UNUSED 0x1
#define CS35L45_ASP_TX_HIZ_DISABLED 0x2
/*
* cirrus,boost-low-power-mode
*
* BST_LPMODE_NO_REACTION: No reaction
* BST_LPMODE_DCM_MODE: Force boost DCM low power mode
* BST_LPMODE_STATIC_BYPASS: Force boost static bypass
*/
#define CS35L45_BST_LPMODE_NO_REACTION 0x0
#define CS35L45_BST_LPMODE_DCM_MODE 0x1
#define CS35L45_BST_LPMODE_STATIC_BYPASS 0x2
/*
* cirrus,amplifier-low-power-mode
*
* AMP_LPMODE_NG_MODE: Noise gate mode
* AMP_LPMODE_NFR_MODE: Noise floor reduction mode
*/
#define CS35L45_AMP_LPMODE_NG_MODE 0x0
#define CS35L45_AMP_LPMODE_NFR_MODE 0x1
/*
* cirrus,ldpm-groupX-pcm-threshold-db
*
* LDPM_PCM_THLD_TRUE_ZERO:
*/
#define CS35L45_LDPM_PCM_THLD_TRUE_ZERO -2147483648
/*
* Optional GPIOX Sub-nodes:
* The cs35l45 node can have up to three "cirrus,gpio-ctrlX" ('X' = [1,2,3])

View File

@ -156,6 +156,58 @@
#define LPI_MI2S_TX_5 150
#define LPI_MI2S_RX_6 151
#define LPI_MI2S_TX_6 152
#define AIF_MI2S_RX_0 153
#define AIF_MI2S_TX_0 154
#define AIF_MI2S_RX_1 155
#define AIF_MI2S_TX_1 156
#define AIF_MI2S_RX_2 157
#define AIF_MI2S_TX_2 158
#define AIF_MI2S_RX_3 159
#define AIF_MI2S_TX_3 160
#define AIF_MI2S_RX_4 161
#define AIF_MI2S_TX_4 162
#define AIF_MI2S_RX_5 163
#define AIF_MI2S_TX_5 164
#define AIF_MI2S_RX_6 165
#define AIF_MI2S_TX_6 166
#define AIF_MI2S_RX_7 167
#define AIF_MI2S_TX_7 168
#define AIF_MI2S_RX_8 169
#define AIF_MI2S_TX_8 170
#define AIF_MI2S_RX_9 171
#define AIF_MI2S_TX_9 172
#define AIF_MI2S_RX_10 173
#define AIF_MI2S_TX_10 174
#define AIF_MI2S_RX_11 175
#define AIF_MI2S_TX_11 176
#define AIF_MI2S_RX_12 177
#define AIF_MI2S_TX_12 178
#define AIF_TDM_RX_0 179
#define AIF_TDM_TX_0 180
#define AIF_TDM_RX_1 181
#define AIF_TDM_TX_1 182
#define AIF_TDM_RX_2 183
#define AIF_TDM_TX_2 184
#define AIF_TDM_RX_3 185
#define AIF_TDM_TX_3 186
#define AIF_TDM_RX_4 187
#define AIF_TDM_TX_4 188
#define AIF_TDM_RX_5 189
#define AIF_TDM_TX_5 190
#define AIF_TDM_RX_6 191
#define AIF_TDM_TX_6 192
#define AIF_TDM_RX_7 193
#define AIF_TDM_TX_7 194
#define AIF_TDM_RX_8 195
#define AIF_TDM_TX_8 196
#define AIF_TDM_RX_9 197
#define AIF_TDM_TX_9 198
#define AIF_TDM_RX_10 199
#define AIF_TDM_TX_10 200
#define AIF_TDM_RX_11 201
#define AIF_TDM_TX_11 202
#define AIF_TDM_RX_12 203
#define AIF_TDM_TX_12 204
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2

View File

@ -1760,15 +1760,6 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
#define dma_request_channel(mask, x, y) \
__dma_request_channel(&(mask), x, y, NULL)
/* Deprecated, please use dma_request_chan() directly */
static inline struct dma_chan * __deprecated
dma_request_slave_channel(struct device *dev, const char *name)
{
struct dma_chan *ch = dma_request_chan(dev, name);
return IS_ERR(ch) ? NULL : ch;
}
static inline struct dma_chan
*dma_request_slave_channel_compat(const dma_cap_mask_t mask,
dma_filter_fn fn, void *fn_param,

View File

@ -96,7 +96,7 @@ struct cs_dsp_alg_region {
struct cs_dsp_coeff_ctl {
struct list_head list;
struct cs_dsp *dsp;
void *cache;
void *cache __counted_by_ptr(len);
const char *fw_name;
/* Subname is needed to match with firmware */
const char *subname;

View File

@ -449,6 +449,11 @@
#define AW88399_NOISE_GATE_EN_MASK \
(~(((1<<AW88399_NOISE_GATE_EN_BITS_LEN)-1) << AW88399_NOISE_GATE_EN_START_BIT))
#define AW88399_EPS_EN_START_BIT (2)
#define AW88399_EPS_EN_BITS_LEN (1)
#define AW88399_EPS_EN_MASK \
(~(((1 << AW88399_EPS_EN_BITS_LEN) - 1) << AW88399_EPS_EN_START_BIT))
#define AW88399_WDT_CNT_START_BIT (0)
#define AW88399_WDT_CNT_BITS_LEN (8)
#define AW88399_WDT_CNT_MASK \
@ -598,7 +603,6 @@ struct aw88399 {
unsigned int crc_init_val;
unsigned int vcalb_init_val;
unsigned int dither_st;
bool bsts_unreliable;
bool fw_needs_reload;
};

View File

@ -188,6 +188,7 @@ struct snd_compr_ops {
* @card: sound card pointer
* @direction: Playback or capture direction
* @lock: device lock
* @open_list: list of open compress files
* @device: device id
* @use_pause_in_draining: allow pause in draining, true when set
*/
@ -199,6 +200,7 @@ struct snd_compr {
struct snd_card *card;
unsigned int direction;
struct mutex lock;
struct list_head open_list;
int device;
bool use_pause_in_draining;
#ifdef CONFIG_SND_VERBOSE_PROCFS

View File

@ -60,20 +60,16 @@ enum sdca_quirk {
SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING,
};
#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA)
#if IS_ENABLED(CONFIG_SND_SOC_SDCA)
void sdca_lookup_functions(struct sdw_slave *slave);
void sdca_lookup_swft(struct sdw_slave *slave);
void sdca_lookup_interface_revision(struct sdw_slave *slave);
bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk);
int sdca_dev_register_functions(struct sdw_slave *slave);
void sdca_dev_unregister_functions(struct sdw_slave *slave);
#else
static inline void sdca_lookup_functions(struct sdw_slave *slave) {}
static inline void sdca_lookup_swft(struct sdw_slave *slave) {}
static inline void sdca_lookup_interface_revision(struct sdw_slave *slave) {}
static inline bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk)
{
return false;
@ -88,4 +84,21 @@ static inline void sdca_dev_unregister_functions(struct sdw_slave *slave) {}
#endif
/*
* Called from the SoundWire bus during peripheral enumeration; gated on
* ACPI to avoid a soundwire_bus <-> snd_soc_sdca module cycle on DT builds
* (where the bodies are stubs anyway).
*/
#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA)
void sdca_lookup_functions(struct sdw_slave *slave);
void sdca_lookup_interface_revision(struct sdw_slave *slave);
#else
static inline void sdca_lookup_functions(struct sdw_slave *slave) {}
static inline void sdca_lookup_interface_revision(struct sdw_slave *slave) {}
#endif
#endif

View File

@ -0,0 +1,70 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* The MIPI SDCA specification is available for public downloads at
* https://www.mipi.org/mipi-sdca-v1-0-download
*
* Copyright (C) 2025 Cirrus Logic, Inc. and
* Cirrus Logic International Semiconductor Ltd.
*/
#ifndef __SDCA_CLASS_H__
#define __SDCA_CLASS_H__
#include <linux/completion.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
struct device;
struct regmap;
struct sdw_slave;
struct sdca_function_data;
/**
* struct sdca_class_ops - optional codec-provided class callbacks
* @populate_function: fill @function (entities, clusters, init_table, ...)
* from static tables in place of sdca_parse_function() on
* DT/non-DisCo platforms. Called once per SDCA function with
* @dev pointing at that function's device. Pure data source;
* performs no bus I/O. Return 0 on success or a negative errno.
*/
struct sdca_class_ops {
int (*populate_function)(struct device *dev,
struct sdca_function_data *function);
};
struct sdca_class_drv {
struct device *dev;
struct regmap *dev_regmap;
struct sdw_slave *sdw;
struct sdca_interrupt_info *irq_info;
const struct sdca_class_ops *ops;
struct mutex regmap_lock;
/* Serialise function initialisations */
struct mutex init_lock;
struct work_struct boot_work;
};
/* Library helpers used by codec-specific SDCA SoundWire drivers. */
int sdca_class_probe(struct sdw_slave *sdw,
struct sdca_class_drv *drv,
const struct sdca_class_ops *ops);
void sdca_class_remove(struct sdca_class_drv *drv);
/*
* PM helpers. Codec drivers embed sdca_class_drv in their own priv,
* own dev_set_drvdata(), and compose these into their own dev_pm_ops:
*
* static int wcd_runtime_suspend(struct device *dev) {
* struct wcd_priv *priv = dev_get_drvdata(dev);
* return sdca_class_runtime_suspend(&priv->class);
* }
*/
int sdca_class_runtime_suspend(struct sdca_class_drv *drv);
int sdca_class_runtime_resume(struct sdca_class_drv *drv);
int sdca_class_system_suspend(struct sdca_class_drv *drv);
int sdca_class_system_resume(struct sdca_class_drv *drv);
#endif /* __SDCA_CLASS_H__ */

View File

@ -219,12 +219,14 @@ static inline int simple_util_parse_aux_devs(struct simple_util_priv *priv, char
int simple_util_init_jack(struct snd_soc_card *card,
struct simple_util_jack *sjack,
int is_hp, char *prefix, char *pin);
void simple_util_remove_jack(struct simple_util_jack *sjack);
int simple_util_init_aux_jacks(struct snd_soc_card *card, char *prefix);
int simple_util_init_priv(struct simple_util_priv *priv,
struct link_info *li);
void simple_util_remove(struct platform_device *pdev);
int graph_util_card_probe(struct snd_soc_card *card);
int graph_util_card_remove(struct snd_soc_card *card);
int graph_util_is_ports0(struct device_node *port);
int graph_util_parse_dai(struct simple_util_priv *priv, struct device_node *ep,
struct snd_soc_dai_link_component *dlc, int *is_single_link);

View File

@ -258,10 +258,16 @@ struct snd_soc_component {
void *priv;
};
#define for_each_component_dais(component, dai)\
list_for_each_entry(dai, &(component)->dai_list, list)
#define for_each_component_dais_safe(component, dai, _dai)\
list_for_each_entry_safe(dai, _dai, &(component)->dai_list, list)
#define for_each_component_dais(component, dai) \
for (dai = snd_soc_dai_from_list((component)->dai_list.next); \
snd_soc_dai_to_list(dai) != &(component)->dai_list; \
dai = snd_soc_dai_from_list(snd_soc_dai_to_list(dai)->next))
#define for_each_component_dais_safe(component, dai, _dai) \
for (dai = snd_soc_dai_from_list((component)->dai_list.next), \
_dai = snd_soc_dai_from_list(snd_soc_dai_to_list(dai)->next); \
snd_soc_dai_to_list(dai) != &(component)->dai_list; \
dai = _dai, _dai = snd_soc_dai_from_list(snd_soc_dai_to_list(_dai)->next))
/**
* snd_soc_component_to_dapm() - Returns the DAPM context associated with a
@ -286,9 +292,12 @@ static inline int snd_soc_component_cache_sync(
return regcache_sync(component->regmap);
}
struct snd_soc_component *snd_soc_component_alloc(struct device *dev);
struct snd_soc_component *snd_soc_component_new(struct device *dev, const char *name,
const struct snd_soc_component_driver *driver);
int snd_soc_component_register(struct snd_soc_component *component,
struct snd_soc_dai_driver *dai_drv,
int num_dai);
void snd_soc_component_set_name(struct snd_soc_component *component, const char *name);
const char *snd_soc_component_name(struct snd_soc_component *component);
void snd_soc_component_set_priv(struct snd_soc_component *component, void *priv);

View File

@ -212,8 +212,11 @@ int snd_soc_dai_get_channel_map(const struct snd_soc_dai *dai,
unsigned int *tx_num, unsigned int *tx_slot,
unsigned int *rx_num, unsigned int *rx_slot);
struct snd_soc_component *snd_soc_dai_to_component(const struct snd_soc_dai *dai);
struct snd_soc_dai_driver *snd_soc_dai_to_driver(const struct snd_soc_dai *dai);
int snd_soc_dai_is_dummy(const struct snd_soc_dai *dai);
int snd_soc_dai_add_controls(struct snd_soc_dai *dai,
const struct snd_kcontrol_new *controls, int num_controls);
int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params);
@ -228,18 +231,7 @@ void snd_soc_dai_suspend(struct snd_soc_dai *dai);
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);
bool snd_soc_dai_stream_valid(const struct snd_soc_dai *dai, int stream);
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,
int stream)
{
snd_soc_dai_action(dai, stream, 1);
}
static inline void snd_soc_dai_deactivate(struct snd_soc_dai *dai,
int stream)
{
snd_soc_dai_action(dai, stream, -1);
}
int snd_soc_dai_active(const struct snd_soc_dai *dai);
int snd_soc_pcm_dai_probe(struct snd_soc_pcm_runtime *rtd, int order);
@ -277,7 +269,12 @@ int snd_soc_dai_compr_get_metadata(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_metadata *metadata);
const char *snd_soc_dai_name_get(const struct snd_soc_dai *dai);
int snd_soc_dai_matches_args(const struct snd_soc_dai *dai,
const struct of_phandle_args *args2);
int snd_soc_dai_matches_dlc(struct snd_soc_dai *dai,
const struct snd_soc_dai_link_component *dlc);
const char *snd_soc_dai_name(const struct snd_soc_dai *dai);
int snd_soc_dai_id(const struct snd_soc_dai *dai);
struct snd_soc_dai_ops {
/* DAI driver callbacks */
@ -489,69 +486,51 @@ struct snd_soc_dai {
void *priv;
};
const struct snd_soc_pcm_stream *
snd_soc_dai_pcm_stream_get_i(const struct snd_soc_dai *dai, int stream);
static inline const struct snd_soc_pcm_stream *
snd_soc_dai_get_pcm_stream(const struct snd_soc_dai *dai, int stream)
snd_soc_dai_pcm_stream_get_s(const struct snd_soc_dai *dai, struct snd_pcm_substream *substream)
{
return (stream == SNDRV_PCM_STREAM_PLAYBACK) ?
&dai->driver->playback : &dai->driver->capture;
return snd_soc_dai_pcm_stream_get_i(dai, substream->stream);
}
#define snd_soc_dai_pcm_stream_get(dai, x) _Generic((x), \
int : snd_soc_dai_pcm_stream_get_i, \
struct snd_pcm_substream * : snd_soc_dai_pcm_stream_get_s)(dai, x)
#define snd_soc_dai_get_widget_playback(dai) snd_soc_dai_get_widget(dai, SNDRV_PCM_STREAM_PLAYBACK)
#define snd_soc_dai_get_widget_capture(dai) snd_soc_dai_get_widget(dai, SNDRV_PCM_STREAM_CAPTURE)
static inline
struct snd_soc_dapm_widget *snd_soc_dai_get_widget(struct snd_soc_dai *dai, int stream)
{
return dai->stream[stream].widget;
}
#define snd_soc_dai_stream_widget_get_playback(dai) snd_soc_dai_stream_widget_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
#define snd_soc_dai_stream_widget_get_capture(dai) snd_soc_dai_stream_widget_get(dai, SNDRV_PCM_STREAM_CAPTURE)
struct snd_soc_dapm_widget *snd_soc_dai_stream_widget_get(struct snd_soc_dai *dai, int stream);
#define snd_soc_dai_set_widget_playback(dai, widget) snd_soc_dai_set_widget(dai, SNDRV_PCM_STREAM_PLAYBACK, widget)
#define snd_soc_dai_set_widget_capture(dai, widget) snd_soc_dai_set_widget(dai, SNDRV_PCM_STREAM_CAPTURE, widget)
static inline
void snd_soc_dai_set_widget(struct snd_soc_dai *dai, int stream, struct snd_soc_dapm_widget *widget)
{
dai->stream[stream].widget = widget;
}
#define snd_soc_dai_stream_widget_set_playback(dai, widget) snd_soc_dai_stream_widget_set(dai, SNDRV_PCM_STREAM_PLAYBACK, widget)
#define snd_soc_dai_stream_widget_set_capture(dai, widget) snd_soc_dai_stream_widget_set(dai, SNDRV_PCM_STREAM_CAPTURE, widget)
void snd_soc_dai_stream_widget_set(struct snd_soc_dai *dai, int stream, struct snd_soc_dapm_widget *widget);
#define snd_soc_dai_dma_data_get_playback(dai) snd_soc_dai_dma_data_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
#define snd_soc_dai_dma_data_get_capture(dai) snd_soc_dai_dma_data_get(dai, SNDRV_PCM_STREAM_CAPTURE)
#define snd_soc_dai_get_dma_data(dai, ss) snd_soc_dai_dma_data_get(dai, ss->stream)
static inline void *snd_soc_dai_dma_data_get(const struct snd_soc_dai *dai, int stream)
#define snd_soc_dai_stream_dma_data_get_playback(dai) snd_soc_dai_stream_dma_data_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
#define snd_soc_dai_stream_dma_data_get_capture(dai) snd_soc_dai_stream_dma_data_get(dai, SNDRV_PCM_STREAM_CAPTURE)
void *snd_soc_dai_stream_dma_data_get_i(const struct snd_soc_dai *dai, int stream);
static inline void *snd_soc_dai_stream_dma_data_get_s(const struct snd_soc_dai *dai, struct snd_pcm_substream *substream)
{
return dai->stream[stream].dma_data;
return snd_soc_dai_stream_dma_data_get_i(dai, substream->stream);
}
#define snd_soc_dai_stream_dma_data_get(dai, x) _Generic((x), \
int : snd_soc_dai_stream_dma_data_get_i, \
struct snd_pcm_substream * : snd_soc_dai_stream_dma_data_get_s)(dai, x)
#define snd_soc_dai_dma_data_set_playback(dai, data) snd_soc_dai_dma_data_set(dai, SNDRV_PCM_STREAM_PLAYBACK, data)
#define snd_soc_dai_dma_data_set_capture(dai, data) snd_soc_dai_dma_data_set(dai, SNDRV_PCM_STREAM_CAPTURE, data)
#define snd_soc_dai_set_dma_data(dai, ss, data) snd_soc_dai_dma_data_set(dai, ss->stream, data)
static inline void snd_soc_dai_dma_data_set(struct snd_soc_dai *dai, int stream, void *data)
#define snd_soc_dai_stream_dma_data_set_playback(dai, data) snd_soc_dai_stream_dma_data_set(dai, SNDRV_PCM_STREAM_PLAYBACK, data)
#define snd_soc_dai_stream_dma_data_set_capture(dai, data) snd_soc_dai_stream_dma_data_set(dai, SNDRV_PCM_STREAM_CAPTURE, data)
void snd_soc_dai_stream_dma_data_set_i(struct snd_soc_dai *dai, int stream, void *data);
static inline void snd_soc_dai_stream_dma_data_set_s(struct snd_soc_dai *dai, struct snd_pcm_substream *substream, void *data)
{
dai->stream[stream].dma_data = data;
snd_soc_dai_stream_dma_data_set_i(dai, substream->stream, data);
}
#define snd_soc_dai_stream_dma_data_set(dai, x, data) _Generic((x), \
int : snd_soc_dai_stream_dma_data_set_i, \
struct snd_pcm_substream * : snd_soc_dai_stream_dma_data_set_s)(dai, x, data)
static inline void snd_soc_dai_init_dma_data(struct snd_soc_dai *dai, void *playback, void *capture)
{
snd_soc_dai_dma_data_set_playback(dai, playback);
snd_soc_dai_dma_data_set_capture(dai, capture);
}
unsigned int snd_soc_dai_stream_tdm_mask_get(const struct snd_soc_dai *dai, int stream);
void snd_soc_dai_stream_tdm_mask_set(struct snd_soc_dai *dai, int stream, unsigned int tdm_mask);
static inline unsigned int snd_soc_dai_tdm_mask_get(const struct snd_soc_dai *dai,
int stream)
{
return dai->stream[stream].tdm_mask;
}
static inline void snd_soc_dai_tdm_mask_set(struct snd_soc_dai *dai, int stream,
unsigned int tdm_mask)
{
dai->stream[stream].tdm_mask = tdm_mask;
}
static inline unsigned int snd_soc_dai_stream_active(const struct snd_soc_dai *dai,
int stream)
{
/* see snd_soc_dai_action() for setup */
return dai->stream[stream].active;
}
unsigned int snd_soc_dai_stream_active(const struct snd_soc_dai *dai, int stream);
static inline void snd_soc_dai_set_drvdata(struct snd_soc_dai *dai,
void *data)
@ -564,45 +543,43 @@ static inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai)
return dev_get_drvdata(dai->dev);
}
/**
* snd_soc_dai_set_stream() - Configures a DAI for stream operation
* @dai: DAI
* @stream: STREAM (opaque structure depending on DAI type)
* @direction: Stream direction(Playback/Capture)
* Some subsystems, such as SoundWire, don't have a notion of direction and we reuse
* the ASoC stream direction to configure sink/source ports.
* Playback maps to source ports and Capture for sink ports.
*
* This should be invoked with NULL to clear the stream set previously.
* Returns 0 on success, a negative error code otherwise.
*/
static inline int snd_soc_dai_set_stream(struct snd_soc_dai *dai,
void *stream, int direction)
{
if (dai->driver->ops->set_stream)
return dai->driver->ops->set_stream(dai, stream, direction);
else
return -ENOTSUPP;
}
int snd_soc_dai_set_stream(struct snd_soc_dai *dai, void *stream, int direction);
void *snd_soc_dai_get_stream(struct snd_soc_dai *dai, int direction);
/**
* snd_soc_dai_get_stream() - Retrieves stream from DAI
* @dai: DAI
* @direction: Stream direction(Playback/Capture)
*
* This routine only retrieves that was previously configured
* with snd_soc_dai_get_stream()
*
* Returns pointer to stream or an ERR_PTR value, e.g.
* ERR_PTR(-ENOTSUPP) if callback is not supported;
*/
static inline void *snd_soc_dai_get_stream(struct snd_soc_dai *dai,
int direction)
struct snd_soc_dai *snd_soc_dai_register(struct snd_soc_component *component,
struct snd_soc_dai_driver *dai_drv,
bool legacy_dai_naming);
void snd_soc_dai_unregister(struct snd_soc_dai *dai);
struct snd_soc_dai *snd_soc_dai_from_list(struct list_head *list);
struct list_head *snd_soc_dai_to_list(struct snd_soc_dai *dai);
unsigned int snd_soc_dai_get_symmetric_rate(struct snd_soc_dai *dai);
unsigned int snd_soc_dai_get_symmetric_channels(struct snd_soc_dai *dai);
unsigned int snd_soc_dai_get_symmetric_sample_bits(struct snd_soc_dai *dai);
void snd_soc_dai_set_priv(struct snd_soc_dai *dai, void *priv);
void *snd_soc_dai_to_priv(struct snd_soc_dai *dai);
/* REMOVE ME */
#define snd_soc_dai_get_pcm_stream snd_soc_dai_pcm_stream_get
#define snd_soc_dai_get_widget_playback(dai) snd_soc_dai_stream_widget_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
#define snd_soc_dai_get_widget_capture(dai) snd_soc_dai_stream_widget_get(dai, SNDRV_PCM_STREAM_CAPTURE)
#define snd_soc_dai_get_widget snd_soc_dai_stream_widget_get
#define snd_soc_dai_set_widget_playback(dai, widget) snd_soc_dai_stream_widget_set(dai, SNDRV_PCM_STREAM_PLAYBACK, widget)
#define snd_soc_dai_set_widget_capture(dai, widget) snd_soc_dai_stream_widget_set(dai, SNDRV_PCM_STREAM_CAPTURE, widget)
#define snd_soc_dai_set_widget snd_soc_dai_stream_widget_set
#define snd_soc_dai_dma_data_get_playback(dai) snd_soc_dai_stream_dma_data_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
#define snd_soc_dai_dma_data_get_capture(dai) snd_soc_dai_stream_dma_data_get(dai, SNDRV_PCM_STREAM_CAPTURE)
#define snd_soc_dai_get_dma_data snd_soc_dai_stream_dma_data_get
#define snd_soc_dai_dma_data_get snd_soc_dai_stream_dma_data_get
#define snd_soc_dai_dma_data_set_playback(dai, data) snd_soc_dai_stream_dma_data_set(dai, SNDRV_PCM_STREAM_PLAYBACK, data)
#define snd_soc_dai_dma_data_set_capture(dai, data) snd_soc_dai_stream_dma_data_set(dai, SNDRV_PCM_STREAM_CAPTURE, data)
#define snd_soc_dai_set_dma_data snd_soc_dai_stream_dma_data_set
#define snd_soc_dai_dma_data_set snd_soc_dai_stream_dma_data_set
#define snd_soc_dai_tdm_mask_get snd_soc_dai_stream_tdm_mask_get
#define snd_soc_dai_tdm_mask_set snd_soc_dai_stream_tdm_mask_set
static inline void snd_soc_dai_init_dma_data(struct snd_soc_dai *dai, void *playback, void *capture)
{
if (dai->driver->ops->get_stream)
return dai->driver->ops->get_stream(dai, direction);
else
return ERR_PTR(-ENOTSUPP);
snd_soc_dai_stream_dma_data_set_playback(dai, playback);
snd_soc_dai_stream_dma_data_set_capture(dai, capture);
}
#endif

View File

@ -447,15 +447,9 @@ static inline int snd_soc_resume(struct device *dev)
}
#endif
int snd_soc_poweroff(struct device *dev);
int snd_soc_register_component_c(struct snd_soc_component *component,
const struct snd_soc_component_driver *component_driver,
struct snd_soc_dai_driver *dai_drv, int num_dai);
int snd_soc_register_component_d(struct device *dev,
int snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *component_driver,
struct snd_soc_dai_driver *dai_drv, int num_dai);
#define snd_soc_register_component(x, ...) _Generic((x), \
struct device * : snd_soc_register_component_d, \
struct snd_soc_component * : snd_soc_register_component_c)(x, __VA_ARGS__)
int devm_snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *component_driver,
@ -555,8 +549,6 @@ int snd_soc_add_component_controls(struct snd_soc_component *component,
const struct snd_kcontrol_new *controls, unsigned int num_controls);
int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
const struct snd_kcontrol_new *controls, int num_controls);
int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
const struct snd_kcontrol_new *controls, int num_controls);
int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
@ -1389,19 +1381,12 @@ void snd_soc_dlc_use_cpu_as_platform(struct snd_soc_dai_link_component *platform
struct of_phandle_args *snd_soc_copy_dai_args(struct device *dev,
const struct of_phandle_args *args);
struct snd_soc_dai *snd_soc_get_dai_via_args(const struct of_phandle_args *dai_args);
struct snd_soc_dai *snd_soc_register_dai(struct snd_soc_component *component,
struct snd_soc_dai_driver *dai_drv,
bool legacy_dai_naming);
void snd_soc_unregister_dai(struct snd_soc_dai *dai);
struct snd_soc_dai *snd_soc_find_dai(
const struct snd_soc_dai_link_component *dlc);
struct snd_soc_dai *snd_soc_find_dai_with_mutex(
const struct snd_soc_dai_link_component *dlc);
void soc_pcm_set_dai_params(struct snd_soc_dai *dai,
struct snd_pcm_hw_params *params);
#include <sound/soc-dai.h>
static inline
@ -1551,4 +1536,11 @@ static inline void _snd_soc_dpcm_mutex_assert_held_r(struct snd_soc_pcm_runtime
#include <sound/soc-card.h>
#include <sound/soc-jack.h>
/*
* REMOVE ME
*/
#define snd_soc_add_dai_controls snd_soc_dai_add_controls
#define snd_soc_register_dai snd_soc_dai_register
#define snd_soc_unregister_dai snd_soc_dai_unregister
#endif

View File

@ -292,4 +292,24 @@ int asoc_sdw_es9356_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai
int asoc_sdw_es9356_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_es9356_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
/* Senary SN624x SDCA */
int asoc_sdw_senary_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_senary_sdca_jack_exit(struct snd_soc_card *card,
struct snd_soc_dai_link *dai_link);
int asoc_sdw_senary_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dai *dai);
int asoc_sdw_senary_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_senary_amp_exit(struct snd_soc_card *card,
struct snd_soc_dai_link *dai_link);
int asoc_sdw_senary_sdca_spk_rtd_init(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dai *dai);
int asoc_sdw_senary_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dai *dai);
#endif

View File

@ -436,12 +436,10 @@ enum sof_ipc4_fw_config_params {
SOF_IPC4_FW_CFG_RESERVED,
SOF_IPC4_FW_CFG_POWER_GATING_POLICY,
SOF_IPC4_FW_CFG_ASSERT_MODE,
SOF_IPC4_FW_RESERVED1,
SOF_IPC4_FW_RESERVED2,
SOF_IPC4_FW_RESERVED3,
SOF_IPC4_FW_RESERVED4,
SOF_IPC4_FW_RESERVED5,
SOF_IPC4_FW_CONTEXT_SAVE
/* Reserved: 24 - 28 */
SOF_IPC4_FW_CONTEXT_SAVE = 29,
/* Reserved: 30 - 34 */
SOF_IPC4_FW_CFG_SOF_INFO = 35,
};
struct sof_ipc4_fw_version {
@ -451,6 +449,14 @@ struct sof_ipc4_fw_version {
uint16_t build;
} __packed;
/*
* tuple based array for SOF specific information under SOF_IPC4_FW_CFG_SOF_INFO
* tuple of fw_config
*/
enum ipc4_fw_sof_info_params {
SOF_IPC4_SOF_CODEC_INFO,
};
/* Payload data for SOF_IPC4_MOD_SET_DX */
struct sof_ipc4_dx_state_info {
/* core(s) to apply the change */
@ -641,9 +647,10 @@ struct sof_ipc4_notify_module_data {
* The event_data contains the struct sof_ipc4_control_msg_payload of the control
* which sent the notification.
*/
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_MASK GENMASK(31, 16)
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_SOF_MAGIC_MASK GENMASK(31, 16)
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_VAL 0xA15A0000
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_PARAMID_MASK GENMASK(15, 0)
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_COMPR_MAGIC_VAL 0xC0C00000
/*
* Macros for creating struct sof_ipc4_module_init_ext_init payload
@ -706,7 +713,8 @@ struct sof_ipc4_module_init_ext_object {
enum sof_ipc4_mod_init_ext_obj_id {
SOF_IPC4_MOD_INIT_DATA_ID_INVALID = 0,
SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA,
SOF_IPC4_MOD_INIT_DATA_ID_MAX = SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA,
SOF_IPC4_MOD_INIT_DATA_ID_MODULE_DATA,
SOF_IPC4_MOD_INIT_DATA_ID_MAX = SOF_IPC4_MOD_INIT_DATA_ID_MODULE_DATA,
};
/* DP module memory configuration data object for object array */

View File

@ -56,6 +56,10 @@ enum tasdevice_dsp_dev_idx {
TASDEVICE_DSP_TAS_2781_QUAD,
TASDEVICE_DSP_TAS_5825_MONO,
TASDEVICE_DSP_TAS_5825_DUAL,
TASDEVICE_DSP_TAS_2573_MONO,
TASDEVICE_DSP_TAS_2573_DUAL,
TASDEVICE_DSP_TAS_2573_21,
TASDEVICE_DSP_TAS_2573_QUAD,
TASDEVICE_DSP_TAS_MAX_DEVICE
};
@ -142,6 +146,7 @@ struct tasdevice_fw {
struct tasdevice_calibration *calibrations;
struct fct_param_address fct_par_addr;
struct device *dev;
int calibration_config_id;
};
enum tasdevice_fw_state {
@ -206,6 +211,14 @@ struct tasdevice_rca {
* capture.
*/
int capture_profile_id;
/*
* Primarily designed for speaker calibration scenarios with special
* requirements. For regular use cases, when the default value -1 is
* set, calibration will directly reuse the current playback
* configuration; non-negative values can be customized for special
* calibration demands.
*/
int calibration_profile_id;
/*
* Since version 0x105, the keyword 'init' was introduced into the
* profile, which is used for chip initialization, particularly to

View File

@ -49,6 +49,13 @@
#define TASDEVICE_REG(book, page, reg) (((book * 256 * 128) + \
(page * 128)) + reg)
#define TAS_REG_ERR_LOG(dev, chn, reg, ret) \
dev_err((dev), "%s, C%uBx%02xPx%02xRx%02x E=%d\n", \
__func__, chn, TASDEVICE_BOOK_ID(reg), \
TASDEVICE_PAGE_ID(reg), \
TASDEVICE_PAGE_REG(reg), \
(ret))
/* Software Reset, compatble with new device (TAS5825). */
#define TASDEVICE_REG_SWRESET TASDEVICE_REG(0x0, 0x0, 0x01)
#define TASDEVICE_REG_SWRESET_RESET BIT(0)
@ -91,6 +98,30 @@
/* prm_TE_1_Beta1 */
#define TAS2563_TE_DT_REG TASDEVICE_REG(0x00, 0x0f, 0x70)
#define TAS2573_FCT_INT_LATCH TASDEVICE_REG(0x00, 0x00, 0x67)
/* YM57 */
#define TAS2573_FCT_OUTPUT_R0 TASDEVICE_REG(0x00, 0x65, 0x74)
/* YM58 */
#define TAS2573_FCT_OUTPUT_R0_LOW TASDEVICE_REG(0x00, 0x65, 0x78)
/* YM59 */
#define TAS2573_FCT_OUTPUT_INV_R0 TASDEVICE_REG(0x00, 0x65, 0x7C)
/* YM61 */
#define TAS2573_FCT_OUTPUT_POWERTOT TASDEVICE_REG(0x00, 0x66, 0x0C)
/* YM64 */
#define TAS2573_FCT_OUTPUT_F0 TASDEVICE_REG(0x00, 0x65, 0x18)
/* YM147 */
#define TAS2573_FCT_STATUS_CTRL TASDEVICE_REG(0x00, 0x68, 0x74)
/* YM148 */
#define TAS2573_FCT_STATUS_BINNING TASDEVICE_REG(0x00, 0x68, 0x78)
/* YM664 */
#define TAS2573_RE_OUT TASDEVICE_REG(0x00, 0x7A, 0x18)
/* YM952 */
#define TAS2573_SILENCE_DETECTED TASDEVICE_REG(0x00, 0x83, 0x60)
/* YM954 */
#define TAS2573_OPEN_CIRCUIT TASDEVICE_REG(0x00, 0x83, 0x68)
/* YM955 */
#define TAS2573_SHORTCKT TASDEVICE_REG(0x00, 0x83, 0x6C)
#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)

View File

@ -42,6 +42,7 @@
#endif
struct snd_compr_file {
struct list_head list;
unsigned long caps;
struct snd_compr_stream stream;
};
@ -75,11 +76,11 @@ static inline void snd_compr_task_free_all(struct snd_compr_stream *stream) { }
static int snd_compr_open(struct inode *inode, struct file *f)
{
struct snd_compr *compr;
struct snd_compr_file *data;
struct snd_compr_runtime *runtime;
struct snd_compr_file *data = NULL;
struct snd_compr_runtime *runtime = NULL;
enum snd_compr_direction dirn;
int maj = imajor(inode);
int ret;
int ret = 0;
if ((f->f_flags & O_ACCMODE) == O_WRONLY)
dirn = SND_COMPRESS_PLAYBACK;
@ -101,17 +102,30 @@ static int snd_compr_open(struct inode *inode, struct file *f)
return -ENODEV;
}
ret = snd_card_file_add(compr->card, f);
if (ret < 0) {
snd_card_unref(compr->card);
return ret;
}
if (!try_module_get(compr->card->module)) {
snd_card_file_remove(compr->card, f);
snd_card_unref(compr->card);
return -EFAULT;
}
if (dirn != compr->direction) {
pr_err("this device doesn't support this direction\n");
snd_card_unref(compr->card);
return -EINVAL;
ret = -EINVAL;
goto __error;
}
data = kzalloc_obj(*data);
if (!data) {
snd_card_unref(compr->card);
return -ENOMEM;
ret = -ENOMEM;
goto __error;
}
INIT_LIST_HEAD(&data->list);
INIT_DELAYED_WORK(&data->stream.error_work, error_delayed_work);
@ -121,9 +135,8 @@ static int snd_compr_open(struct inode *inode, struct file *f)
data->stream.device = compr;
runtime = kzalloc_obj(*runtime);
if (!runtime) {
kfree(data);
snd_card_unref(compr->card);
return -ENOMEM;
ret = -ENOMEM;
goto __error;
}
runtime->state = SNDRV_PCM_STATE_OPEN;
init_waitqueue_head(&runtime->sleep);
@ -132,11 +145,18 @@ static int snd_compr_open(struct inode *inode, struct file *f)
#endif
data->stream.runtime = runtime;
f->private_data = (void *)data;
scoped_guard(mutex, &compr->lock)
scoped_guard(mutex, &compr->lock) {
ret = compr->ops->open(&data->stream);
if (!ret)
list_add_tail(&data->list, &compr->open_list);
}
__error:
if (ret) {
kfree(runtime);
kfree(data);
module_put(compr->card->module);
snd_card_file_remove(compr->card, f);
}
snd_card_unref(compr->card);
return ret;
@ -146,17 +166,23 @@ static int snd_compr_free(struct inode *inode, struct file *f)
{
struct snd_compr_file *data = f->private_data;
struct snd_compr_runtime *runtime = data->stream.runtime;
struct snd_compr *compr = data->stream.device;
cancel_delayed_work_sync(&data->stream.error_work);
switch (runtime->state) {
case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_DRAINING:
case SNDRV_PCM_STATE_PAUSED:
data->stream.ops->trigger(&data->stream, SNDRV_PCM_TRIGGER_STOP);
break;
default:
break;
scoped_guard(mutex, &compr->lock) {
if (!list_empty(&data->list))
list_del_init(&data->list);
switch (runtime->state) {
case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_DRAINING:
case SNDRV_PCM_STATE_PAUSED:
data->stream.ops->trigger(&data->stream, SNDRV_PCM_TRIGGER_STOP);
break;
default:
break;
}
}
snd_compr_task_free_all(&data->stream);
@ -164,8 +190,10 @@ static int snd_compr_free(struct inode *inode, struct file *f)
data->stream.ops->free(&data->stream);
if (!data->stream.runtime->dma_buffer_p)
kfree(data->stream.runtime->buffer);
module_put(data->stream.device->card->module);
kfree(data->stream.runtime);
kfree(data);
snd_card_file_remove(compr->card, f);
return 0;
}
@ -919,8 +947,10 @@ static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
* It is expected that driver will notify the drain completion and then
* stream will be moved to SETUP state, even if draining resulted in an
* error. We can trigger next track after this.
*
* The state has been set to SNDRV_PCM_STATE_DRAINING by the caller,
* before the drain trigger was issued.
*/
stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
mutex_unlock(&stream->device->lock);
/* we wait for drain to complete here, drain can return when
@ -945,6 +975,7 @@ static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
static int snd_compr_drain(struct snd_compr_stream *stream)
{
snd_pcm_state_t state;
int retval;
switch (stream->runtime->state) {
@ -959,9 +990,20 @@ static int snd_compr_drain(struct snd_compr_stream *stream)
break;
}
/*
* The state must be set to draining before the trigger is issued as the
* drain can be completed by the driver either from the trigger callback
* itself or from a different context as soon as the trigger is called.
* A snd_compr_drain_notify() arriving before the state is updated would
* be lost and the wait for the drain to finish would never be woken up.
*/
state = stream->runtime->state;
stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN);
if (retval) {
pr_debug("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval);
stream->runtime->state = state;
wake_up(&stream->runtime->sleep);
return retval;
}
@ -997,6 +1039,7 @@ static int snd_compr_next_track(struct snd_compr_stream *stream)
static int snd_compr_partial_drain(struct snd_compr_stream *stream)
{
snd_pcm_state_t state;
int retval;
switch (stream->runtime->state) {
@ -1020,9 +1063,16 @@ static int snd_compr_partial_drain(struct snd_compr_stream *stream)
return -EPERM;
stream->partial_drain = true;
/* See the comment in snd_compr_drain() on the state handling */
state = stream->runtime->state;
stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN);
if (retval) {
pr_debug("Partial drain returned failure\n");
stream->partial_drain = false;
stream->runtime->state = state;
wake_up(&stream->runtime->sleep);
return retval;
}
@ -1432,8 +1482,27 @@ static int snd_compress_dev_register(struct snd_device *device)
static int snd_compress_dev_disconnect(struct snd_device *device)
{
struct snd_compr *compr;
struct snd_compr_file *data;
compr = device->device_data;
scoped_guard(mutex, &compr->lock) {
list_for_each_entry(data, &compr->open_list, list) {
switch (data->stream.runtime->state) {
case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_DRAINING:
case SNDRV_PCM_STATE_PAUSED:
data->stream.ops->trigger(&data->stream,
SNDRV_PCM_TRIGGER_STOP);
break;
default:
break;
}
data->stream.runtime->state = SNDRV_PCM_STATE_DISCONNECTED;
wake_up(&data->stream.runtime->sleep);
}
}
snd_unregister_device(compr->dev);
return 0;
}
@ -1541,6 +1610,7 @@ int snd_compress_new(struct snd_card *card, int device,
compr->device = device;
compr->direction = dirn;
mutex_init(&compr->lock);
INIT_LIST_HEAD(&compr->open_list);
snd_compress_set_id(compr, id);

View File

@ -118,7 +118,6 @@ static int aw88399_hda_init(struct aw88399_hda *aw88399)
mutex_init(&core->lock);
core->reset_gpio = aw88399->reset_gpio;
core->regmap = aw88399->regmap;
core->bsts_unreliable = aw88399->bsts_unreliable;
aw88399_hw_reset(core);
@ -155,41 +154,20 @@ static int aw88399_swap_channels(struct aw88399_hda *aw88399)
return 0;
}
static int aw88399_skip_bsts_check(struct aw88399_hda *aw88399)
{
/*
* BSTS (boost-finished) status bit does not reliably report on
* some hardware. On certain Lenovo Legion laptops, both amps
* report BSTS=0 (boost not finished) during normal playback
* despite clean audio output. Skip BSTS in the startup status
* check to avoid false init failures.
*/
aw88399->bsts_unreliable = true;
dev_dbg(aw88399->dev, "BSTS status check disabled\n");
return 0;
}
static int aw88399_apply_legion_quirks(struct aw88399_hda *aw88399)
{
aw88399_swap_channels(aw88399);
aw88399_skip_bsts_check(aw88399);
return 0;
}
struct aw88399_prop_model {
const char *ssid;
int (*apply_prop)(struct aw88399_hda *aw88399);
};
static const struct aw88399_prop_model aw88399_prop_model_table[] = {
{ "17AA3906", aw88399_apply_legion_quirks },
{ "17AA3907", aw88399_apply_legion_quirks },
{ "17AA3927", aw88399_apply_legion_quirks },
{ "17AA3928", aw88399_apply_legion_quirks },
{ "17AA3936", aw88399_apply_legion_quirks },
{ "17AA3937", aw88399_apply_legion_quirks },
{ "17AA3938", aw88399_apply_legion_quirks },
{ "17AA3939", aw88399_apply_legion_quirks },
{ "17AA3906", aw88399_swap_channels },
{ "17AA3907", aw88399_swap_channels },
{ "17AA3927", aw88399_swap_channels },
{ "17AA3928", aw88399_swap_channels },
{ "17AA3936", aw88399_swap_channels },
{ "17AA3937", aw88399_swap_channels },
{ "17AA3938", aw88399_swap_channels },
{ "17AA3939", aw88399_swap_channels },
{ }
};

View File

@ -19,7 +19,6 @@ struct aw88399_hda {
struct gpio_desc *reset_gpio;
struct aw_device *aw_dev;
struct aw88399 *core;
bool bsts_unreliable;
const char *acpi_subsystem_id;
int index;

View File

@ -351,7 +351,7 @@ int intel_nhlt_ssp_device_type(struct device *dev, struct nhlt_acpi_table *nhlt,
int i;
if (!nhlt) {
dev_err(dev, "%s: NHLT table is missing (query for SSP%d)\n",
dev_dbg(dev, "%s: NHLT table is missing (query for SSP%d)\n",
__func__, virtual_bus_id);
return -EINVAL;
}
@ -369,7 +369,7 @@ int intel_nhlt_ssp_device_type(struct device *dev, struct nhlt_acpi_table *nhlt,
epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
}
dev_err(dev, "%s: No match for SSP%d in NHLT table\n", __func__,
dev_dbg(dev, "%s: No match for SSP%d in NHLT table\n", __func__,
virtual_bus_id);
dev_dbg(dev, "Available endpoints:\n");

View File

@ -30,7 +30,6 @@
static unsigned long acp2x_machine_id;
static struct snd_soc_jack st_jack;
static struct device *codec_dev;
static struct gpio_desc *gpio_pa;
static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
@ -191,6 +190,7 @@ static const struct acpi_gpio_mapping acpi_es8336_gpios[] = {
static int st_es8336_late_probe(struct snd_soc_card *card)
{
struct device *codec_dev __free(put_device) = NULL;
struct acpi_device *adev;
int ret;
@ -198,7 +198,7 @@ static int st_es8336_late_probe(struct snd_soc_card *card)
if (!adev)
return -ENODEV;
codec_dev = acpi_get_first_physical_node(adev);
codec_dev = acpi_bus_get_primary_device(adev);
acpi_dev_put(adev);
if (!codec_dev) {
dev_err(card->dev, "can not find codec dev\n");
@ -213,7 +213,6 @@ static int st_es8336_late_probe(struct snd_soc_card *card)
if (IS_ERR(gpio_pa)) {
ret = dev_err_probe(card->dev, PTR_ERR(gpio_pa),
"could not get pa-enable GPIO\n");
put_device(codec_dev);
return ret;
}
return 0;

View File

@ -167,7 +167,7 @@ config SND_SOC_AMD_SOF_SDW_MACH
config SND_SOC_AMD_LEGACY_SDW_MACH
tristate "AMD Legacy(No DSP) Soundwire Machine Driver Support"
depends on X86 && PCI && ACPI
depends on X86 && PCI && ACPI && EFI
depends on SOUNDWIRE
select SND_SOC_AMD_SDW_MACH_COMMON
select SND_SOC_SDW_UTILS
@ -181,7 +181,8 @@ config SND_SOC_AMD_LEGACY_SDW_MACH
select SND_SOC_RT715_SDW
select SND_SOC_RT715_SDCA_SDW
select SND_SOC_RT722_SDCA_SDW
select SND_SOC_TAS2783_SDW
select SND_SOC_ES9356 if SND_SOC_SDCA
select SND_SOC_TAS2783_SDW if SND_SOC_SDCA && EFI
help
This option enables Legacy(No DSP) sound card support for SoundWire
enabled AMD platforms along with ACP PDM controller.

View File

@ -265,6 +265,14 @@ static int create_sdw_dailink(struct snd_soc_card *card,
if (!soc_end->dai_info->direction[stream])
continue;
/*
* skip adding reference stream for amp type
* as legacy AMD doesn't use the DSP.
*/
if (soc_end->dai_info->dai_type == SOC_SDW_DAI_TYPE_AMP &&
stream == SNDRV_PCM_STREAM_CAPTURE)
continue;
int link_num = ffs(soc_end->link_mask) - 1;
cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
@ -448,6 +456,30 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
sdw_be_num = ret;
/*
* Legacy AMD has no DSP, so AMP reference capture streams are not
* supported. Subtract them from num_devs so create_sdw_dailink()
* uses the correct count directly, and decrement sdw_be_num when
* all capture endpoints on a DAI are AMP type.
*/
for (int i = 0; i < num_ends; i++) {
struct asoc_sdw_dailink *d = &soc_dais[i];
struct asoc_sdw_endpoint *e;
if (!d->initialised)
break;
if (!d->num_devs[SNDRV_PCM_STREAM_CAPTURE])
continue;
list_for_each_entry(e, &d->endpoints, list) {
if (e->dai_info->direction[SNDRV_PCM_STREAM_CAPTURE] &&
e->dai_info->dai_type == SOC_SDW_DAI_TYPE_AMP)
d->num_devs[SNDRV_PCM_STREAM_CAPTURE]--;
}
if (!d->num_devs[SNDRV_PCM_STREAM_CAPTURE])
sdw_be_num--;
}
/* enable dmic */
if (soc_sdw_quirk & ASOC_SDW_ACP_DMIC)
dmic_num = 1;

View File

@ -10,6 +10,7 @@
#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <sound/soc-acpi.h>
#include <acpi/acpi_bus.h>
#include <linux/clk.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
@ -41,6 +42,11 @@ struct acp3x_es83xx_private {
struct snd_soc_dapm_route mic_map[2];
};
static void acp3x_es83xx_put_codec_device(void *data)
{
put_device(data);
}
static const unsigned int channels[] = {
DUAL_CHANNEL,
};
@ -428,7 +434,7 @@ static int acp3x_es83xx_probe(struct snd_soc_card *card)
return -ENXIO;
}
codec_dev = acpi_get_first_physical_node(adev);
codec_dev = acpi_bus_get_primary_device(adev);
acpi_dev_put(adev);
if (!codec_dev) {
dev_warn(dev, "Error cannot find codec device, will defer probe\n");
@ -441,6 +447,12 @@ static int acp3x_es83xx_probe(struct snd_soc_card *card)
return -ENOMEM;
}
ret = devm_add_action_or_reset(dev,
acp3x_es83xx_put_codec_device,
codec_dev);
if (ret)
return ret;
priv->codec_dev = codec_dev;
priv->quirk = (unsigned long)dmi_id->driver_data;
acp_drvdata->mach_priv = priv;

View File

@ -117,6 +117,42 @@ static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = {
}
};
static const struct snd_soc_acpi_endpoint es9356_endpoints[] = {
{ /* Jack Playback Endpoint */
.num = 0,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
{ /* DMIC Capture Endpoint */
.num = 1,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
{ /* Jack Capture Endpoint */
.num = 2,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
{ /* Speaker Playback Endpoint */
.num = 3,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
};
static const struct snd_soc_acpi_adr_device es9356_0_adr[] = {
{
.adr = 0x00003004b3935601ull,
.num_endpoints = ARRAY_SIZE(es9356_endpoints),
.endpoints = es9356_endpoints,
.name_prefix = "es9356"
}
};
static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
{ /* Jack Playback Endpoint */
.num = 0,
@ -465,6 +501,15 @@ static const struct snd_soc_acpi_link_adr acp63_rt722_only[] = {
{}
};
static const struct snd_soc_acpi_link_adr acp63_es9356_only[] = {
{
.mask = BIT(0),
.num_adr = ARRAY_SIZE(es9356_0_adr),
.adr_d = es9356_0_adr,
},
{}
};
struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sof_sdw_machines[] = {
{
.link_mask = BIT(0) | BIT(1),
@ -478,6 +523,11 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sof_sdw_machines[] = {
EXPORT_SYMBOL(snd_soc_acpi_amd_acp63_sof_sdw_machines);
struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sdw_machines[] = {
{
.link_mask = BIT(0),
.links = acp63_es9356_only,
.drv_name = "amd_sdw",
},
{
.link_mask = BIT(0),
.links = acp63_rt722_only,

View File

@ -23,6 +23,19 @@
#define ACP71_PCI_REV 0x71
#define ACP72_PCI_REV 0x72
/**
* struct amd_pdm_pdata - platform data passed via mach->pdata to machine driver
* @pdm_sel: active PDM controller (ACP7X_PDM_DMIC0 or ACP7X_PDM_DMIC1),
* non-zero when a PDM controller was identified via ACPI _DSD
*
* Carries the PDM controller selection for ACP7.B/7.F platforms, derived
* from the acp-audio-ep-port ACPI _DSD property and passed via mach->pdata
* to the machine driver.
*/
struct amd_pdm_pdata {
unsigned int pdm_sel;
};
#define SOC_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0))
#define ASOC_SDW_FOUR_SPK BIT(4)
#define ASOC_SDW_ACP_DMIC BIT(5)

View File

@ -294,6 +294,7 @@ struct acp63_dev_data;
* struct acp_hw_ops - ACP PCI driver platform specific ops
* @acp_init: ACP initialization
* @acp_deinit: ACP de-initialization
* @disable_interrupts: disable ACP interrupt sources
* @acp_get_config: function to read the acp pin configuration
* @acp_sdw_dma_irq_thread: ACP SoundWire DMA interrupt thread
* acp_suspend: ACP system level suspend callback
@ -304,6 +305,7 @@ struct acp63_dev_data;
struct acp_hw_ops {
int (*acp_init)(void __iomem *acp_base, struct device *dev);
int (*acp_deinit)(void __iomem *acp_base, struct device *dev);
void (*disable_interrupts)(void __iomem *acp_base);
void (*acp_get_config)(struct pci_dev *pci, struct acp63_dev_data *acp_data);
void (*acp_sdw_dma_irq_thread)(struct acp63_dev_data *acp_data);
int (*acp_suspend)(struct device *dev);
@ -397,6 +399,12 @@ static inline int acp_hw_deinit(struct acp63_dev_data *adata, struct device *dev
return -EOPNOTSUPP;
}
static inline void acp_hw_disable_interrupts(struct acp63_dev_data *adata)
{
if (adata && adata->hw_ops && adata->hw_ops->disable_interrupts)
ACP_HW_OPS(adata, disable_interrupts)(adata->acp63_base);
}
static inline void acp_hw_get_config(struct pci_dev *pci, struct acp63_dev_data *adata)
{
if (adata && adata->hw_ops && adata->hw_ops->acp_get_config)

View File

@ -738,6 +738,8 @@ static void snd_acp63_remove(struct pci_dev *pci)
int ret;
adata = pci_get_drvdata(pci);
acp_hw_disable_interrupts(adata);
devm_free_irq(&pci->dev, pci->irq, adata);
if (adata->sdw) {
amd_sdw_exit(adata);
platform_device_unregister(adata->sdw_dma_dev);

View File

@ -248,6 +248,7 @@ void acp63_hw_init_ops(struct acp_hw_ops *hw_ops)
{
hw_ops->acp_init = acp63_init;
hw_ops->acp_deinit = acp63_deinit;
hw_ops->disable_interrupts = acp63_disable_interrupts;
hw_ops->acp_get_config = acp63_get_config;
hw_ops->acp_sdw_dma_irq_thread = acp63_sdw_dma_irq_thread;
hw_ops->acp_suspend = snd_acp63_suspend;
@ -484,6 +485,7 @@ void acp70_hw_init_ops(struct acp_hw_ops *hw_ops)
{
hw_ops->acp_init = acp70_init;
hw_ops->acp_deinit = acp70_deinit;
hw_ops->disable_interrupts = acp70_disable_interrupts;
hw_ops->acp_get_config = acp70_get_config;
hw_ops->acp_sdw_dma_irq_thread = acp70_sdw_dma_irq_thread;
hw_ops->acp_suspend = snd_acp70_suspend;

View File

@ -47,7 +47,7 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = {
* atmel_pcm_dma_irq: SSC interrupt handler for DMAENGINE enabled SSC
*
* We use DMAENGINE to send/receive data to/from SSC so this ISR is only to
* check if any overrun occured.
* check if any overrun occurred.
*/
static void atmel_pcm_dma_irq(u32 ssc_sr,
struct snd_pcm_substream *substream)

View File

@ -27,7 +27,7 @@ struct ringbuf_regs {
unsigned wraddr;
unsigned baseaddr;
unsigned endaddr;
unsigned fmark; /* freemark for play, fullmark for caputure */
unsigned fmark; /* freemark for play, fullmark for capture */
unsigned period_bytes;
unsigned buf_size;
};

View File

@ -1136,11 +1136,15 @@ static int pm860x_set_bias_level(struct snd_soc_component *component,
return 0;
}
static const u64 pm860x_selectable_formats = SND_SOC_POSSIBLE_DAIFMT_I2S;
static const struct snd_soc_dai_ops pm860x_pcm_dai_ops = {
.mute_stream = pm860x_mute_stream,
.hw_params = pm860x_pcm_hw_params,
.set_fmt = pm860x_pcm_set_dai_fmt,
.set_sysclk = pm860x_set_dai_sysclk,
.auto_selectable_formats = &pm860x_selectable_formats,
.num_auto_selectable_formats = 1,
.no_capture_mute = 1,
};
@ -1149,6 +1153,8 @@ static const struct snd_soc_dai_ops pm860x_i2s_dai_ops = {
.hw_params = pm860x_i2s_hw_params,
.set_fmt = pm860x_i2s_set_dai_fmt,
.set_sysclk = pm860x_set_dai_sysclk,
.auto_selectable_formats = &pm860x_selectable_formats,
.num_auto_selectable_formats = 1,
.no_capture_mute = 1,
};

View File

@ -123,6 +123,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_ES8328_I2C
imply SND_SOC_ES8375
imply SND_SOC_ES8389
imply SND_SOC_ES9039Q2M
imply SND_SOC_ES9356
imply SND_SOC_ES7134
imply SND_SOC_ES7241
@ -173,6 +174,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_MT6660
imply SND_SOC_NAU8315
imply SND_SOC_NAU8325
imply SND_SOC_NAU8360
imply SND_SOC_NAU8540
imply SND_SOC_NAU8810
imply SND_SOC_NAU8821
@ -255,6 +257,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_SIMPLE_MUX
imply SND_SOC_SMA1303
imply SND_SOC_SMA1307
imply SND_SOC_SN624X_SDCA_SDW
imply SND_SOC_SPDIF
imply SND_SOC_SRC4XXX_I2C
imply SND_SOC_SSM2305
@ -1315,6 +1318,19 @@ config SND_SOC_ES8389
tristate "Everest Semi ES8389 CODEC"
depends on I2C
config SND_SOC_ES9039Q2M
tristate "ESS Technology ES9039Q2M CODEC"
depends on I2C
select REGMAP_I2C
help
Enable support for the ESS Technology ES9039Q2M, a 32-bit
two-channel audio DAC with an asynchronous sample rate converter,
supporting PCM, DSD, DoP and S/PDIF input. This driver covers the
I2C control interface, which the MODE pin selects.
To compile this driver as a module, choose M here: the module
will be called snd-soc-es9039q2m.
config SND_SOC_ES9356
tristate "Everest Semi ES9356 CODEC SDW"
depends on SND_SOC_SDCA
@ -2097,6 +2113,18 @@ config SND_SOC_SMA1307
If you are using a system with an SMA1307 amplifier connected
via I2C, enable this option.
config SND_SOC_SN624X_SDCA_SDW
tristate "Senary SN624x SDCA Codec - SDW"
depends on SND_SOC_SDCA
depends on SOUNDWIRE
select REGMAP_SOUNDWIRE
select REGMAP_SOUNDWIRE_MBQ
help
Enable support for Senary SN624x SDCA SoundWire codecs.
These multi-function devices provide headset jack, speaker
amplifier, and digital microphone endpoints on the SoundWire
bus.
config SND_SOC_SPDIF
tristate "S/PDIF CODEC"
@ -2524,6 +2552,17 @@ config SND_SOC_WCD939X_SDW
The WCD9390/9395 is a audio codec IC Integrated in
Qualcomm SoCs like SM8650.
config SND_SOC_WCD9378_SDCA
tristate "Qualcomm Tambora (WCD9378) SDCA codec"
depends on SOUNDWIRE
depends on SND_SOC_SDCA_CLASS
help
This enables support for the Qualcomm Tambora (WCD9378) headset
codec when driven via the SDCA class driver on ARM platforms
without ACPI/DisCo tables. It provides the static SDCA topology
and SoundWire data port properties transcribed from the factory
ACPI tables.
config SND_SOC_WM0010
tristate
depends on SPI_MASTER
@ -2901,6 +2940,16 @@ config SND_SOC_NAU8825
tristate
depends on I2C
config SND_SOC_NAU8360
tristate "Nuvoton Technology Corporation NAU83G60 Stereo Smart Amplifier"
depends on I2C
select FW_LOADER
help
The NAU83G60 is a stereo 30W+30W smart amplifier with integrated
low-latency Advanced Audio DSP running the KCS (Klippel Controlled
Sound) speaker control algorithm. KCS provides mechanical and
thermal speaker protection with voltage and current sensing.
config SND_SOC_NTPFW
tristate

View File

@ -140,6 +140,7 @@ snd-soc-es8328-i2c-y := es8328-i2c.o
snd-soc-es8328-spi-y := es8328-spi.o
snd-soc-es8375-y := es8375.o
snd-soc-es8389-y := es8389.o
snd-soc-es9039q2m-y := es9039q2m.o
snd-soc-es9356-y := es9356.o
snd-soc-framer-y := framer-codec.o
snd-soc-fs-amp-lib-y := fs-amp-lib.o
@ -198,6 +199,7 @@ snd-soc-mt6359-accdet-y := mt6359-accdet.o
snd-soc-mt6660-y := mt6660.o
snd-soc-nau8315-y := nau8315.o
snd-soc-nau8325-y := nau8325.o
snd-soc-nau8360-y := nau8360.o nau8360-dsp.o
snd-soc-nau8540-y := nau8540.o
snd-soc-nau8810-y := nau8810.o
snd-soc-nau8821-y := nau8821.o
@ -301,6 +303,7 @@ snd-soc-sigmadsp-regmap-y := sigmadsp-regmap.o
snd-soc-si476x-y := si476x.o
snd-soc-sma1303-y := sma1303.o
snd-soc-sma1307-y := sma1307.o
snd-soc-sn624x-sdca-y := sn624x-sdca-sdw.o
snd-soc-spdif-tx-y := spdif_transmitter.o
snd-soc-spdif-rx-y := spdif_receiver.o
snd-soc-src4xxx-y := src4xxx.o
@ -366,6 +369,7 @@ snd-soc-wcd938x-y := wcd938x.o
snd-soc-wcd938x-sdw-y := wcd938x-sdw.o
snd-soc-wcd939x-y := wcd939x.o
snd-soc-wcd939x-sdw-y := wcd939x-sdw.o
snd-soc-wcd9378-y := wcd9378-sdw.o wcd9378-sdca.o
snd-soc-wm-adsp-y := wm_adsp.o
snd-soc-wm-adsp-test-y := wm_adsp_fw_find_test.o
snd-soc-wm0010-y := wm0010.o
@ -584,6 +588,7 @@ obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o
obj-$(CONFIG_SND_SOC_ES8375) += snd-soc-es8375.o
obj-$(CONFIG_SND_SOC_ES8389) += snd-soc-es8389.o
obj-$(CONFIG_SND_SOC_ES9039Q2M) += snd-soc-es9039q2m.o
obj-$(CONFIG_SND_SOC_ES9356) += snd-soc-es9356.o
obj-$(CONFIG_SND_SOC_FRAMER) += snd-soc-framer.o
obj-$(CONFIG_SND_SOC_FS_AMP_LIB)+= snd-soc-fs-amp-lib.o
@ -637,6 +642,7 @@ obj-$(CONFIG_SND_SOC_MT6359_ACCDET) += mt6359-accdet.o
obj-$(CONFIG_SND_SOC_MT6660) += snd-soc-mt6660.o
obj-$(CONFIG_SND_SOC_NAU8315) += snd-soc-nau8315.o
obj-$(CONFIG_SND_SOC_NAU8325) += snd-soc-nau8325.o
obj-$(CONFIG_SND_SOC_NAU8360) += snd-soc-nau8360.o
obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o
obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o
obj-$(CONFIG_SND_SOC_NAU8821) += snd-soc-nau8821.o
@ -742,6 +748,7 @@ obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o
obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o
obj-$(CONFIG_SND_SOC_SMA1303) += snd-soc-sma1303.o
obj-$(CONFIG_SND_SOC_SMA1307) += snd-soc-sma1307.o
obj-$(CONFIG_SND_SOC_SN624X_SDCA_SDW) += snd-soc-sn624x-sdca.o
obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
obj-$(CONFIG_SND_SOC_SRC4XXX) += snd-soc-src4xxx.o
obj-$(CONFIG_SND_SOC_SRC4XXX_I2C) += snd-soc-src4xxx-i2c.o
@ -819,6 +826,7 @@ ifdef CONFIG_SND_SOC_WCD939X_SDW
# avoid link failure by forcing sdw code built-in when needed
obj-$(CONFIG_SND_SOC_WCD939X) += snd-soc-wcd939x-sdw.o
endif
obj-$(CONFIG_SND_SOC_WCD9378_SDCA) += snd-soc-wcd9378.o
obj-$(CONFIG_SND_SOC_WM0010) += snd-soc-wm0010.o
obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o

View File

@ -299,7 +299,6 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0, 0),
SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0, 0),
SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0, 0),
SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0, 0),
/* Power */
SND_SOC_DAPM_SUPPLY("Audio Power",
@ -324,7 +323,6 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
SND_SOC_DAPM_AIF_OUT("AD_OUT1", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("AD_OUT2", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("AD_OUT3", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("AD_OUT4", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("AD_OUT57", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("AD_OUT68", NULL, 0, SND_SOC_NOPM, 0, 0),
@ -584,36 +582,6 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("AD5768 Enable", AB8500_ADPATHENA,
AB8500_ADPATHENA_ENAD5768, 0, NULL, 0),
/* Digital Microphone path */
SND_SOC_DAPM_INPUT("DMic 1"),
SND_SOC_DAPM_INPUT("DMic 2"),
SND_SOC_DAPM_INPUT("DMic 3"),
SND_SOC_DAPM_INPUT("DMic 4"),
SND_SOC_DAPM_INPUT("DMic 5"),
SND_SOC_DAPM_INPUT("DMic 6"),
SND_SOC_DAPM_MIXER("DMIC1",
AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC1, 0,
NULL, 0),
SND_SOC_DAPM_MIXER("DMIC2",
AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC2, 0,
NULL, 0),
SND_SOC_DAPM_MIXER("DMIC3",
AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC3, 0,
NULL, 0),
SND_SOC_DAPM_MIXER("DMIC4",
AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC4, 0,
NULL, 0),
SND_SOC_DAPM_MIXER("DMIC5",
AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC5, 0,
NULL, 0),
SND_SOC_DAPM_MIXER("DMIC6",
AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC6, 0,
NULL, 0),
SND_SOC_DAPM_MIXER("AD4 Channel Volume",
SND_SOC_NOPM, 0, 0,
NULL, 0),
/* Acoustical Noise Cancellation path */
SND_SOC_DAPM_MUX("ANC Source",
@ -648,6 +616,40 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
NULL, 0),
};
static const struct snd_soc_dapm_widget ab8500_dmic_dapm_widgets[] = {
SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0, 0),
SND_SOC_DAPM_AIF_OUT("AD_OUT4", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_INPUT("DMic 1"),
SND_SOC_DAPM_INPUT("DMic 2"),
SND_SOC_DAPM_INPUT("DMic 3"),
SND_SOC_DAPM_INPUT("DMic 4"),
SND_SOC_DAPM_INPUT("DMic 5"),
SND_SOC_DAPM_INPUT("DMic 6"),
SND_SOC_DAPM_MIXER("DMIC1",
AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC1, 0,
NULL, 0),
SND_SOC_DAPM_MIXER("DMIC2",
AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC2, 0,
NULL, 0),
SND_SOC_DAPM_MIXER("DMIC3",
AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC3, 0,
NULL, 0),
SND_SOC_DAPM_MIXER("DMIC4",
AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC4, 0,
NULL, 0),
SND_SOC_DAPM_MIXER("DMIC5",
AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC5, 0,
NULL, 0),
SND_SOC_DAPM_MIXER("DMIC6",
AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC6, 0,
NULL, 0),
SND_SOC_DAPM_MIXER("AD4 Channel Volume",
SND_SOC_NOPM, 0, 0,
NULL, 0),
};
/*
* DAPM-routes
*/
@ -853,35 +855,6 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
{"AD_OUT68", NULL, "Main Supply"},
{"AD_OUT68", NULL, "AD6 Channel Volume"},
/* Digital Microphone path */
{"DMic 1", NULL, "V-DMIC"},
{"DMic 2", NULL, "V-DMIC"},
{"DMic 3", NULL, "V-DMIC"},
{"DMic 4", NULL, "V-DMIC"},
{"DMic 5", NULL, "V-DMIC"},
{"DMic 6", NULL, "V-DMIC"},
{"DMIC1", NULL, "DMic 1"},
{"DMIC2", NULL, "DMic 2"},
{"DMIC3", NULL, "DMic 3"},
{"DMIC4", NULL, "DMic 4"},
{"DMIC5", NULL, "DMic 5"},
{"DMIC6", NULL, "DMic 6"},
{"AD1 Source Select", "DMic 1", "DMIC1"},
{"AD2 Source Select", "DMic 2", "DMIC2"},
{"AD3 Source Select", "DMic 3", "DMIC3"},
{"AD5 Source Select", "DMic 5", "DMIC5"},
{"AD6 Source Select", "DMic 6", "DMIC6"},
{"AD4 Channel Volume", NULL, "DMIC4"},
{"AD4 Channel Volume", NULL, "AD34 Enable"},
{"ab8500_0c", NULL, "AD_OUT4"},
{"AD_OUT4", NULL, "Main Supply"},
{"AD_OUT4", NULL, "AD4 Channel Volume"},
/* LineIn Bypass path */
{"LINL to HSL Volume", NULL, "LINL Enable"},
@ -911,7 +884,6 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
{"Sidetone Left Source", "Headset Left", "DA_IN1"},
{"Sidetone Right Source", "LineIn Right", "AD2 Channel Volume"},
{"Sidetone Right Source", "Mic 1", "AD3 Channel Volume"},
{"Sidetone Right Source", "DMic 4", "AD4 Channel Volume"},
{"Sidetone Right Source", "Headset Right", "DA_IN2"},
{"STFIR1 Control", NULL, "Sidetone Left Source"},
@ -924,6 +896,37 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
{"DA2 Enable", NULL, "STFIR2 Volume"},
};
static const struct snd_soc_dapm_route ab8500_dmic_dapm_routes[] = {
{"DMic 1", NULL, "V-DMIC"},
{"DMic 2", NULL, "V-DMIC"},
{"DMic 3", NULL, "V-DMIC"},
{"DMic 4", NULL, "V-DMIC"},
{"DMic 5", NULL, "V-DMIC"},
{"DMic 6", NULL, "V-DMIC"},
{"DMIC1", NULL, "DMic 1"},
{"DMIC2", NULL, "DMic 2"},
{"DMIC3", NULL, "DMic 3"},
{"DMIC4", NULL, "DMic 4"},
{"DMIC5", NULL, "DMic 5"},
{"DMIC6", NULL, "DMic 6"},
{"AD1 Source Select", "DMic 1", "DMIC1"},
{"AD2 Source Select", "DMic 2", "DMIC2"},
{"AD3 Source Select", "DMic 3", "DMIC3"},
{"AD5 Source Select", "DMic 5", "DMIC5"},
{"AD6 Source Select", "DMic 6", "DMIC6"},
{"AD4 Channel Volume", NULL, "DMIC4"},
{"AD4 Channel Volume", NULL, "AD34 Enable"},
{"ab8500_0c", NULL, "AD_OUT4"},
{"AD_OUT4", NULL, "Main Supply"},
{"AD_OUT4", NULL, "AD4 Channel Volume"},
{"Sidetone Right Source", "DMic 4", "AD4 Channel Volume"},
};
static const struct snd_soc_dapm_route ab8500_dapm_routes_mic1a_vamicx[] = {
{"MIC1A V-AMICx Enable", NULL, "V-AMIC1"},
{"MIC1A V-AMICx Enable", NULL, "V-AMIC2"},
@ -1950,9 +1953,22 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
return 0;
}
static const u64 ab8500_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_DSP_A |
SND_SOC_POSSIBLE_DAIFMT_DSP_B |
SND_SOC_POSSIBLE_DAIFMT_GATED |
SND_SOC_POSSIBLE_DAIFMT_CONT |
SND_SOC_POSSIBLE_DAIFMT_NB_NF |
SND_SOC_POSSIBLE_DAIFMT_NB_IF |
SND_SOC_POSSIBLE_DAIFMT_IB_NF |
SND_SOC_POSSIBLE_DAIFMT_IB_IF;
static const struct snd_soc_dai_ops ab8500_codec_ops = {
.set_fmt = ab8500_codec_set_dai_fmt,
.set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
.auto_selectable_formats = &ab8500_selectable_formats,
.num_auto_selectable_formats = 1,
};
static struct snd_soc_dai_driver ab8500_codec_dai[] = {
@ -2043,13 +2059,30 @@ static int ab8500_codec_probe(struct snd_soc_component *component)
{
struct device *dev = component->dev;
struct device_node *np = dev->of_node;
struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
struct ab8500_codec_platform_data codec_pdata;
struct snd_soc_dapm_context *dapm;
int status;
dev_dbg(dev, "%s: Enter.\n", __func__);
ab8500_codec_of_probe(dev, np, &codec_pdata);
if (is_ab8500(ab8500)) {
dapm = snd_soc_component_to_dapm(component);
status = snd_soc_dapm_new_controls(dapm,
ab8500_dmic_dapm_widgets,
ARRAY_SIZE(ab8500_dmic_dapm_widgets));
if (status)
return status;
status = snd_soc_dapm_add_routes(dapm,
ab8500_dmic_dapm_routes,
ARRAY_SIZE(ab8500_dmic_dapm_routes));
if (status)
return status;
}
status = ab8500_audio_init_audioblock(component);
if (status < 0) {
dev_err(dev, "%s: failed to init audio-block (%d)!\n",

View File

@ -880,12 +880,24 @@ static const struct snd_soc_component_driver adau1372_driver = {
.endianness = 1,
};
static const u64 adau1372_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
SND_SOC_POSSIBLE_DAIFMT_DSP_A |
SND_SOC_POSSIBLE_DAIFMT_DSP_B |
SND_SOC_POSSIBLE_DAIFMT_NB_NF |
SND_SOC_POSSIBLE_DAIFMT_NB_IF |
SND_SOC_POSSIBLE_DAIFMT_IB_NF |
SND_SOC_POSSIBLE_DAIFMT_IB_IF;
static const struct snd_soc_dai_ops adau1372_dai_ops = {
.set_fmt = adau1372_set_dai_fmt,
.set_tdm_slot = adau1372_set_tdm_slot,
.set_tristate = adau1372_set_tristate,
.hw_params = adau1372_hw_params,
.startup = adau1372_startup,
.auto_selectable_formats = &adau1372_selectable_formats,
.num_auto_selectable_formats = 1,
};
#define ADAU1372_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \

View File

@ -1196,10 +1196,22 @@ static int adau1373_set_dai_sysclk(struct snd_soc_dai *dai,
return 0;
}
static const u64 adau1373_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_RIGHT_J |
SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
SND_SOC_POSSIBLE_DAIFMT_DSP_B |
SND_SOC_POSSIBLE_DAIFMT_NB_NF |
SND_SOC_POSSIBLE_DAIFMT_NB_IF |
SND_SOC_POSSIBLE_DAIFMT_IB_NF |
SND_SOC_POSSIBLE_DAIFMT_IB_IF;
static const struct snd_soc_dai_ops adau1373_dai_ops = {
.hw_params = adau1373_hw_params,
.set_sysclk = adau1373_set_dai_sysclk,
.set_fmt = adau1373_set_dai_fmt,
.auto_selectable_formats = &adau1373_selectable_formats,
.num_auto_selectable_formats = 1,
};
#define ADAU1373_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \

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