ASoC: Updates for v7.1

There's one new core feature here but mostly this has been a fairly
quiet release, we've got a few new drivers and one core feature that's
likely to be relatively rarely used but the bulk of the work this time
around has been on quality.

 - Support for bus keepers, this will be used by the Apple device
   support.
 - Enhancements to the SDCA support, incuding retaskable jacks.
 - Unwinding of the pcm_new()/pcm_free() cleanups from Morimoto-san.
 - Test improvements for the Cirrus Logic drivers.
 - Large sets of fixes for the NXP, nVidia and Qualcomm drivers.
 - Support for AMD RPL DMICs, Cirrus Logic CS42L43 and CS47L47, nVidia
   machines with CPCAP and WM8962.
This commit is contained in:
Takashi Iwai
2026-04-13 18:09:48 +02:00
286 changed files with 6693 additions and 2625 deletions

View File

@@ -1,14 +0,0 @@
Analog Devices SSM2305 Speaker Amplifier
========================================
Required properties:
- compatible : "adi,ssm2305"
- shutdown-gpios : The gpio connected to the shutdown pin.
The gpio signal is ACTIVE_LOW.
Example:
ssm2305: analog-amplifier {
compatible = "adi,ssm2305";
shutdown-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
};

View File

@@ -0,0 +1,46 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/adi,ssm2305.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices SSM2305 Class-D Speaker Amplifier
maintainers:
- Lars-Peter Clausen <lars@metafoo.de>
description:
The SSM2305 is a filterless, high efficiency, mono 2.8 W Class-D
audio amplifier with a micropower shutdown mode controlled via a
dedicated active-low GPIO pin.
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
const: adi,ssm2305
shutdown-gpios:
maxItems: 1
description:
GPIO connected to the shutdown pin (SD) of the SSM2305.
The pin is active-low; asserting it puts the device into
micropower shutdown mode.
required:
- compatible
- shutdown-gpios
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
analog-amplifier {
compatible = "adi,ssm2305";
shutdown-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
};
...

View File

@@ -35,6 +35,10 @@ properties:
dvdd-supply: true
firmware-name:
maxItems: 1
description: Name of the *_acf.bin file used for amplifier initialization
awinic,audio-channel:
description:
It is used to distinguish multiple PA devices, so that different

View File

@@ -16,6 +16,8 @@ description: |
DAC for headphone output, two integrated Class D amplifiers for
loudspeakers, and two ADCs for wired headset microphone input or
stereo line input. PDM inputs are provided for digital microphones.
CS42L43B variant adds dedicated PDM interface, SoundWire Clock Gearing
support and more decimators to ISRCs.
allOf:
- $ref: dai-common.yaml#
@@ -24,6 +26,7 @@ properties:
compatible:
enum:
- cirrus,cs42l43
- cirrus,cs42l43b
reg:
maxItems: 1

View File

@@ -1,42 +0,0 @@
* Hisilicon 6210 i2s controller
Required properties:
- compatible: should be one of the following:
- "hisilicon,hi6210-i2s"
- reg: physical base address of the i2s controller unit and length of
memory mapped region.
- interrupts: should contain the i2s interrupt.
- clocks: a list of phandle + clock-specifier pairs, one for each entry
in clock-names.
- clock-names: should contain following:
- "dacodec"
- "i2s-base"
- dmas: DMA specifiers for tx dma. See the DMA client binding,
Documentation/devicetree/bindings/dma/dma.txt
- dma-names: should be "tx" and "rx"
- hisilicon,sysctrl-syscon: phandle to sysctrl syscon
- #sound-dai-cells: Should be set to 1 (for multi-dai)
- The dai cell indexes reference the following interfaces:
0: S2 interface
(Currently that is the only one available, but more may be
supported in the future)
Example for the hi6210 i2s controller:
i2s0: i2s@f7118000{
compatible = "hisilicon,hi6210-i2s";
reg = <0x0 0xf7118000 0x0 0x8000>; /* i2s unit */
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; /* 155 "DigACodec_intr"-32 */
clocks = <&sys_ctrl HI6220_DACODEC_PCLK>,
<&sys_ctrl HI6220_BBPPLL0_DIV>;
clock-names = "dacodec", "i2s-base";
dmas = <&dma0 15 &dma0 14>;
dma-names = "rx", "tx";
hisilicon,sysctrl-syscon = <&sys_ctrl>;
#sound-dai-cells = <1>;
};
Then when referencing the i2s controller:
sound-dai = <&i2s0 0>; /* index 0 => S2 interface */

View File

@@ -0,0 +1,80 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/hisilicon,hi6210-i2s.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: HiSilicon hi6210 I2S controller
maintainers:
- John Stultz <john.stultz@linaro.org>
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
const: hisilicon,hi6210-i2s
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 2
clock-names:
items:
- const: dacodec
- const: i2s-base
dmas:
maxItems: 2
dma-names:
items:
- const: tx
- const: rx
hisilicon,sysctrl-syscon:
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to sysctrl syscon
"#sound-dai-cells":
const: 1
description: |
The dai cell indexes reference the following interfaces:
0: S2 interface
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- dmas
- dma-names
- hisilicon,sysctrl-syscon
- "#sound-dai-cells"
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/hi6220-clock.h>
i2s@f7118000 {
compatible = "hisilicon,hi6210-i2s";
reg = <0xf7118000 0x8000>;
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&sys_ctrl HI6220_DACODEC_PCLK>,
<&sys_ctrl HI6220_BBPPLL0_DIV>;
clock-names = "dacodec", "i2s-base";
dmas = <&dma0 14>, <&dma0 15>;
dma-names = "tx", "rx";
hisilicon,sysctrl-syscon = <&sys_ctrl>;
#sound-dai-cells = <1>;
};

View File

@@ -24,6 +24,7 @@ patternProperties:
cpu/codec dais.
type: object
$ref: tdm-slot.yaml#
properties:
link-name:
@@ -38,13 +39,9 @@ patternProperties:
- i2s
- dsp_b
dai-tdm-slot-num:
description: see tdm-slot.txt.
$ref: /schemas/types.yaml#/definitions/uint32
dai-tdm-slot-num: true
dai-tdm-slot-width:
description: see tdm-slot.txt.
$ref: /schemas/types.yaml#/definitions/uint32
dai-tdm-slot-width: true
playback-only:
description: link is used only for playback

View File

@@ -28,8 +28,6 @@ properties:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of the WM8960 audio codec.
unevaluatedProperties: false
required:
- compatible
- mediatek,platform
@@ -38,6 +36,8 @@ required:
- pinctrl-names
- pinctrl-0
additionalProperties: false
examples:
- |
sound {

View File

@@ -36,14 +36,14 @@ properties:
required:
- sound-dai
unevaluatedProperties: false
required:
- compatible
- audio-routing
- platform
- codec
unevaluatedProperties: false
examples:
- |
sound {

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/mediatek,mt8173-rt5650-rt5514.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek MT8173 with RT5650 and RT5514 audio codecs
maintainers:
- Koro Chen <koro.chen@mediatek.com>
properties:
compatible:
const: mediatek,mt8173-rt5650-rt5514
mediatek,audio-codec:
$ref: /schemas/types.yaml#/definitions/phandle-array
description: Phandles of rt5650 and rt5514 codecs
items:
- description: phandle of rt5650 codec
- description: phandle of rt5514 codec
mediatek,platform:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of MT8173 ASoC platform.
required:
- compatible
- mediatek,audio-codec
- mediatek,platform
additionalProperties: false
examples:
- |
sound {
compatible = "mediatek,mt8173-rt5650-rt5514";
mediatek,audio-codec = <&rt5650>, <&rt5514>;
mediatek,platform = <&afe>;
};
...

View File

@@ -105,12 +105,12 @@ patternProperties:
required:
- link-name
unevaluatedProperties: false
required:
- compatible
- mediatek,platform
unevaluatedProperties: false
examples:
- |
sound {

View File

@@ -1,15 +0,0 @@
MT8173 with RT5650 RT5514 CODECS
Required properties:
- compatible : "mediatek,mt8173-rt5650-rt5514"
- mediatek,audio-codec: the phandles of rt5650 and rt5514 codecs
- mediatek,platform: the phandle of MT8173 ASoC platform
Example:
sound {
compatible = "mediatek,mt8173-rt5650-rt5514";
mediatek,audio-codec = <&rt5650 &rt5514>;
mediatek,platform = <&afe>;
};

View File

@@ -0,0 +1,90 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/nvidia,tegra-audio-cpcap.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NVIDIA Tegra audio complex with CPCAP CODEC
maintainers:
- Svyatoslav Ryhel <clamor95@gmail.com>
allOf:
- $ref: nvidia,tegra-audio-common.yaml#
properties:
compatible:
items:
- pattern: '^motorola,tegra-audio-cpcap(-[a-z0-9]+)+$'
- const: nvidia,tegra-audio-cpcap
nvidia,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 pins (documented in the binding document), and the jacks on the
board.
minItems: 2
items:
enum:
# Board Connectors
- Speakers
- Int Spk
- Earpiece
- Int Mic
- Headset Mic
- Internal Mic 1
- Internal Mic 2
- Headphone
- Headphones
- Headphone Jack
- Mic Jack
# CODEC Pins
- MICR
- HSMIC
- EMUMIC
- MICL
- EXTR
- EXTL
- EP
- SPKR
- SPKL
- LINER
- LINEL
- HSR
- HSL
- EMUR
- EMUL
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/tegra20-car.h>
#include <dt-bindings/soc/tegra-pmc.h>
sound {
compatible = "motorola,tegra-audio-cpcap-olympus",
"nvidia,tegra-audio-cpcap";
nvidia,model = "Motorola Atrix 4G (MB860) CPCAP";
nvidia,audio-routing =
"Headphones", "HSR",
"Headphones", "HSL",
"Int Spk", "SPKR",
"Int Spk", "SPKL",
"Earpiece", "EP",
"HSMIC", "Mic Jack",
"MICR", "Internal Mic 1",
"MICL", "Internal Mic 2";
nvidia,i2s-controller = <&tegra_i2s1>;
nvidia,audio-codec = <&cpcap_audio>;
clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
<&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
<&tegra_car TEGRA20_CLK_CDEV1>;
clock-names = "pll_a", "pll_a_out0", "mclk";
};

View File

@@ -35,10 +35,15 @@ properties:
items:
enum:
# Board Connectors
- Speakers
- Int Spk
- Headphone
- Headphones
- Headphone Jack
- Earpiece
- Headset Mic
- Mic Jack
- Int Mic
- Internal Mic 1
- Internal Mic 2

View File

@@ -0,0 +1,88 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/nvidia,tegra-audio-wm8962.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NVIDIA Tegra audio complex with WM8962 CODEC
maintainers:
- Svyatoslav Ryhel <clamor95@gmail.com>
allOf:
- $ref: nvidia,tegra-audio-common.yaml#
properties:
compatible:
items:
- pattern: '^[a-z0-9]+,tegra-audio-wm8962(-[a-z0-9]+)+$'
- const: nvidia,tegra-audio-wm8962
nvidia,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 pins (documented in the binding document), and the jacks on the
board.
minItems: 2
items:
enum:
# Board Connectors
- Speakers
- Int Spk
- Earpiece
- Int Mic
- Headset Mic
- Internal Mic 1
- Internal Mic 2
- Headphone
- Headphones
- Headphone Jack
- Mic Jack
# CODEC Pins
- IN1L
- IN1R
- IN2L
- IN2R
- IN3L
- IN3R
- IN4L
- IN4R
- DMICDAT
- HPOUTL
- HPOUTR
- SPKOUT
- SPKOUTL
- SPKOUTR
required:
- nvidia,i2s-controller
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/tegra30-car.h>
#include <dt-bindings/soc/tegra-pmc.h>
sound {
compatible = "microsoft,tegra-audio-wm8962-surface-rt",
"nvidia,tegra-audio-wm8962";
nvidia,model = "Microsoft Surface RT WM8962";
nvidia,audio-routing =
"Headphone Jack", "HPOUTR",
"Headphone Jack", "HPOUTL",
"Int Spk", "SPKOUTR",
"Int Spk", "SPKOUTL";
nvidia,i2s-controller = <&tegra_i2s1>;
nvidia,audio-codec = <&wm8962>;
clocks = <&tegra_car TEGRA30_CLK_PLL_A>,
<&tegra_car TEGRA30_CLK_PLL_A_OUT0>,
<&tegra_pmc TEGRA_PMC_CLK_OUT_1>;
clock-names = "pll_a", "pll_a_out0", "mclk";
};

View File

@@ -126,13 +126,16 @@ patternProperties:
reg:
contains:
# MI2S DAI ID range PRIMARY_MI2S_RX - QUATERNARY_MI2S_TX and
# QUINARY_MI2S_RX - QUINARY_MI2S_TX
# QUINARY_MI2S_RX - QUINARY_MI2S_TX and
# LPI_MI2S_RX_0 - SENARY_MI2S_TX
items:
oneOf:
- minimum: 16
maximum: 23
- minimum: 127
maximum: 128
- minimum: 137
maximum: 148
then:
required:
- qcom,sd-lines

View File

@@ -1,22 +0,0 @@
ROCKCHIP with MAX98357A/RT5514/DA7219 codecs on GRU boards
Required properties:
- compatible: "rockchip,rk3399-gru-sound"
- rockchip,cpu: The phandle of the Rockchip I2S controller that's
connected to the codecs
- rockchip,codec: The phandle of the audio codecs
Optional properties:
- dmic-wakeup-delay-ms : specify delay time (ms) for DMIC ready.
If this option is specified, which means it's required dmic need
delay for DMIC to ready so that rt5514 can avoid recording before
DMIC send valid data
Example:
sound {
compatible = "rockchip,rk3399-gru-sound";
rockchip,cpu = <&i2s0>;
rockchip,codec = <&max98357a &rt5514 &da7219>;
dmic-wakeup-delay-ms = <20>;
};

View File

@@ -0,0 +1,60 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/rockchip,rk3399-gru-sound.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Rockchip with MAX98357A/RT5514/DA7219 codecs on GRU boards
maintainers:
- Heiko Stuebner <heiko@sntech.de>
properties:
compatible:
const: rockchip,rk3399-gru-sound
rockchip,cpu:
$ref: /schemas/types.yaml#/definitions/phandle-array
description: |
List of phandles to the Rockchip CPU DAI controllers connected to codecs
minItems: 1
items:
- items:
- description: Phandle to the Rockchip I2S controllers
- items:
- description: |
Phandle to the Rockchip SPDIF controller. Required when a
DisplayPort audio codec is referenced in rockchip,codec
rockchip,codec:
$ref: /schemas/types.yaml#/definitions/phandle-array
description: |
The phandles of the audio codecs connected to the Rockchip CPU DAI
controllers
minItems: 1
maxItems: 6
items:
maxItems: 1
dmic-wakeup-delay-ms:
description: |
specify delay time (ms) for DMIC ready.
If this option is specified, a delay is required for DMIC to get ready
so that rt5514 can avoid recording before DMIC sends valid data
required:
- compatible
- rockchip,cpu
- rockchip,codec
additionalProperties: false
examples:
- |
sound {
compatible = "rockchip,rk3399-gru-sound";
rockchip,cpu = <&i2s0 &spdif>;
rockchip,codec = <&max98357a &rt5514 &da7219 &cdn_dp>;
dmic-wakeup-delay-ms = <20>;
};

View File

@@ -0,0 +1,59 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/rockchip,rockchip-audio-max98090.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Rockchip audio complex with MAX98090 codec
maintainers:
- Fabio Estevam <festevam@gmail.com>
properties:
compatible:
const: rockchip,rockchip-audio-max98090
rockchip,model:
$ref: /schemas/types.yaml#/definitions/string
description: The user-visible name of this sound complex.
rockchip,i2s-controller:
$ref: /schemas/types.yaml#/definitions/phandle
description: Phandle to the Rockchip I2S controller.
rockchip,audio-codec:
$ref: /schemas/types.yaml#/definitions/phandle
description: Phandle to the MAX98090 audio codec.
rockchip,headset-codec:
$ref: /schemas/types.yaml#/definitions/phandle
description: Phandle to the external chip for jack detection.
rockchip,hdmi-codec:
$ref: /schemas/types.yaml#/definitions/phandle
description: Phandle to the HDMI device for HDMI codec.
required:
- compatible
- rockchip,model
- rockchip,i2s-controller
allOf:
- if:
required:
- rockchip,audio-codec
then:
required:
- rockchip,headset-codec
unevaluatedProperties: false
examples:
- |
sound {
compatible = "rockchip,rockchip-audio-max98090";
rockchip,model = "ROCKCHIP-I2S";
rockchip,i2s-controller = <&i2s>;
rockchip,audio-codec = <&max98090>;
rockchip,headset-codec = <&headsetcodec>;
};

View File

@@ -1,42 +0,0 @@
ROCKCHIP with MAX98090 CODEC
Required properties:
- compatible: "rockchip,rockchip-audio-max98090"
- rockchip,model: The user-visible name of this sound complex
- rockchip,i2s-controller: The phandle of the Rockchip I2S controller that's
connected to the CODEC
Optional properties:
- rockchip,audio-codec: The phandle of the MAX98090 audio codec.
- rockchip,headset-codec: The phandle of Ext chip for jack detection. This is
required if there is rockchip,audio-codec.
- rockchip,hdmi-codec: The phandle of HDMI device for HDMI codec.
Example:
/* For max98090-only board. */
sound {
compatible = "rockchip,rockchip-audio-max98090";
rockchip,model = "ROCKCHIP-I2S";
rockchip,i2s-controller = <&i2s>;
rockchip,audio-codec = <&max98090>;
rockchip,headset-codec = <&headsetcodec>;
};
/* For HDMI-only board. */
sound {
compatible = "rockchip,rockchip-audio-max98090";
rockchip,model = "ROCKCHIP-I2S";
rockchip,i2s-controller = <&i2s>;
rockchip,hdmi-codec = <&hdmi>;
};
/* For max98090 plus HDMI board. */
sound {
compatible = "rockchip,rockchip-audio-max98090";
rockchip,model = "ROCKCHIP-I2S";
rockchip,i2s-controller = <&i2s>;
rockchip,audio-codec = <&max98090>;
rockchip,headset-codec = <&headsetcodec>;
rockchip,hdmi-codec = <&hdmi>;
};

View File

@@ -27,14 +27,6 @@ definitions:
description: dai-link uses bit clock inversion
$ref: /schemas/types.yaml#/definitions/flag
dai-tdm-slot-num:
description: see tdm-slot.txt.
$ref: /schemas/types.yaml#/definitions/uint32
dai-tdm-slot-width:
description: see tdm-slot.txt.
$ref: /schemas/types.yaml#/definitions/uint32
system-clock-frequency:
description: |
If a clock is specified and a multiplication factor is given with
@@ -115,6 +107,8 @@ definitions:
dai:
type: object
$ref: tdm-slot.yaml#
properties:
sound-dai:
maxItems: 1
@@ -133,10 +127,6 @@ definitions:
bitclock-master:
$ref: /schemas/types.yaml#/definitions/flag
dai-tdm-slot-num:
$ref: "#/definitions/dai-tdm-slot-num"
dai-tdm-slot-width:
$ref: "#/definitions/dai-tdm-slot-width"
clocks:
maxItems: 1
system-clock-frequency:

View File

@@ -1,29 +0,0 @@
TDM slot:
This specifies audio DAI's TDM slot.
TDM slot properties:
dai-tdm-slot-num : Number of slots in use.
dai-tdm-slot-width : Width in bits for each slot.
dai-tdm-slot-tx-mask : Transmit direction slot mask, optional
dai-tdm-slot-rx-mask : Receive direction slot mask, optional
For instance:
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <8>;
dai-tdm-slot-tx-mask = <0 1>;
dai-tdm-slot-rx-mask = <1 0>;
And for each specified driver, there could be one .of_xlate_tdm_slot_mask()
to specify an explicit mapping of the channels and the slots. If it's absent
the default snd_soc_of_xlate_tdm_slot_mask() will be used to generating the
tx and rx masks.
For snd_soc_of_xlate_tdm_slot_mask(), the tx and rx masks will use a 1 bit
for an active slot as default, and the default active bits are at the LSB of
the masks.
The explicit masks are given as array of integers, where the first
number presents bit-0 (LSB), second presents bit-1, etc. Any non zero
number is considered 1 and 0 is 0. snd_soc_of_xlate_tdm_slot_mask()
does not do anything, if either mask is set non zero value.

View File

@@ -0,0 +1,52 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/tdm-slot.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Time Division Multiplexing (TDM) Slot Parameters
maintainers:
- Liam Girdwood <lgirdwood@gmail.com>
select: false
properties:
dai-tdm-slot-num:
$ref: /schemas/types.yaml#/definitions/uint32
description: Number of slots in use
dai-tdm-slot-width:
$ref: /schemas/types.yaml#/definitions/uint32
description: Width, in bits, of each slot
dai-tdm-idle-mode:
$ref: /schemas/types.yaml#/definitions/string
enum:
- none
- off
- zero
- pulldown
- hiz
- pullup
- drivehigh
description: Drive mode for inactive/idle TDM slots. For hardware that
implements .set_tdm_idle(). Optional. "None" represents undefined
behaviour and is the same as not setting this property.
patternProperties:
'^dai-tdm-slot-[rt]x-mask$':
$ref: /schemas/types.yaml#/definitions/uint32-array
description: Slot mask for active TDM slots. Optional. Drivers may
specify .xlate_tdm_slot_mask() to generate a slot mask dynamically. If
neither this property nor a driver-specific function are specified, the
default snd_soc_xlate_tdm_slot_mask() function will be used to generate
a mask. The first element of the array is slot 0 (LSB). Any nonzero
value will be treated as 1.
'^dai-tdm-slot-[rt]x-idle-mask$':
$ref: /schemas/types.yaml#/definitions/uint32
description: Idle slot mask. Optional. A bit being set to 1 indicates
that the corresponding TDM slot is inactive/idle.
additionalProperties: true

View File

@@ -30,7 +30,7 @@ properties:
description: |
I2C address of the device can be between 0x41 to 0x48.
reset-gpio:
reset-gpios:
maxItems: 1
description: GPIO used to reset the device.
@@ -82,7 +82,7 @@ examples:
#sound-dai-cells = <0>;
interrupt-parent = <&gpio1>;
interrupts = <14>;
reset-gpio = <&gpio1 15 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
shutdown-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
ti,imon-slot-no = <0>;
ti,vmon-slot-no = <2>;

View File

@@ -239,7 +239,6 @@ static struct gpiod_lookup_table wm8994_gpiod_table = {
static struct arizona_pdata wm5102_reva_pdata = {
.gpio_base = CODEC_GPIO_BASE,
.irq_flags = IRQF_TRIGGER_HIGH,
.micd_pol_gpio = CODEC_GPIO_BASE + 4,
.micd_rate = 6,
.gpio_defaults = {
[2] = 0x10000, /* AIF3TXLRCLK */
@@ -265,6 +264,8 @@ static struct gpiod_lookup_table wm5102_reva_gpiod_table = {
.table = {
GPIO_LOOKUP("GPION", 7,
"wlf,ldoena", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("arizona", 4,
"wlf,micd-pol", GPIO_ACTIVE_HIGH),
{ },
},
};
@@ -272,7 +273,6 @@ static struct gpiod_lookup_table wm5102_reva_gpiod_table = {
static struct arizona_pdata wm5102_pdata = {
.gpio_base = CODEC_GPIO_BASE,
.irq_flags = IRQF_TRIGGER_HIGH,
.micd_pol_gpio = CODEC_GPIO_BASE + 2,
.gpio_defaults = {
[2] = 0x10000, /* AIF3TXLRCLK */
[3] = 0x4, /* OPCLK */
@@ -297,6 +297,8 @@ static struct gpiod_lookup_table wm5102_gpiod_table = {
.table = {
GPIO_LOOKUP("GPION", 7,
"wlf,ldo1ena", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("arizona", 2,
"wlf,micd-pol", GPIO_ACTIVE_HIGH),
{ },
},
};

View File

@@ -9,6 +9,7 @@
* Cirrus Logic International Semiconductor Ltd.
*/
#include <kunit/static_stub.h>
#include <kunit/visibility.h>
#include <linux/cleanup.h>
#include <linux/ctype.h>
@@ -18,6 +19,7 @@
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ratelimit.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
@@ -30,45 +32,47 @@
/*
* When the KUnit test is running the error-case tests will cause a lot
* of messages. Rate-limit to prevent overflowing the kernel log buffer
* during KUnit test runs.
* during KUnit test runs and allow the test to redirect this function.
* In normal (not KUnit) builds this collapses to only return true.
*/
#if IS_ENABLED(CONFIG_FW_CS_DSP_KUNIT_TEST)
bool cs_dsp_suppress_err_messages;
EXPORT_SYMBOL_IF_KUNIT(cs_dsp_suppress_err_messages);
VISIBLE_IF_KUNIT bool cs_dsp_can_emit_message(void)
{
KUNIT_STATIC_STUB_REDIRECT(cs_dsp_can_emit_message);
bool cs_dsp_suppress_warn_messages;
EXPORT_SYMBOL_IF_KUNIT(cs_dsp_suppress_warn_messages);
if (IS_ENABLED(CONFIG_FW_CS_DSP_KUNIT_TEST)) {
static DEFINE_RATELIMIT_STATE(_rs,
DEFAULT_RATELIMIT_INTERVAL,
DEFAULT_RATELIMIT_BURST);
return __ratelimit(&_rs);
}
bool cs_dsp_suppress_info_messages;
EXPORT_SYMBOL_IF_KUNIT(cs_dsp_suppress_info_messages);
return true;
}
EXPORT_SYMBOL_IF_KUNIT(cs_dsp_can_emit_message);
#define cs_dsp_err(_dsp, fmt, ...) \
do { \
if (!cs_dsp_suppress_err_messages) \
dev_err_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
#define cs_dsp_err(_dsp, fmt, ...) \
do { \
if (cs_dsp_can_emit_message()) \
dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
} while (false)
#define cs_dsp_warn(_dsp, fmt, ...) \
do { \
if (!cs_dsp_suppress_warn_messages) \
dev_warn_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
#define cs_dsp_warn(_dsp, fmt, ...) \
do { \
if (cs_dsp_can_emit_message()) \
dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
} while (false)
#define cs_dsp_info(_dsp, fmt, ...) \
do { \
if (!cs_dsp_suppress_info_messages) \
dev_info_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
#define cs_dsp_info(_dsp, fmt, ...) \
do { \
if (cs_dsp_can_emit_message()) \
dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
} while (false)
#define cs_dsp_dbg(_dsp, fmt, ...) \
do { \
if (cs_dsp_can_emit_message()) \
dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \
} while (false)
#define cs_dsp_dbg(_dsp, fmt, ...) \
dev_dbg_ratelimited(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
#else
#define cs_dsp_err(_dsp, fmt, ...) \
dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
#define cs_dsp_warn(_dsp, fmt, ...) \
dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
#define cs_dsp_info(_dsp, fmt, ...) \
dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
#define cs_dsp_dbg(_dsp, fmt, ...) \
dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
#endif
#define ADSP1_CONTROL_1 0x00
#define ADSP1_CONTROL_2 0x02
@@ -515,6 +519,7 @@ void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root)
debugfs_create_bool("booted", 0444, root, &dsp->booted);
debugfs_create_bool("running", 0444, root, &dsp->running);
debugfs_create_bool("hibernating", 0444, root, &dsp->hibernating);
debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id);
debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version);
@@ -703,7 +708,7 @@ int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int
lockdep_assert_held(&dsp->pwr_lock);
if (!dsp->running)
if (!dsp->running || dsp->hibernating)
return -EPERM;
ret = cs_dsp_coeff_base_reg(ctl, &reg, 0);
@@ -827,7 +832,7 @@ int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl,
}
ctl->set = 1;
if (ctl->enabled && ctl->dsp->running)
if (ctl->enabled && ctl->dsp->running && !ctl->dsp->hibernating)
ret = cs_dsp_coeff_write_ctrl_raw(ctl, off, buf, len);
if (ret < 0)
@@ -920,12 +925,12 @@ int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl,
return -EINVAL;
if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
if (ctl->enabled && ctl->dsp->running)
if (ctl->enabled && ctl->dsp->running && !ctl->dsp->hibernating)
return cs_dsp_coeff_read_ctrl_raw(ctl, off, buf, len);
else
return -EPERM;
} else {
if (!ctl->flags && ctl->enabled && ctl->dsp->running)
if (!ctl->flags && ctl->enabled && ctl->dsp->running && !ctl->dsp->hibernating)
ret = cs_dsp_coeff_read_ctrl_raw(ctl, 0, ctl->cache, ctl->len);
if (buf != ctl->cache)
@@ -1108,6 +1113,44 @@ err_ctl:
return ret;
}
/**
* cs_dsp_hibernate() - Disable or enable all controls for a DSP
* @dsp: pointer to DSP structure
* @hibernate: whether to set controls to cache only mode
*
* When @hibernate is true, the DSP is entering hibernation mode where the
* regmap is inaccessible, and all controls become cache only.
* When @hibernate is false, the DSP has exited hibernation mode. If the DSP
* is running, all controls are re-synced to the DSP.
*
*/
void cs_dsp_hibernate(struct cs_dsp *dsp, bool hibernate)
{
mutex_lock(&dsp->pwr_lock);
if (!dsp->running) {
cs_dsp_dbg(dsp, "Cannot hibernate, DSP not running\n");
goto out;
}
if (dsp->hibernating == hibernate)
goto out;
cs_dsp_dbg(dsp, "Set hibernating to %d\n", hibernate);
dsp->hibernating = hibernate;
if (!dsp->hibernating && dsp->running) {
int ret = cs_dsp_coeff_sync_controls(dsp);
if (ret)
cs_dsp_err(dsp, "Error syncing controls: %d\n", ret);
}
out:
mutex_unlock(&dsp->pwr_lock);
}
EXPORT_SYMBOL_NS_GPL(cs_dsp_hibernate, "FW_CS_DSP");
struct cs_dsp_coeff_parsed_alg {
int id;
const u8 *name;
@@ -2510,6 +2553,7 @@ int cs_dsp_adsp1_power_up(struct cs_dsp *dsp,
goto err_ena;
dsp->booted = true;
dsp->hibernating = false;
/* Start the core running */
regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
@@ -2788,6 +2832,7 @@ int cs_dsp_power_up(struct cs_dsp *dsp,
dsp->ops->disable_core(dsp);
dsp->booted = true;
dsp->hibernating = false;
mutex_unlock(&dsp->pwr_lock);

View File

@@ -10,9 +10,7 @@
#define FW_CS_DSP_H
#if IS_ENABLED(CONFIG_KUNIT)
extern bool cs_dsp_suppress_err_messages;
extern bool cs_dsp_suppress_warn_messages;
extern bool cs_dsp_suppress_info_messages;
bool cs_dsp_can_emit_message(void);
#endif
#endif /* ifndef FW_CS_DSP_H */

View File

@@ -7,6 +7,7 @@
#include <kunit/device.h>
#include <kunit/resource.h>
#include <kunit/static_stub.h>
#include <kunit/test.h>
#include <linux/build_bug.h>
#include <linux/firmware/cirrus/cs_dsp.h>
@@ -2155,6 +2156,15 @@ static void bin_patch_name_and_info(struct kunit *test)
KUNIT_EXPECT_EQ(test, reg_val, payload_data);
}
static bool cs_dsp_bin_test_can_emit_message_hook(void)
{
#if defined(DEBUG)
return true;
#else
return false;
#endif
}
static int cs_dsp_bin_test_common_init(struct kunit *test, struct cs_dsp *dsp,
int wmdr_ver)
{
@@ -2239,16 +2249,12 @@ static int cs_dsp_bin_test_common_init(struct kunit *test, struct cs_dsp *dsp,
* The large number of test cases will cause an unusually large amount
* of dev_info() messages from cs_dsp, so suppress these.
*/
cs_dsp_suppress_info_messages = true;
kunit_activate_static_stub(test, cs_dsp_can_emit_message,
cs_dsp_bin_test_can_emit_message_hook);
return 0;
}
static void cs_dsp_bin_test_exit(struct kunit *test)
{
cs_dsp_suppress_info_messages = false;
}
static int cs_dsp_bin_test_halo_init_common(struct kunit *test, int wmdr_ver)
{
struct cs_dsp *dsp;
@@ -2833,28 +2839,29 @@ static struct kunit_case cs_dsp_bin_test_cases_adsp2[] = {
static struct kunit_suite cs_dsp_bin_test_halo = {
.name = "cs_dsp_bin_halo",
.init = cs_dsp_bin_test_halo_init,
.exit = cs_dsp_bin_test_exit,
.test_cases = cs_dsp_bin_test_cases_halo,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_bin_test_halo_wmdr3 = {
.name = "cs_dsp_bin_halo_wmdr_v3",
.init = cs_dsp_bin_test_halo_wmdr3_init,
.test_cases = cs_dsp_bin_test_cases_halo_wmdr3,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_bin_test_adsp2_32bit = {
.name = "cs_dsp_bin_adsp2_32bit",
.init = cs_dsp_bin_test_adsp2_32bit_init,
.exit = cs_dsp_bin_test_exit,
.test_cases = cs_dsp_bin_test_cases_adsp2,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_bin_test_adsp2_16bit = {
.name = "cs_dsp_bin_adsp2_16bit",
.init = cs_dsp_bin_test_adsp2_16bit_init,
.exit = cs_dsp_bin_test_exit,
.test_cases = cs_dsp_bin_test_cases_adsp2,
.attr.speed = KUNIT_SPEED_SLOW,
};
kunit_test_suites(&cs_dsp_bin_test_halo,

View File

@@ -8,6 +8,7 @@
#include <kunit/device.h>
#include <kunit/resource.h>
#include <kunit/static_stub.h>
#include <kunit/test.h>
#include <linux/build_bug.h>
#include <linux/firmware/cirrus/cs_dsp.h>
@@ -380,11 +381,13 @@ static void bin_block_payload_len_garbage(struct kunit *test)
0);
}
static void cs_dsp_bin_err_test_exit(struct kunit *test)
static bool cs_dsp_bin_err_test_can_emit_message_hook(void)
{
cs_dsp_suppress_err_messages = false;
cs_dsp_suppress_warn_messages = false;
cs_dsp_suppress_info_messages = false;
#if defined(DEBUG)
return true;
#else
return false;
#endif
}
static int cs_dsp_bin_err_test_common_init(struct kunit *test, struct cs_dsp *dsp,
@@ -482,9 +485,8 @@ static int cs_dsp_bin_err_test_common_init(struct kunit *test, struct cs_dsp *ds
* Testing error conditions can produce a lot of log output
* from cs_dsp error messages, so suppress messages.
*/
cs_dsp_suppress_err_messages = true;
cs_dsp_suppress_warn_messages = true;
cs_dsp_suppress_info_messages = true;
kunit_activate_static_stub(test, cs_dsp_can_emit_message,
cs_dsp_bin_err_test_can_emit_message_hook);
return 0;
}
@@ -584,22 +586,22 @@ static struct kunit_case cs_dsp_bin_err_test_cases[] = {
static struct kunit_suite cs_dsp_bin_err_test_halo = {
.name = "cs_dsp_bin_err_halo",
.init = cs_dsp_bin_err_test_halo_init,
.exit = cs_dsp_bin_err_test_exit,
.test_cases = cs_dsp_bin_err_test_cases,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_bin_err_test_adsp2_32bit = {
.name = "cs_dsp_bin_err_adsp2_32bit",
.init = cs_dsp_bin_err_test_adsp2_32bit_init,
.exit = cs_dsp_bin_err_test_exit,
.test_cases = cs_dsp_bin_err_test_cases,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_bin_err_test_adsp2_16bit = {
.name = "cs_dsp_bin_err_adsp2_16bit",
.init = cs_dsp_bin_err_test_adsp2_16bit_init,
.exit = cs_dsp_bin_err_test_exit,
.test_cases = cs_dsp_bin_err_test_cases,
.attr.speed = KUNIT_SPEED_SLOW,
};
kunit_test_suites(&cs_dsp_bin_err_test_halo,

View File

@@ -3248,30 +3248,35 @@ static struct kunit_suite cs_dsp_ctl_cache_test_halo = {
.name = "cs_dsp_ctl_cache_wmfwV3_halo",
.init = cs_dsp_ctl_cache_test_halo_init,
.test_cases = cs_dsp_ctl_cache_test_cases_v3,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1 = {
.name = "cs_dsp_ctl_cache_wmfwV1_adsp2_32bit",
.init = cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1_init,
.test_cases = cs_dsp_ctl_cache_test_cases_v1,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2 = {
.name = "cs_dsp_ctl_cache_wmfwV2_adsp2_32bit",
.init = cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2_init,
.test_cases = cs_dsp_ctl_cache_test_cases_v2,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1 = {
.name = "cs_dsp_ctl_cache_wmfwV1_adsp2_16bit",
.init = cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1_init,
.test_cases = cs_dsp_ctl_cache_test_cases_v1,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2 = {
.name = "cs_dsp_ctl_cache_wmfwV2_adsp2_16bit",
.init = cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2_init,
.test_cases = cs_dsp_ctl_cache_test_cases_v2,
.attr.speed = KUNIT_SPEED_SLOW,
};
kunit_test_suites(&cs_dsp_ctl_cache_test_halo,

View File

@@ -1805,30 +1805,35 @@ static struct kunit_suite cs_dsp_ctl_parse_test_halo = {
.name = "cs_dsp_ctl_parse_wmfwV3_halo",
.init = cs_dsp_ctl_parse_test_halo_init,
.test_cases = cs_dsp_ctl_parse_test_cases_v2_v3,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_ctl_parse_test_adsp2_32bit_wmfw1 = {
.name = "cs_dsp_ctl_parse_wmfwV1_adsp2_32bit",
.init = cs_dsp_ctl_parse_test_adsp2_32bit_wmfw1_init,
.test_cases = cs_dsp_ctl_parse_test_cases_v1,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_ctl_parse_test_adsp2_32bit_wmfw2 = {
.name = "cs_dsp_ctl_parse_wmfwV2_adsp2_32bit",
.init = cs_dsp_ctl_parse_test_adsp2_32bit_wmfw2_init,
.test_cases = cs_dsp_ctl_parse_test_cases_v2_v3,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_ctl_parse_test_adsp2_16bit_wmfw1 = {
.name = "cs_dsp_ctl_parse_wmfwV1_adsp2_16bit",
.init = cs_dsp_ctl_parse_test_adsp2_16bit_wmfw1_init,
.test_cases = cs_dsp_ctl_parse_test_cases_v1,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_ctl_parse_test_adsp2_16bit_wmfw2 = {
.name = "cs_dsp_ctl_parse_wmfwV2_adsp2_16bit",
.init = cs_dsp_ctl_parse_test_adsp2_16bit_wmfw2_init,
.test_cases = cs_dsp_ctl_parse_test_cases_v2_v3,
.attr.speed = KUNIT_SPEED_SLOW,
};
kunit_test_suites(&cs_dsp_ctl_parse_test_halo,

View File

@@ -2636,30 +2636,35 @@ static struct kunit_suite cs_dsp_ctl_rw_test_halo = {
.name = "cs_dsp_ctl_rw_wmfwV3_halo",
.init = cs_dsp_ctl_rw_test_halo_init,
.test_cases = cs_dsp_ctl_rw_test_cases_halo,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_ctl_rw_test_adsp2_32bit_wmfw1 = {
.name = "cs_dsp_ctl_rw_wmfwV1_adsp2_32bit",
.init = cs_dsp_ctl_rw_test_adsp2_32bit_wmfw1_init,
.test_cases = cs_dsp_ctl_rw_test_cases_adsp,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_ctl_rw_test_adsp2_32bit_wmfw2 = {
.name = "cs_dsp_ctl_rw_wmfwV2_adsp2_32bit",
.init = cs_dsp_ctl_rw_test_adsp2_32bit_wmfw2_init,
.test_cases = cs_dsp_ctl_rw_test_cases_adsp,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_ctl_rw_test_adsp2_16bit_wmfw1 = {
.name = "cs_dsp_ctl_rw_wmfwV1_adsp2_16bit",
.init = cs_dsp_ctl_rw_test_adsp2_16bit_wmfw1_init,
.test_cases = cs_dsp_ctl_rw_test_cases_adsp,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_ctl_rw_test_adsp2_16bit_wmfw2 = {
.name = "cs_dsp_ctl_rw_wmfwV2_adsp2_16bit",
.init = cs_dsp_ctl_rw_test_adsp2_16bit_wmfw2_init,
.test_cases = cs_dsp_ctl_rw_test_cases_adsp,
.attr.speed = KUNIT_SPEED_SLOW,
};
kunit_test_suites(&cs_dsp_ctl_rw_test_halo,

View File

@@ -8,6 +8,7 @@
#include <kunit/device.h>
#include <kunit/resource.h>
#include <kunit/static_stub.h>
#include <kunit/test.h>
#include <linux/build_bug.h>
#include <linux/firmware/cirrus/cs_dsp.h>
@@ -1775,6 +1776,15 @@ static void wmfw_load_with_info(struct kunit *test)
KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);
}
static bool cs_dsp_wmfw_test_can_emit_message_hook(void)
{
#if defined(DEBUG)
return true;
#else
return false;
#endif
}
static int cs_dsp_wmfw_test_common_init(struct kunit *test, struct cs_dsp *dsp,
int wmfw_version)
{
@@ -1863,16 +1873,12 @@ static int cs_dsp_wmfw_test_common_init(struct kunit *test, struct cs_dsp *dsp,
* The large number of test cases will cause an unusually large amount
* of dev_info() messages from cs_dsp, so suppress these.
*/
cs_dsp_suppress_info_messages = true;
kunit_activate_static_stub(test, cs_dsp_can_emit_message,
cs_dsp_wmfw_test_can_emit_message_hook);
return 0;
}
static void cs_dsp_wmfw_test_exit(struct kunit *test)
{
cs_dsp_suppress_info_messages = false;
}
static int cs_dsp_wmfw_test_halo_init(struct kunit *test)
{
struct cs_dsp *dsp;
@@ -2180,50 +2186,50 @@ static struct kunit_case cs_dsp_wmfw_test_cases_adsp2[] = {
static struct kunit_suite cs_dsp_wmfw_test_halo = {
.name = "cs_dsp_wmfwV3_halo",
.init = cs_dsp_wmfw_test_halo_init,
.exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_halo,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw0 = {
.name = "cs_dsp_wmfwV0_adsp2_32bit",
.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw0_init,
.exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw1 = {
.name = "cs_dsp_wmfwV1_adsp2_32bit",
.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw1_init,
.exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw2 = {
.name = "cs_dsp_wmfwV2_adsp2_32bit",
.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw2_init,
.exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw0 = {
.name = "cs_dsp_wmfwV0_adsp2_16bit",
.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw0_init,
.exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw1 = {
.name = "cs_dsp_wmfwV1_adsp2_16bit",
.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw1_init,
.exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw2 = {
.name = "cs_dsp_wmfwV2_adsp2_16bit",
.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw2_init,
.exit = cs_dsp_wmfw_test_exit,
.test_cases = cs_dsp_wmfw_test_cases_adsp2,
.attr.speed = KUNIT_SPEED_SLOW,
};
kunit_test_suites(&cs_dsp_wmfw_test_halo,

View File

@@ -8,6 +8,7 @@
#include <kunit/device.h>
#include <kunit/resource.h>
#include <kunit/static_stub.h>
#include <kunit/test.h>
#include <linux/build_bug.h>
#include <linux/firmware/cirrus/cs_dsp.h>
@@ -989,11 +990,13 @@ static void wmfw_v2_coeff_description_exceeds_block(struct kunit *test)
-EOVERFLOW);
}
static void cs_dsp_wmfw_err_test_exit(struct kunit *test)
static bool cs_dsp_wmfw_err_test_can_emit_message_hook(void)
{
cs_dsp_suppress_err_messages = false;
cs_dsp_suppress_warn_messages = false;
cs_dsp_suppress_info_messages = false;
#if defined(DEBUG)
return true;
#else
return false;
#endif
}
static int cs_dsp_wmfw_err_test_common_init(struct kunit *test, struct cs_dsp *dsp,
@@ -1080,9 +1083,8 @@ static int cs_dsp_wmfw_err_test_common_init(struct kunit *test, struct cs_dsp *d
* Testing error conditions can produce a lot of log output
* from cs_dsp error messages, so suppress messages.
*/
cs_dsp_suppress_err_messages = true;
cs_dsp_suppress_warn_messages = true;
cs_dsp_suppress_info_messages = true;
kunit_activate_static_stub(test, cs_dsp_can_emit_message,
cs_dsp_wmfw_err_test_can_emit_message_hook);
return 0;
}
@@ -1304,50 +1306,50 @@ static struct kunit_case cs_dsp_wmfw_err_test_cases_v3[] = {
static struct kunit_suite cs_dsp_wmfw_err_test_halo = {
.name = "cs_dsp_wmfwV3_err_halo",
.init = cs_dsp_wmfw_err_test_halo_init,
.exit = cs_dsp_wmfw_err_test_exit,
.test_cases = cs_dsp_wmfw_err_test_cases_v3,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_wmfw_err_test_adsp2_32bit_wmfw0 = {
.name = "cs_dsp_wmfwV0_err_adsp2_32bit",
.init = cs_dsp_wmfw_err_test_adsp2_32bit_wmfw0_init,
.exit = cs_dsp_wmfw_err_test_exit,
.test_cases = cs_dsp_wmfw_err_test_cases_v0,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_wmfw_err_test_adsp2_32bit_wmfw1 = {
.name = "cs_dsp_wmfwV1_err_adsp2_32bit",
.init = cs_dsp_wmfw_err_test_adsp2_32bit_wmfw1_init,
.exit = cs_dsp_wmfw_err_test_exit,
.test_cases = cs_dsp_wmfw_err_test_cases_v1,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_wmfw_err_test_adsp2_32bit_wmfw2 = {
.name = "cs_dsp_wmfwV2_err_adsp2_32bit",
.init = cs_dsp_wmfw_err_test_adsp2_32bit_wmfw2_init,
.exit = cs_dsp_wmfw_err_test_exit,
.test_cases = cs_dsp_wmfw_err_test_cases_v2,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_wmfw_err_test_adsp2_16bit_wmfw0 = {
.name = "cs_dsp_wmfwV0_err_adsp2_16bit",
.init = cs_dsp_wmfw_err_test_adsp2_16bit_wmfw0_init,
.exit = cs_dsp_wmfw_err_test_exit,
.test_cases = cs_dsp_wmfw_err_test_cases_v0,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_wmfw_err_test_adsp2_16bit_wmfw1 = {
.name = "cs_dsp_wmfwV1_err_adsp2_16bit",
.init = cs_dsp_wmfw_err_test_adsp2_16bit_wmfw1_init,
.exit = cs_dsp_wmfw_err_test_exit,
.test_cases = cs_dsp_wmfw_err_test_cases_v1,
.attr.speed = KUNIT_SPEED_SLOW,
};
static struct kunit_suite cs_dsp_wmfw_err_test_adsp2_16bit_wmfw2 = {
.name = "cs_dsp_wmfwV2_err_adsp2_16bit",
.init = cs_dsp_wmfw_err_test_adsp2_16bit_wmfw2_init,
.exit = cs_dsp_wmfw_err_test_exit,
.test_cases = cs_dsp_wmfw_err_test_cases_v2,
.attr.speed = KUNIT_SPEED_SLOW,
};
kunit_test_suites(&cs_dsp_wmfw_err_test_halo,

View File

@@ -47,6 +47,7 @@ static int cs42l43_i2c_probe(struct i2c_client *i2c)
cs42l43->irq = i2c->irq;
/* A device on an I2C is always attached by definition. */
cs42l43->attached = true;
cs42l43->variant_id = (long)device_get_match_data(cs42l43->dev);
cs42l43->regmap = devm_regmap_init_i2c(i2c, &cs42l43_i2c_regmap);
if (IS_ERR(cs42l43->regmap))
@@ -58,7 +59,8 @@ static int cs42l43_i2c_probe(struct i2c_client *i2c)
#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id cs42l43_of_match[] = {
{ .compatible = "cirrus,cs42l43", },
{ .compatible = "cirrus,cs42l43", .data = (void *)CS42L43_DEVID_VAL },
{ .compatible = "cirrus,cs42l43b", .data = (void *)CS42L43B_DEVID_VAL },
{}
};
MODULE_DEVICE_TABLE(of, cs42l43_of_match);
@@ -66,7 +68,8 @@ MODULE_DEVICE_TABLE(of, cs42l43_of_match);
#if IS_ENABLED(CONFIG_ACPI)
static const struct acpi_device_id cs42l43_acpi_match[] = {
{ "CSC4243", 0 },
{ "CSC4243", CS42L43_DEVID_VAL },
{ "CSC2A3B", CS42L43B_DEVID_VAL },
{}
};
MODULE_DEVICE_TABLE(acpi, cs42l43_acpi_match);

View File

@@ -178,6 +178,7 @@ static int cs42l43_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *
cs42l43->dev = dev;
cs42l43->sdw = sdw;
cs42l43->variant_id = (long)id->driver_data;
cs42l43->regmap = devm_regmap_init_sdw(sdw, &cs42l43_sdw_regmap);
if (IS_ERR(cs42l43->regmap))
@@ -188,7 +189,8 @@ static int cs42l43_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *
}
static const struct sdw_device_id cs42l43_sdw_id[] = {
SDW_SLAVE_ENTRY(0x01FA, 0x4243, 0),
SDW_SLAVE_ENTRY(0x01FA, 0x4243, (void *) CS42L43_DEVID_VAL),
SDW_SLAVE_ENTRY(0x01FA, 0x2A3B, (void *) CS42L43B_DEVID_VAL),
{}
};
MODULE_DEVICE_TABLE(sdw, cs42l43_sdw_id);

View File

@@ -115,9 +115,14 @@ const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS] = {
{ CS42L43_DECIM_HPF_WNF_CTRL2, 0x00000001 },
{ CS42L43_DECIM_HPF_WNF_CTRL3, 0x00000001 },
{ CS42L43_DECIM_HPF_WNF_CTRL4, 0x00000001 },
{ CS42L43B_DECIM_HPF_WNF_CTRL5, 0x00000001 },
{ CS42L43B_DECIM_HPF_WNF_CTRL6, 0x00000001 },
{ CS42L43_DMIC_PDM_CTRL, 0x00000000 },
{ CS42L43_DECIM_VOL_CTRL_CH1_CH2, 0x20122012 },
{ CS42L43_DECIM_VOL_CTRL_CH3_CH4, 0x20122012 },
{ CS42L43B_DECIM_VOL_CTRL_CH1_CH2, 0x20122012 },
{ CS42L43B_DECIM_VOL_CTRL_CH3_CH4, 0x20122012 },
{ CS42L43B_DECIM_VOL_CTRL_CH5_CH6, 0x20122012 },
{ CS42L43_INTP_VOLUME_CTRL1, 0x00000180 },
{ CS42L43_INTP_VOLUME_CTRL2, 0x00000180 },
{ CS42L43_AMP1_2_VOL_RAMP, 0x00000022 },
@@ -155,8 +160,12 @@ const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS] = {
{ CS42L43_SWIRE_DP2_CH2_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP3_CH1_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP3_CH2_INPUT, 0x00000000 },
{ CS42L43B_SWIRE_DP3_CH3_INPUT, 0x00000000 },
{ CS42L43B_SWIRE_DP3_CH4_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP4_CH1_INPUT, 0x00000000 },
{ CS42L43_SWIRE_DP4_CH2_INPUT, 0x00000000 },
{ CS42L43B_SWIRE_DP4_CH3_INPUT, 0x00000000 },
{ CS42L43B_SWIRE_DP4_CH4_INPUT, 0x00000000 },
{ CS42L43_ASRC_INT1_INPUT1, 0x00000000 },
{ CS42L43_ASRC_INT2_INPUT1, 0x00000000 },
{ CS42L43_ASRC_INT3_INPUT1, 0x00000000 },
@@ -169,10 +178,14 @@ const struct reg_default cs42l43_reg_default[CS42L43_N_DEFAULTS] = {
{ CS42L43_ISRC1INT2_INPUT1, 0x00000000 },
{ CS42L43_ISRC1DEC1_INPUT1, 0x00000000 },
{ CS42L43_ISRC1DEC2_INPUT1, 0x00000000 },
{ CS42L43B_ISRC1DEC3_INPUT1, 0x00000000 },
{ CS42L43B_ISRC1DEC4_INPUT1, 0x00000000 },
{ CS42L43_ISRC2INT1_INPUT1, 0x00000000 },
{ CS42L43_ISRC2INT2_INPUT1, 0x00000000 },
{ CS42L43_ISRC2DEC1_INPUT1, 0x00000000 },
{ CS42L43_ISRC2DEC2_INPUT1, 0x00000000 },
{ CS42L43B_ISRC2DEC3_INPUT1, 0x00000000 },
{ CS42L43B_ISRC2DEC4_INPUT1, 0x00000000 },
{ CS42L43_EQ1MIX_INPUT1, 0x00800000 },
{ CS42L43_EQ1MIX_INPUT2, 0x00800000 },
{ CS42L43_EQ1MIX_INPUT3, 0x00800000 },
@@ -269,6 +282,8 @@ EXPORT_SYMBOL_NS_GPL(cs42l43_reg_default, "MFD_CS42L43");
bool cs42l43_readable_register(struct device *dev, unsigned int reg)
{
struct cs42l43 *cs42l43 = dev_get_drvdata(dev);
switch (reg) {
case CS42L43_DEVID:
case CS42L43_REVID:
@@ -292,7 +307,6 @@ bool cs42l43_readable_register(struct device *dev, unsigned int reg)
case CS42L43_ADC_B_CTRL1 ... CS42L43_ADC_B_CTRL2:
case CS42L43_DECIM_HPF_WNF_CTRL1 ... CS42L43_DECIM_HPF_WNF_CTRL4:
case CS42L43_DMIC_PDM_CTRL:
case CS42L43_DECIM_VOL_CTRL_CH1_CH2 ... CS42L43_DECIM_VOL_CTRL_CH3_CH4:
case CS42L43_INTP_VOLUME_CTRL1 ... CS42L43_INTP_VOLUME_CTRL2:
case CS42L43_AMP1_2_VOL_RAMP:
case CS42L43_ASP_CTRL:
@@ -387,8 +401,16 @@ bool cs42l43_readable_register(struct device *dev, unsigned int reg)
case CS42L43_BOOT_CONTROL:
case CS42L43_BLOCK_EN:
case CS42L43_SHUTTER_CONTROL:
case CS42L43_MCU_SW_REV ... CS42L43_MCU_RAM_MAX:
return true;
case CS42L43B_MCU_SW_REV ... CS42L43B_MCU_RAM_MAX:
return true; // registers present on all variants
case CS42L43_MCU_SW_REV ... CS42L43B_MCU_SW_REV - 1:
case CS42L43B_MCU_RAM_MAX + 1 ... CS42L43_MCU_RAM_MAX:
case CS42L43_DECIM_VOL_CTRL_CH1_CH2 ... CS42L43_DECIM_VOL_CTRL_CH3_CH4:
return cs42l43->variant_id == CS42L43_DEVID_VAL; // regs only in CS42L43 variant
case CS42L43B_DECIM_VOL_CTRL_CH1_CH2 ... CS42L43B_DECIM_HPF_WNF_CTRL6:
case CS42L43B_SWIRE_DP3_CH3_INPUT ... CS42L43B_SWIRE_DP4_CH4_INPUT:
case CS42L43B_ISRC1DEC3_INPUT1 ... CS42L43B_ISRC2DEC4_INPUT1:
return cs42l43->variant_id == CS42L43B_DEVID_VAL; // regs only in CS42L43B variant
default:
return false;
}
@@ -597,15 +619,27 @@ static int cs42l43_wait_for_attach(struct cs42l43 *cs42l43)
static int cs42l43_mcu_stage_2_3(struct cs42l43 *cs42l43, bool shadow)
{
unsigned int need_reg = CS42L43_NEED_CONFIGS;
unsigned int boot_reg;
unsigned int val;
int ret;
if (shadow)
need_reg = CS42L43_FW_SH_BOOT_CFG_NEED_CONFIGS;
switch (cs42l43->variant_id) {
case CS42L43_DEVID_VAL:
if (shadow)
need_reg = CS42L43_FW_SH_BOOT_CFG_NEED_CONFIGS;
boot_reg = CS42L43_BOOT_STATUS;
break;
case CS42L43B_DEVID_VAL:
need_reg = CS42L43B_NEED_CONFIGS;
boot_reg = CS42L43B_BOOT_STATUS;
break;
default:
return -EINVAL;
}
regmap_write(cs42l43->regmap, need_reg, 0);
ret = regmap_read_poll_timeout(cs42l43->regmap, CS42L43_BOOT_STATUS,
ret = regmap_read_poll_timeout(cs42l43->regmap, boot_reg,
val, (val == CS42L43_MCU_BOOT_STAGE3),
CS42L43_MCU_POLL_US, CS42L43_MCU_CMD_TIMEOUT_US);
if (ret) {
@@ -644,13 +678,25 @@ static int cs42l43_mcu_stage_3_2(struct cs42l43 *cs42l43)
*/
static int cs42l43_mcu_disable(struct cs42l43 *cs42l43)
{
unsigned int val;
unsigned int val, cfg_reg, ctrl_reg;
int ret;
regmap_write(cs42l43->regmap, CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_REG,
CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_DISABLE_VAL);
regmap_write(cs42l43->regmap, CS42L43_FW_MISSION_CTRL_MM_CTRL_SELECTION,
CS42L43_FW_MM_CTRL_MCU_SEL_MASK);
switch (cs42l43->variant_id) {
case CS42L43_DEVID_VAL:
cfg_reg = CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_REG;
ctrl_reg = CS42L43_FW_MISSION_CTRL_MM_CTRL_SELECTION;
break;
case CS42L43B_DEVID_VAL:
cfg_reg = CS42L43B_FW_MISSION_CTRL_MM_MCU_CFG_REG;
ctrl_reg = CS42L43B_FW_MISSION_CTRL_MM_CTRL_SELECTION;
break;
default:
return -EINVAL;
}
regmap_write(cs42l43->regmap, cfg_reg, CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_DISABLE_VAL);
regmap_write(cs42l43->regmap, ctrl_reg, CS42L43_FW_MM_CTRL_MCU_SEL_MASK);
regmap_write(cs42l43->regmap, CS42L43_MCU_SW_INTERRUPT, CS42L43_CONTROL_IND_MASK);
regmap_write(cs42l43->regmap, CS42L43_MCU_SW_INTERRUPT, 0);
@@ -740,18 +786,32 @@ static int cs42l43_mcu_update_step(struct cs42l43 *cs42l43)
{
unsigned int mcu_rev, bios_rev, boot_status, secure_cfg;
bool patched, shadow;
int boot_status_reg, mcu_sw_rev_reg;
int ret;
switch (cs42l43->variant_id) {
case CS42L43_DEVID_VAL:
boot_status_reg = CS42L43_BOOT_STATUS;
mcu_sw_rev_reg = CS42L43_MCU_SW_REV;
break;
case CS42L43B_DEVID_VAL:
boot_status_reg = CS42L43B_BOOT_STATUS;
mcu_sw_rev_reg = CS42L43B_MCU_SW_REV;
break;
default:
return -EINVAL;
}
/* Clear any stale software interrupt bits. */
regmap_read(cs42l43->regmap, CS42L43_SOFT_INT, &mcu_rev);
ret = regmap_read(cs42l43->regmap, CS42L43_BOOT_STATUS, &boot_status);
ret = regmap_read(cs42l43->regmap, boot_status_reg, &boot_status);
if (ret) {
dev_err(cs42l43->dev, "Failed to read boot status: %d\n", ret);
return ret;
}
ret = regmap_read(cs42l43->regmap, CS42L43_MCU_SW_REV, &mcu_rev);
ret = regmap_read(cs42l43->regmap, mcu_sw_rev_reg, &mcu_rev);
if (ret) {
dev_err(cs42l43->dev, "Failed to read firmware revision: %d\n", ret);
return ret;
@@ -918,6 +978,13 @@ static void cs42l43_boot_work(struct work_struct *work)
switch (devid) {
case CS42L43_DEVID_VAL:
case CS42L43B_DEVID_VAL:
if (devid != cs42l43->variant_id) {
dev_err(cs42l43->dev,
"Device ID (0x%06x) does not match variant ID (0x%06lx)\n",
devid, cs42l43->variant_id);
goto err;
}
break;
default:
dev_err(cs42l43->dev, "Unrecognised devid: 0x%06x\n", devid);

View File

@@ -9,7 +9,7 @@
#ifndef CS42L43_CORE_INT_H
#define CS42L43_CORE_INT_H
#define CS42L43_N_DEFAULTS 176
#define CS42L43_N_DEFAULTS 189
struct dev_pm_ops;
struct device;

View File

@@ -140,6 +140,18 @@
#define DISPLAY_PORT_RX_6 134
#define DISPLAY_PORT_RX_7 135
#define USB_RX 136
#define LPI_MI2S_RX_0 137
#define LPI_MI2S_TX_0 138
#define LPI_MI2S_RX_1 139
#define LPI_MI2S_TX_1 140
#define LPI_MI2S_RX_2 141
#define LPI_MI2S_TX_2 142
#define LPI_MI2S_RX_3 143
#define LPI_MI2S_TX_3 144
#define LPI_MI2S_RX_4 145
#define LPI_MI2S_TX_4 146
#define SENARY_MI2S_RX 147
#define SENARY_MI2S_TX 148
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2

View File

@@ -179,6 +179,7 @@ struct cs_dsp {
bool booted;
bool running;
bool hibernating;
struct list_head ctl_list;
@@ -354,4 +355,6 @@ int cs_dsp_chunk_write(struct cs_dsp_chunk *ch, int nbits, u32 val);
int cs_dsp_chunk_flush(struct cs_dsp_chunk *ch);
int cs_dsp_chunk_read(struct cs_dsp_chunk *ch, int nbits);
void cs_dsp_hibernate(struct cs_dsp *dsp, bool hibernating);
#endif

View File

@@ -117,11 +117,6 @@ struct arizona_pdata {
/** Check for line output with HPDET method */
bool hpdet_acc_id_line;
#ifdef CONFIG_GPIOLIB_LEGACY
/** GPIO used for mic isolation with HPDET */
int hpdet_id_gpio;
#endif
/** Channel to use for headphone detection */
unsigned int hpdet_channel;
@@ -131,11 +126,6 @@ struct arizona_pdata {
/** Extra debounce timeout used during initial mic detection (ms) */
unsigned int micd_detect_debounce;
#ifdef CONFIG_GPIOLIB_LEGACY
/** GPIO for mic detection polarity */
int micd_pol_gpio;
#endif
/** Mic detect ramp rate */
unsigned int micd_bias_start_time;

View File

@@ -1181,4 +1181,80 @@
/* CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_REG */
#define CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_DISABLE_VAL 0xF05AA50F
/* CS42L43B VARIANT REGISTERS */
#define CS42L43B_DEVID_VAL 0x0042A43B
#define CS42L43B_DECIM_VOL_CTRL_CH1_CH2 0x00008280
#define CS42L43B_DECIM_VOL_CTRL_CH3_CH4 0x00008284
#define CS42L43B_DECIM_VOL_CTRL_CH5_CH6 0x00008290
#define CS42L43B_DECIM_VOL_CTRL_UPDATE 0x0000829C
#define CS42L43B_DECIM_HPF_WNF_CTRL5 0x000082A0
#define CS42L43B_DECIM_HPF_WNF_CTRL6 0x000082A4
#define CS42L43B_SWIRE_DP3_CH3_INPUT 0x0000C320
#define CS42L43B_SWIRE_DP3_CH4_INPUT 0x0000C330
#define CS42L43B_SWIRE_DP4_CH3_INPUT 0x0000C340
#define CS42L43B_SWIRE_DP4_CH4_INPUT 0x0000C350
#define CS42L43B_ISRC1DEC3_INPUT1 0x0000C780
#define CS42L43B_ISRC1DEC4_INPUT1 0x0000C790
#define CS42L43B_ISRC2DEC3_INPUT1 0x0000C7A0
#define CS42L43B_ISRC2DEC4_INPUT1 0x0000C7B0
#define CS42L43B_FW_MISSION_CTRL_NEED_CONFIGS 0x00117E00
#define CS42L43B_FW_MISSION_CTRL_HAVE_CONFIGS 0x00117E04
#define CS42L43B_FW_MISSION_CTRL_PATCH_START_ADDR_REG 0x00117E08
#define CS42L43B_FW_MISSION_CTRL_MM_CTRL_SELECTION 0x00117E0C
#define CS42L43B_FW_MISSION_CTRL_MM_MCU_CFG_REG 0x00117E10
#define CS42L43B_MCU_SW_REV 0x00117314
#define CS42L43B_PATCH_START_ADDR 0x00117318
#define CS42L43B_CONFIG_SELECTION 0x0011731C
#define CS42L43B_NEED_CONFIGS 0x00117320
#define CS42L43B_BOOT_STATUS 0x00117330
#define CS42L43B_FW_MISSION_CTRL_NEED_CONFIGS 0x00117E00
#define CS42L43B_FW_MISSION_CTRL_HAVE_CONFIGS 0x00117E04
#define CS42L43B_FW_MISSION_CTRL_PATCH_START_ADDR_REG 0x00117E08
#define CS42L43B_FW_MISSION_CTRL_MM_CTRL_SELECTION 0x00117E0C
#define CS42L43B_FW_MISSION_CTRL_MM_MCU_CFG_REG 0x00117E10
#define CS42L43B_MCU_RAM_MAX 0x00117FFF
/* CS42L43B_DECIM_DECIM_VOL_CTRL_CH5_CH6 */
#define CS42L43B_DECIM6_MUTE_MASK 0x80000000
#define CS42L43B_DECIM6_MUTE_SHIFT 31
#define CS42L43B_DECIM6_VOL_MASK 0x3FC00000
#define CS42L43B_DECIM6_VOL_SHIFT 22
#define CS42L43B_DECIM6_PATH1_VOL_FALL_RATE_MASK 0x00380000
#define CS42L43B_DECIM6_PATH1_VOL_FALL_RATE_SHIFT 19
#define CS42L43B_DECIM6_PATH1_VOL_RISE_RATE_MASK 0x00070000
#define CS42L43B_DECIM6_PATH1_VOL_RISE_RATE_SHIFT 16
#define CS42L43B_DECIM5_MUTE_MASK 0x00008000
#define CS42L43B_DECIM5_MUTE_SHIFT 15
#define CS42L43B_DECIM5_VOL_MASK 0x00003FC0
#define CS42L43B_DECIM5_VOL_SHIFT 6
#define CS42L43B_DECIM5_PATH1_VOL_FALL_RATE_MASK 0x00000038
#define CS42L43B_DECIM5_PATH1_VOL_FALL_RATE_SHIFT 3
#define CS42L43B_DECIM5_PATH1_VOL_RISE_RATE_MASK 0x00000007
#define CS42L43B_DECIM5_PATH1_VOL_RISE_RATE_SHIFT 0
/* CS42L43B_DECIM_VOL_CTRL_UPDATE */
#define CS42L43B_DECIM6_PATH1_VOL_TRIG_MASK 0x00000800
#define CS42L43B_DECIM6_PATH1_VOL_TRIG_SHIFT 11
#define CS42L43B_DECIM5_PATH1_VOL_TRIG_MASK 0x00000100
#define CS42L43B_DECIM5_PATH1_VOL_TRIG_SHIFT 8
#define CS42L43B_DECIM4_VOL_UPDATE_MASK 0x00000020
#define CS42L43B_DECIM4_VOL_UPDATE_SHIFT 5
/* CS42L43_ISRC1_CTRL..CS42L43_ISRC2_CTRL */
#define CS42L43B_ISRC_DEC4_EN_MASK 0x00000008
#define CS42L43B_ISRC_DEC4_EN_SHIFT 3
#define CS42L43B_ISRC_DEC4_EN_WIDTH 1
#define CS42L43B_ISRC_DEC3_EN_MASK 0x00000004
#define CS42L43B_ISRC_DEC3_EN_SHIFT 2
#define CS42L43B_ISRC_DEC3_EN_WIDTH 1
#endif /* CS42L43_CORE_REGS_H */

View File

@@ -98,6 +98,7 @@ struct cs42l43 {
bool sdw_pll_active;
bool attached;
bool hw_lock;
long variant_id;
};
#endif /* CS42L43_CORE_EXT_H */

View File

@@ -32,9 +32,6 @@ struct snd_ctl_elem_value;
#define CS35L56_UPDATE_REGS 0x0002A0C
#define CS35L56_REFCLK_INPUT 0x0002C04
#define CS35L56_GLOBAL_SAMPLE_RATE 0x0002C0C
#define CS35L56_OTP_MEM_53 0x00300D4
#define CS35L56_OTP_MEM_54 0x00300D8
#define CS35L56_OTP_MEM_55 0x00300DC
#define CS35L56_ASP1_ENABLES1 0x0004800
#define CS35L56_ASP1_CONTROL1 0x0004804
#define CS35L56_ASP1_CONTROL2 0x0004808
@@ -86,6 +83,9 @@ struct snd_ctl_elem_value;
#define CS35L56_DIE_STS1 0x0017040
#define CS35L56_DIE_STS2 0x0017044
#define CS35L56_DSP_RESTRICT_STS1 0x00190F0
#define CS35L56_OTP_MEM_53 0x00300D4
#define CS35L56_OTP_MEM_54 0x00300D8
#define CS35L56_OTP_MEM_55 0x00300DC
#define CS35L56_DSP1_XMEM_PACKED_0 0x2000000
#define CS35L56_DSP1_XMEM_PACKED_6143 0x2005FFC
#define CS35L56_DSP1_XMEM_UNPACKED32_0 0x2400000
@@ -435,6 +435,7 @@ ssize_t cs35l56_cal_data_debugfs_read(struct cs35l56_base *cs35l56_base,
ssize_t cs35l56_cal_data_debugfs_write(struct cs35l56_base *cs35l56_base,
const char __user *from, size_t count,
loff_t *ppos);
int cs35l56_factory_calibrate(struct cs35l56_base *cs35l56_base);
void cs35l56_create_cal_debugfs(struct cs35l56_base *cs35l56_base,
const struct cs35l56_cal_debugfs_fops *fops);
void cs35l56_remove_cal_debugfs(struct cs35l56_base *cs35l56_base);

View File

@@ -13,6 +13,8 @@
struct device;
struct regmap;
struct sdca_function_data;
struct snd_ctl_elem_value;
struct snd_kcontrol;
struct snd_kcontrol_new;
struct snd_pcm_hw_params;
struct snd_pcm_substream;
@@ -23,6 +25,42 @@ struct snd_soc_dai_ops;
struct snd_soc_dapm_route;
struct snd_soc_dapm_widget;
/* convenient macro to handle the mono volume in 7.8 fixed format representation */
#define SDCA_SINGLE_Q78_TLV(xname, xreg, xmin, xmax, xstep, tlv_array) \
{ \
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
.name = (xname), \
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE, \
.tlv.p = (tlv_array), \
.info = snd_soc_info_volsw, \
.get = sdca_asoc_q78_get_volsw, \
.put = sdca_asoc_q78_put_volsw, \
.private_value = (unsigned long)&(struct soc_mixer_control) { \
.reg = (xreg), .rreg = (xreg), \
.min = (xmin), .max = (xmax), \
.shift = (xstep), .rshift = (xstep), \
.sign_bit = 15 \
} \
}
/* convenient macro for stereo volume in 7.8 fixed format with separate registers for L/R */
#define SDCA_DOUBLE_Q78_TLV(xname, xreg_l, xreg_r, xmin, xmax, xstep, tlv_array) \
{ \
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
.name = (xname), \
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE, \
.tlv.p = (tlv_array), \
.info = snd_soc_info_volsw, \
.get = sdca_asoc_q78_get_volsw, \
.put = sdca_asoc_q78_put_volsw, \
.private_value = (unsigned long)&(struct soc_mixer_control) { \
.reg = (xreg_l), .rreg = (xreg_r), \
.min = (xmin), .max = (xmax), \
.shift = (xstep), .rshift = (xstep), \
.sign_bit = 15 \
} \
}
int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *function,
int *num_widgets, int *num_routes, int *num_controls,
int *num_dais);
@@ -57,5 +95,8 @@ int sdca_asoc_hw_params(struct device *dev, struct regmap *regmap,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai);
int sdca_asoc_q78_put_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int sdca_asoc_q78_get_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
#endif // __SDCA_ASOC_H__

View File

@@ -54,6 +54,11 @@ struct prop_nums {
int platforms;
};
enum simple_util_sysclk_order {
SIMPLE_SYSCLK_ORDER_CODEC_FIRST = 0,
SIMPLE_SYSCLK_ORDER_CPU_FIRST,
};
struct simple_util_priv {
struct snd_soc_card snd_card;
struct simple_dai_props {
@@ -63,6 +68,7 @@ struct simple_util_priv {
struct snd_soc_codec_conf *codec_conf;
struct prop_nums num;
unsigned int mclk_fs;
enum simple_util_sysclk_order sysclk_order;
} *dai_props;
struct simple_util_jack hp_jack;
struct simple_util_jack mic_jack;

View File

@@ -86,10 +86,10 @@ struct snd_soc_component_driver {
unsigned int reg, unsigned int val);
/* pcm creation and destruction */
int (*pcm_construct)(struct snd_soc_component *component,
struct snd_soc_pcm_runtime *rtd);
void (*pcm_destruct)(struct snd_soc_component *component,
struct snd_pcm *pcm);
int (*pcm_new)(struct snd_soc_component *component,
struct snd_soc_pcm_runtime *rtd);
void (*pcm_free)(struct snd_soc_component *component,
struct snd_pcm *pcm);
/* component wide operations */
int (*set_sysclk)(struct snd_soc_component *component,
@@ -224,7 +224,6 @@ struct snd_soc_component {
int num_dai;
struct regmap *regmap;
int val_bytes;
struct mutex io_mutex;
@@ -327,7 +326,7 @@ int snd_soc_component_stream_event(struct snd_soc_component *component,
int snd_soc_component_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level);
void snd_soc_component_setup_regmap(struct snd_soc_component *component);
int snd_soc_component_regmap_val_bytes(struct snd_soc_component *component);
#ifdef CONFIG_REGMAP
void snd_soc_component_init_regmap(struct snd_soc_component *component,
struct regmap *regmap);

View File

@@ -52,6 +52,21 @@ struct snd_compr_stream;
#define SND_SOC_POSSIBLE_DAIFMT_AC97 (1 << SND_SOC_DAI_FORMAT_AC97)
#define SND_SOC_POSSIBLE_DAIFMT_PDM (1 << SND_SOC_DAI_FORMAT_PDM)
/*
* DAI TDM slot idle modes
*
* Describes a CODEC/CPU's behaviour when not actively receiving or
* transmitting on a given TDM slot. NONE is undefined behaviour.
* Add new modes to the end.
*/
#define SND_SOC_DAI_TDM_IDLE_NONE 0
#define SND_SOC_DAI_TDM_IDLE_OFF 1
#define SND_SOC_DAI_TDM_IDLE_ZERO 2
#define SND_SOC_DAI_TDM_IDLE_PULLDOWN 3
#define SND_SOC_DAI_TDM_IDLE_HIZ 4
#define SND_SOC_DAI_TDM_IDLE_PULLUP 5
#define SND_SOC_DAI_TDM_IDLE_DRIVE_HIGH 6
/*
* DAI Clock gating.
*
@@ -181,6 +196,10 @@ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width);
int snd_soc_dai_set_tdm_idle(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask,
int tx_mode, int rx_mode);
int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
unsigned int tx_num, const unsigned int *tx_slot,
unsigned int rx_num, const unsigned int *rx_slot);
@@ -297,6 +316,9 @@ struct snd_soc_dai_ops {
int (*set_tdm_slot)(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask,
int slots, int slot_width);
int (*set_tdm_idle)(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask,
int tx_mode, int rx_mode);
int (*set_channel_map)(struct snd_soc_dai *dai,
unsigned int tx_num, const unsigned int *tx_slot,
unsigned int rx_num, const unsigned int *rx_slot);

View File

@@ -424,6 +424,7 @@ enum snd_soc_dapm_type {
snd_soc_dapm_input = 0, /* input pin */
snd_soc_dapm_output, /* output pin */
snd_soc_dapm_mux, /* selects 1 analog signal from many inputs */
snd_soc_dapm_mux_named_ctl, /* mux with named controls */
snd_soc_dapm_demux, /* connects the input to one of multiple outputs */
snd_soc_dapm_mixer, /* mixes several analog signals together */
snd_soc_dapm_mixer_named_ctl, /* mixer with named controls */

View File

@@ -311,6 +311,12 @@ struct platform_device;
.info = snd_soc_info_bool_ext, \
.get = xhandler_get, .put = xhandler_put, \
.private_value = xdata }
#define SOC_SINGLE_BOOL_EXT_ACC(xname, xdata, xhandler_get, xhandler_put, xaccess) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.access = xaccess, \
.info = snd_soc_info_bool_ext, \
.get = xhandler_get, .put = xhandler_put, \
.private_value = xdata }
#define SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_enum_double, \
@@ -422,11 +428,6 @@ struct snd_soc_jack_pin;
#include <sound/soc-dpcm.h>
#include <sound/soc-topology.h>
enum snd_soc_pcm_subclass {
SND_SOC_PCM_CLASS_PCM = 0,
SND_SOC_PCM_CLASS_BE = 1,
};
int snd_soc_register_card(struct snd_soc_card *card);
void snd_soc_unregister_card(struct snd_soc_card *card);
int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card);
@@ -465,6 +466,7 @@ struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev,
const char *driver_name);
struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
const char *driver_name);
struct snd_soc_component *snd_soc_lookup_component_by_name(const char *component_name);
int soc_new_pcm(struct snd_soc_pcm_runtime *rtd);
#ifdef CONFIG_SND_SOC_COMPRESS
@@ -999,7 +1001,6 @@ struct snd_soc_card {
/* Mutex for PCM operations */
struct mutex pcm_mutex;
enum snd_soc_pcm_subclass pcm_subclass;
int (*probe)(struct snd_soc_card *card);
int (*late_probe)(struct snd_soc_card *card);
@@ -1026,8 +1027,6 @@ struct snd_soc_card {
void (*remove_dai_link)(struct snd_soc_card *,
struct snd_soc_dai_link *link);
long pmdown_time;
/* CPU <--> Codec DAI links */
struct snd_soc_dai_link *dai_link; /* predefined links only */
int num_links; /* predefined links only */
@@ -1072,9 +1071,6 @@ struct snd_soc_card {
struct list_head dapm_list;
struct list_head dapm_dirty;
/* attached dynamic objects */
struct list_head dobj_list;
/* Generic DAPM context for the card */
struct snd_soc_dapm_context *dapm;
struct snd_soc_dapm_stats dapm_stats;
@@ -1239,7 +1235,6 @@ struct soc_mixer_control {
unsigned int sign_bit;
unsigned int invert:1;
unsigned int autodisable:1;
unsigned int sdca_q78:1;
#ifdef CONFIG_SND_SOC_TOPOLOGY
struct snd_soc_dobj dobj;
#endif
@@ -1340,15 +1335,6 @@ void snd_soc_of_parse_node_prefix(struct device_node *np,
struct snd_soc_codec_conf *codec_conf,
struct device_node *of_node,
const char *propname);
static inline
void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
struct snd_soc_codec_conf *codec_conf,
struct device_node *of_node,
const char *propname)
{
snd_soc_of_parse_node_prefix(card->dev->of_node,
codec_conf, of_node, propname);
}
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
const char *propname);
@@ -1412,6 +1398,9 @@ struct snd_soc_dai *snd_soc_find_dai(
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
@@ -1517,7 +1506,7 @@ static inline void _snd_soc_dapm_mutex_assert_held_d(struct snd_soc_dapm_context
*/
static inline void _snd_soc_dpcm_mutex_lock_c(struct snd_soc_card *card)
{
mutex_lock_nested(&card->pcm_mutex, card->pcm_subclass);
mutex_lock(&card->pcm_mutex);
}
static inline void _snd_soc_dpcm_mutex_unlock_c(struct snd_soc_card *card)

View File

@@ -71,6 +71,7 @@ struct asoc_sdw_aux_info {
};
struct asoc_sdw_codec_info {
const int vendor_id;
const int part_id;
const int version_id;
const char *name_prefix;
@@ -82,6 +83,8 @@ struct asoc_sdw_codec_info {
const int dai_num;
struct asoc_sdw_aux_info auxs[SOC_SDW_MAX_AUX_NUM];
const int aux_num;
/* Force AMP-style name_prefix handling (append AMP index) even if MIC/Jack DAIs exist */
const bool is_amp;
int (*codec_card_late_probe)(struct snd_soc_card *card);
@@ -259,6 +262,8 @@ int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_so
int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_cs42l45_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_cs42l45_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_cs47l47_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_cs47l47_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
/* TI */

View File

@@ -1,19 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* UDA1380 ALSA SoC Codec driver
*
* Copyright 2009 Philipp Zabel
*/
#ifndef __UDA1380_H
#define __UDA1380_H
struct uda1380_platform_data {
int gpio_power;
int gpio_reset;
int dac_clk;
#define UDA1380_DAC_CLK_SYSCLK 0
#define UDA1380_DAC_CLK_WSPLL 1
};
#endif /* __UDA1380_H */

View File

@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
config SND_HDA_CIRRUS_SCODEC
tristate

View File

@@ -122,16 +122,6 @@ config SND_AMD_ACP_CONFIG
source "sound/soc/amd/acp/Kconfig"
config SND_SOC_AMD_RPL_ACP6x
tristate "AMD Audio Coprocessor-v6.2 RPL support"
depends on X86 && PCI
help
This option enables Audio Coprocessor i.e. ACP v6.2 support on
AMD RPL platform. By enabling this flag build will be
triggered for ACP PCI driver.
Say m if you have such a device.
If unsure select "N".
config SND_SOC_AMD_ACP63_TOPLEVEL
tristate "support for AMD platforms with ACP version >= 6.3"
default SND_AMD_ACP_CONFIG

View File

@@ -17,5 +17,4 @@ obj-$(CONFIG_SND_SOC_AMD_ACP5x) += vangogh/
obj-$(CONFIG_SND_SOC_AMD_ACP6x) += yc/
obj-$(CONFIG_SND_AMD_ACP_CONFIG) += acp/
obj-$(CONFIG_SND_AMD_ACP_CONFIG) += snd-acp-config.o
obj-$(CONFIG_SND_SOC_AMD_RPL_ACP6x) += rpl/
obj-$(CONFIG_SND_SOC_AMD_PS) += ps/

View File

@@ -11,7 +11,6 @@
#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/driver.h>
@@ -48,8 +47,6 @@ static struct clk *da7219_dai_bclk;
static struct clk *rt5682_dai_wclk;
static struct clk *rt5682_dai_bclk;
void *acp_soc_is_rltk_max(struct device *dev);
static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
{
int ret;
@@ -704,7 +701,7 @@ static struct snd_soc_card cz_rt5682_card = {
.num_controls = ARRAY_SIZE(cz_mc_controls),
};
void *acp_soc_is_rltk_max(struct device *dev)
static void *acp_soc_is_rltk_max(struct device *dev)
{
const struct acpi_device_id *match;

View File

@@ -11,7 +11,6 @@
#include <sound/pcm_params.h>
#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <linux/gpio.h>
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/gpio/consumer.h>

View File

@@ -1252,7 +1252,7 @@ static const struct snd_soc_component_driver acp_asoc_platform = {
.pointer = acp_dma_pointer,
.delay = acp_dma_delay,
.prepare = acp_dma_prepare,
.pcm_construct = acp_dma_new,
.pcm_new = acp_dma_new,
};
static int acp_audio_probe(struct platform_device *pdev)

View File

@@ -1,29 +1,10 @@
// SPDX-License-Identifier: MIT
/*
* Machine driver for AMD ACP Audio engine using Realtek RT5645 codec
*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* This file is modified from rt288 machine driver
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*
*/
#include <sound/core.h>
@@ -32,7 +13,6 @@
#include <sound/pcm_params.h>
#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/acpi.h>

View File

@@ -321,7 +321,7 @@ static const struct snd_soc_component_driver acp_pcm_component = {
.close = acp_dma_close,
.hw_params = acp_dma_hw_params,
.pointer = acp_dma_pointer,
.pcm_construct = acp_dma_new,
.pcm_new = acp_dma_new,
.legacy_dai_naming = 1,
};

View File

@@ -394,10 +394,8 @@ static int create_dmic_dailinks(struct snd_soc_card *card,
static int soc_card_dai_links_create(struct snd_soc_card *card)
{
struct device *dev = card->dev;
struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
int sdw_be_num = 0, dmic_num = 0;
struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
struct snd_soc_aux_dev *soc_aux;
struct snd_soc_codec_conf *codec_conf;
struct snd_soc_dai_link *dai_links;
@@ -440,7 +438,7 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
sdw_be_num = ret;
/* enable dmic */
if (soc_sdw_quirk & ASOC_SDW_ACP_DMIC || mach_params->dmic_num)
if (soc_sdw_quirk & ASOC_SDW_ACP_DMIC)
dmic_num = 1;
dev_dbg(dev, "sdw %d, dmic %d", sdw_be_num, dmic_num);
@@ -551,11 +549,11 @@ static int mc_probe(struct platform_device *pdev)
" cfg-amp:%d", amp_num);
if (!card->components)
return -ENOMEM;
if (mach->mach_params.dmic_num) {
if (soc_sdw_quirk & ASOC_SDW_ACP_DMIC) {
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
"%s mic:dmic cfg-mics:%d",
"%s mic:acp-dmic cfg-mics:%d",
card->components,
mach->mach_params.dmic_num);
1);
if (!card->components)
return -ENOMEM;
}

View File

@@ -11,7 +11,6 @@
#include <sound/jack.h>
#include <sound/soc-acpi.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/i2c.h>

View File

@@ -11,7 +11,6 @@
#include <sound/soc-dapm.h>
#include <sound/jack.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/i2c.h>

View File

@@ -1,24 +1,8 @@
/* SPDX-License-Identifier: MIT */
/*
* ACP_2_2 Register documentation
*
* Copyright (C) 2014 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ACP_2_2_D_H

View File

@@ -1,24 +1,8 @@
/* SPDX-License-Identifier: MIT */
/*
* ACP_2_2 Register documentation
*
* Copyright (C) 2014 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ACP_2_2_ENUM_H

View File

@@ -1,24 +1,8 @@
/* SPDX-License-Identifier: MIT */
/*
* ACP_2_2 Register documentation
*
* Copyright (C) 2014 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ACP_2_2_SH_MASK_H

View File

@@ -351,7 +351,8 @@ static const struct snd_soc_component_driver acp63_pdm_component = {
.close = acp63_pdm_dma_close,
.hw_params = acp63_pdm_dma_hw_params,
.pointer = acp63_pdm_dma_pointer,
.pcm_construct = acp63_pdm_dma_new,
.pcm_new = acp63_pdm_dma_new,
.use_dai_pcm_id = true,
};
static int acp63_pdm_audio_probe(struct platform_device *pdev)

View File

@@ -634,7 +634,7 @@ static const struct snd_soc_component_driver acp63_sdw_component = {
.hw_params = acp63_sdw_dma_hw_params,
.trigger = acp63_sdw_dma_trigger,
.pointer = acp63_sdw_dma_pointer,
.pcm_construct = acp63_sdw_dma_new,
.pcm_new = acp63_sdw_dma_new,
.use_dai_pcm_id = true,
};

View File

@@ -363,7 +363,7 @@ static const struct snd_soc_component_driver acp3x_i2s_component = {
.close = acp3x_dma_close,
.hw_params = acp3x_dma_hw_params,
.pointer = acp3x_dma_pointer,
.pcm_construct = acp3x_dma_new,
.pcm_new = acp3x_dma_new,
};
static int acp3x_audio_probe(struct platform_device *pdev)

View File

@@ -376,7 +376,7 @@ static const struct snd_soc_component_driver acp_pdm_component = {
.close = acp_pdm_dma_close,
.hw_params = acp_pdm_dma_hw_params,
.pointer = acp_pdm_dma_pointer,
.pcm_construct = acp_pdm_dma_new,
.pcm_new = acp_pdm_dma_new,
.legacy_dai_naming = 1,
};

View File

@@ -1,5 +0,0 @@
# SPDX-License-Identifier: GPL-2.0+
# RPL platform Support
snd-rpl-pci-acp6x-y := rpl-pci-acp6x.o
obj-$(CONFIG_SND_SOC_AMD_RPL_ACP6x) += snd-rpl-pci-acp6x.o

View File

@@ -1,227 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* AMD RPL ACP PCI Driver
*
* Copyright 2022 Advanced Micro Devices, Inc.
*/
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include "rpl_acp6x.h"
struct rpl_dev_data {
void __iomem *acp6x_base;
};
static int rpl_power_on(void __iomem *acp_base)
{
u32 val;
int timeout;
val = rpl_acp_readl(acp_base + ACP_PGFSM_STATUS);
if (!val)
return val;
if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS)
rpl_acp_writel(ACP_PGFSM_CNTL_POWER_ON_MASK, acp_base + ACP_PGFSM_CONTROL);
timeout = 0;
while (++timeout < 500) {
val = rpl_acp_readl(acp_base + ACP_PGFSM_STATUS);
if (!val)
return 0;
udelay(1);
}
return -ETIMEDOUT;
}
static int rpl_reset(void __iomem *acp_base)
{
u32 val;
int timeout;
rpl_acp_writel(1, acp_base + ACP_SOFT_RESET);
timeout = 0;
while (++timeout < 500) {
val = rpl_acp_readl(acp_base + ACP_SOFT_RESET);
if (val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK)
break;
cpu_relax();
}
rpl_acp_writel(0, acp_base + ACP_SOFT_RESET);
timeout = 0;
while (++timeout < 500) {
val = rpl_acp_readl(acp_base + ACP_SOFT_RESET);
if (!val)
return 0;
cpu_relax();
}
return -ETIMEDOUT;
}
static int rpl_init(void __iomem *acp_base)
{
int ret;
/* power on */
ret = rpl_power_on(acp_base);
if (ret) {
pr_err("ACP power on failed\n");
return ret;
}
rpl_acp_writel(0x01, acp_base + ACP_CONTROL);
/* Reset */
ret = rpl_reset(acp_base);
if (ret) {
pr_err("ACP reset failed\n");
return ret;
}
rpl_acp_writel(0x03, acp_base + ACP_CLKMUX_SEL);
return 0;
}
static int rpl_deinit(void __iomem *acp_base)
{
int ret;
/* Reset */
ret = rpl_reset(acp_base);
if (ret) {
pr_err("ACP reset failed\n");
return ret;
}
rpl_acp_writel(0x00, acp_base + ACP_CLKMUX_SEL);
rpl_acp_writel(0x00, acp_base + ACP_CONTROL);
return 0;
}
static int snd_rpl_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
struct rpl_dev_data *adata;
u32 addr;
int ret;
/* RPL device check */
switch (pci->revision) {
case 0x62:
break;
default:
dev_dbg(&pci->dev, "acp6x pci device not found\n");
return -ENODEV;
}
if (pci_enable_device(pci)) {
dev_err(&pci->dev, "pci_enable_device failed\n");
return -ENODEV;
}
ret = pci_request_regions(pci, "AMD ACP6x audio");
if (ret < 0) {
dev_err(&pci->dev, "pci_request_regions failed\n");
goto disable_pci;
}
adata = devm_kzalloc(&pci->dev, sizeof(struct rpl_dev_data),
GFP_KERNEL);
if (!adata) {
ret = -ENOMEM;
goto release_regions;
}
addr = pci_resource_start(pci, 0);
adata->acp6x_base = devm_ioremap(&pci->dev, addr,
pci_resource_len(pci, 0));
if (!adata->acp6x_base) {
ret = -ENOMEM;
goto release_regions;
}
pci_set_master(pci);
pci_set_drvdata(pci, adata);
ret = rpl_init(adata->acp6x_base);
if (ret)
goto release_regions;
pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(&pci->dev);
pm_runtime_put_noidle(&pci->dev);
pm_runtime_allow(&pci->dev);
return 0;
release_regions:
pci_release_regions(pci);
disable_pci:
pci_disable_device(pci);
return ret;
}
static int snd_rpl_suspend(struct device *dev)
{
struct rpl_dev_data *adata;
int ret;
adata = dev_get_drvdata(dev);
ret = rpl_deinit(adata->acp6x_base);
if (ret)
dev_err(dev, "ACP de-init failed\n");
return ret;
}
static int snd_rpl_resume(struct device *dev)
{
struct rpl_dev_data *adata;
int ret;
adata = dev_get_drvdata(dev);
ret = rpl_init(adata->acp6x_base);
if (ret)
dev_err(dev, "ACP init failed\n");
return ret;
}
static const struct dev_pm_ops rpl_pm = {
RUNTIME_PM_OPS(snd_rpl_suspend, snd_rpl_resume, NULL)
SYSTEM_SLEEP_PM_OPS(snd_rpl_suspend, snd_rpl_resume)
};
static void snd_rpl_remove(struct pci_dev *pci)
{
struct rpl_dev_data *adata;
int ret;
adata = pci_get_drvdata(pci);
ret = rpl_deinit(adata->acp6x_base);
if (ret)
dev_err(&pci->dev, "ACP de-init failed\n");
pm_runtime_forbid(&pci->dev);
pm_runtime_get_noresume(&pci->dev);
pci_release_regions(pci);
pci_disable_device(pci);
}
static const struct pci_device_id snd_rpl_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_DEVICE_ID),
.class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
.class_mask = 0xffffff },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, snd_rpl_ids);
static struct pci_driver rpl_acp6x_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_rpl_ids,
.probe = snd_rpl_probe,
.remove = snd_rpl_remove,
.driver = {
.pm = pm_ptr(&rpl_pm),
}
};
module_pci_driver(rpl_acp6x_driver);
MODULE_DESCRIPTION("AMD ACP RPL PCI driver");
MODULE_LICENSE("GPL v2");

View File

@@ -1,36 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* AMD ACP Driver
*
* Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.
*/
#include "rpl_acp6x_chip_offset_byte.h"
#define ACP_DEVICE_ID 0x15E2
#define ACP6x_PHY_BASE_ADDRESS 0x1240000
#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001
#define ACP_PGFSM_CNTL_POWER_ON_MASK 1
#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0
#define ACP_PGFSM_STATUS_MASK 3
#define ACP_POWERED_ON 0
#define ACP_POWER_ON_IN_PROGRESS 1
#define ACP_POWERED_OFF 2
#define ACP_POWER_OFF_IN_PROGRESS 3
#define DELAY_US 5
#define ACP_COUNTER 20000
/* time in ms for runtime suspend delay */
#define ACP_SUSPEND_DELAY_MS 2000
static inline u32 rpl_acp_readl(void __iomem *base_addr)
{
return readl(base_addr - ACP6x_PHY_BASE_ADDRESS);
}
static inline void rpl_acp_writel(u32 val, void __iomem *base_addr)
{
writel(val, base_addr - ACP6x_PHY_BASE_ADDRESS);
}

View File

@@ -1,30 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* AMD ACP 6.2 Register Documentation
*
* Copyright 2022 Advanced Micro Devices, Inc.
*/
#ifndef _rpl_acp6x_OFFSET_HEADER
#define _rpl_acp6x_OFFSET_HEADER
/* Registers from ACP_CLKRST block */
#define ACP_SOFT_RESET 0x1241000
#define ACP_CONTROL 0x1241004
#define ACP_STATUS 0x1241008
#define ACP_DYNAMIC_CG_MASTER_CONTROL 0x1241010
#define ACP_PGFSM_CONTROL 0x124101C
#define ACP_PGFSM_STATUS 0x1241020
#define ACP_CLKMUX_SEL 0x1241024
/* Registers from ACP_AON block */
#define ACP_PME_EN 0x1241400
#define ACP_DEVICE_STATE 0x1241404
#define AZ_DEVICE_STATE 0x1241408
#define ACP_PIN_CONFIG 0x1241440
#define ACP_PAD_PULLUP_CTRL 0x1241444
#define ACP_PAD_PULLDOWN_CTRL 0x1241448
#define ACP_PAD_DRIVE_STRENGTH_CTRL 0x124144C
#define ACP_PAD_SCHMEN_CTRL 0x1241450
#endif

View File

@@ -357,7 +357,7 @@ static const struct snd_soc_component_driver acp5x_i2s_component = {
.close = acp5x_dma_close,
.hw_params = acp5x_dma_hw_params,
.pointer = acp5x_dma_pointer,
.pcm_construct = acp5x_dma_new,
.pcm_new = acp5x_dma_new,
};
static int acp5x_audio_probe(struct platform_device *pdev)

View File

@@ -45,6 +45,13 @@ static struct snd_soc_card acp6x_card = {
};
static const struct dmi_system_id yc_acp_quirk_table[] = {
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Lecoo"),
DMI_MATCH(DMI_PRODUCT_NAME, "Bellator N176"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
@@ -493,6 +500,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 17 D7VF"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
DMI_MATCH(DMI_PRODUCT_NAME, "Vector A16 HX A8WHG"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
@@ -731,6 +745,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "BM1403CDA"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_BOARD_NAME, "BM1403CDA"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
DMI_MATCH(DMI_PRODUCT_NAME, "Thin A15 B7VF"),
}
},
{
.driver_data = &acp6x_card,
.matches = {

View File

@@ -346,7 +346,7 @@ static const struct snd_soc_component_driver acp6x_pdm_component = {
.close = acp6x_pdm_dma_close,
.hw_params = acp6x_pdm_dma_hw_params,
.pointer = acp6x_pdm_dma_pointer,
.pcm_construct = acp6x_pdm_dma_new,
.pcm_new = acp6x_pdm_dma_new,
.legacy_dai_naming = 1,
};

View File

@@ -163,6 +163,7 @@ static int snd_acp6x_probe(struct pci_dev *pci,
switch (pci->revision) {
case 0x60:
case 0x6f:
case 0x62: /* RPL */
break;
default:
dev_dbg(&pci->dev, "acp6x pci device not found\n");
@@ -208,6 +209,17 @@ static int snd_acp6x_probe(struct pci_dev *pci,
case ACP_CONFIG_15:
dev_info(&pci->dev, "Audio Mode %d\n", val);
break;
case ACP_CONFIG_10:
case ACP_CONFIG_11:
case ACP_CONFIG_12:
case ACP_CONFIG_13:
case ACP_CONFIG_14:
/* PIN 10 to 14 is reserve for RPL */
if (pci->revision == 0x62) {
dev_info(&pci->dev, "RPL Audio Mode %d\n", val);
break;
}
fallthrough;
default:
adata->res = devm_kzalloc(&pci->dev,
sizeof(struct resource),

View File

@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
menu "Apple"
config SND_SOC_APPLE_MCA

View File

@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
snd-soc-apple-mca-y := mca.o
obj-$(CONFIG_SND_SOC_APPLE_MCA) += snd-soc-apple-mca.o

View File

@@ -1002,8 +1002,8 @@ static const struct snd_soc_component_driver mca_component = {
.hw_params = mca_hw_params,
.trigger = mca_trigger,
.pointer = mca_pointer,
.pcm_construct = mca_pcm_new,
.pcm_destruct = mca_pcm_free,
.pcm_new = mca_pcm_new,
.pcm_free = mca_pcm_free,
};
static void apple_mca_release(struct mca_data *mca)

View File

@@ -316,7 +316,7 @@ static const struct snd_soc_component_driver atmel_soc_platform = {
.prepare = atmel_pcm_prepare,
.trigger = atmel_pcm_trigger,
.pointer = atmel_pcm_pointer,
.pcm_construct = atmel_pcm_new,
.pcm_new = atmel_pcm_new,
};
int atmel_pcm_pdc_platform_register(struct device *dev)

View File

@@ -319,7 +319,7 @@ static const struct snd_soc_component_driver au1xpsc_soc_component = {
.prepare = au1xpsc_pcm_prepare,
.trigger = au1xpsc_pcm_trigger,
.pointer = au1xpsc_pcm_pointer,
.pcm_construct = au1xpsc_pcm_new,
.pcm_new = au1xpsc_pcm_new,
};
static int au1xpsc_pcm_drvprobe(struct platform_device *pdev)

View File

@@ -296,7 +296,7 @@ static const struct snd_soc_component_driver alchemy_pcm_soc_component = {
.hw_free = alchemy_pcm_hw_free,
.trigger = alchemy_pcm_trigger,
.pointer = alchemy_pcm_pointer,
.pcm_construct = alchemy_pcm_new,
.pcm_new = alchemy_pcm_new,
};
static int alchemy_pcm_drvprobe(struct platform_device *pdev)

View File

@@ -386,7 +386,7 @@ static const struct snd_soc_component_driver bcm63xx_soc_platform = {
.prepare = bcm63xx_pcm_prepare,
.trigger = bcm63xx_pcm_trigger,
.pointer = bcm63xx_pcm_pointer,
.pcm_construct = bcm63xx_soc_pcm_new,
.pcm_new = bcm63xx_soc_pcm_new,
};
int bcm63xx_soc_platform_probe(struct platform_device *pdev,

View File

@@ -713,7 +713,7 @@ static const struct snd_soc_component_driver cygnus_soc_platform = {
.prepare = cygnus_pcm_prepare,
.trigger = cygnus_pcm_trigger,
.pointer = cygnus_pcm_pointer,
.pcm_construct = cygnus_dma_new,
.pcm_new = cygnus_dma_new,
};
int cygnus_soc_platform_register(struct device *dev,

View File

@@ -398,31 +398,21 @@ config SND_SOC_WM_HUBS
default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m
config SND_SOC_WM_ADSP
tristate
tristate "Cirrus Logic wm_adsp driver" if KUNIT
select FW_CS_DSP
select SND_SOC_COMPRESS
default y if SND_SOC_MADERA=y
default y if SND_SOC_CS47L24=y
default y if SND_SOC_WM5102=y
default y if SND_SOC_WM5110=y
default y if SND_SOC_WM2200=y
default y if SND_SOC_CS35L41_SPI=y
default y if SND_SOC_CS35L41_I2C=y
default y if SND_SOC_CS35L45_SPI=y
default y if SND_SOC_CS35L45_I2C=y
default y if SND_SOC_CS35L56=y
default y if SND_SOC_CS48L32=y
default m if SND_SOC_MADERA=m
default m if SND_SOC_CS47L24=m
default m if SND_SOC_WM5102=m
default m if SND_SOC_WM5110=m
default m if SND_SOC_WM2200=m
default m if SND_SOC_CS35L41_SPI=m
default m if SND_SOC_CS35L41_I2C=m
default m if SND_SOC_CS35L45_SPI=m
default m if SND_SOC_CS35L45_I2C=m
default m if SND_SOC_CS35L56=m
default m if SND_SOC_CS48L32=m
config SND_SOC_WM_ADSP_TEST
tristate "KUnit tests for Cirrus Logic wm_adsp" if !KUNIT_ALL_TESTS
depends on KUNIT
depends on SND_SOC_WM_ADSP
default KUNIT_ALL_TESTS
help
This builds KUnit tests for the Cirrus Logic wm_adsp library.
For more information on KUnit and unit tests in general,
please refer to the KUnit documentation in
Documentation/dev-tools/kunit/.
If in doubt, say "N".
config SND_SOC_AB8500_CODEC
tristate
@@ -822,6 +812,7 @@ config SND_SOC_CS35L41_LIB
config SND_SOC_CS35L41
tristate
select SND_SOC_WM_ADSP
config SND_SOC_CS35L41_SPI
tristate "Cirrus Logic CS35L41 CODEC (SPI)"
@@ -840,6 +831,7 @@ config SND_SOC_CS35L41_I2C
config SND_SOC_CS35L45
tristate
select REGMAP_IRQ
select SND_SOC_WM_ADSP
config SND_SOC_CS35L45_SPI
tristate "Cirrus Logic CS35L45 CODEC (SPI)"
@@ -863,6 +855,7 @@ config SND_SOC_CS35L45_I2C
config SND_SOC_CS35L56
tristate
select SND_SOC_WM_ADSP
config SND_SOC_CS35L56_SHARED
select SND_SOC_CS_AMP_LIB
@@ -928,6 +921,19 @@ config SND_SOC_CS35L56_CAL_SET_CTRL
If unsure select "N".
config SND_SOC_CS35L56_CAL_PERFORM_CTRL
bool "CS35L56 ALSA control to perform factory calibration"
default N
select SND_SOC_CS35L56_CAL_DEBUGFS_COMMON
help
Allow performing factory calibration data through an ALSA
control. It is recommended to use the debugfs method instead
because debugfs has restricted access permissions.
On most platforms this is not needed.
If unsure select "N".
config SND_SOC_CS35L56_TEST
tristate "KUnit test for Cirrus Logic cs35l56 driver" if !KUNIT_ALL_TESTS
depends on SND_SOC_CS35L56 && KUNIT
@@ -1100,6 +1106,7 @@ config SND_SOC_CS47L15
config SND_SOC_CS47L24
tristate
depends on MFD_CS47L24 && MFD_ARIZONA
select SND_SOC_WM_ADSP
config SND_SOC_CS47L35
tristate
@@ -1121,6 +1128,7 @@ config SND_SOC_CS48L32
tristate "Cirrus Logic CS48L32 audio DSP"
depends on SPI_MASTER
select REGMAP_SPI
select SND_SOC_WM_ADSP
help
Build the codec driver for the Cirrus Logic CS48L32 audio DSP.
@@ -1379,6 +1387,7 @@ config SND_SOC_LOCHNAGAR_SC
config SND_SOC_MADERA
tristate
select SND_SOC_WM_ADSP
default y if SND_SOC_CS47L15=y
default y if SND_SOC_CS47L35=y
default y if SND_SOC_CS47L85=y
@@ -2364,9 +2373,11 @@ config SND_SOC_UDA1342
mic inputs), stereo audio DAC, with basic audio processing.
config SND_SOC_UDA1380
tristate
tristate "Philips UDA1380 CODEC"
depends on I2C
depends on GPIOLIB_LEGACY
help
The UDA1380 codec is used in the HTC Magician and on a number of
Samsung reference boards, as well as the LPC32xx series.
config SND_SOC_WCD_CLASSH
tristate
@@ -2477,6 +2488,7 @@ config SND_SOC_WM2000
config SND_SOC_WM2200
tristate
depends on I2C
select SND_SOC_WM_ADSP
config SND_SOC_WM5100
tristate
@@ -2485,10 +2497,12 @@ config SND_SOC_WM5100
config SND_SOC_WM5102
tristate
depends on MFD_WM5102 && MFD_ARIZONA
select SND_SOC_WM_ADSP
config SND_SOC_WM5110
tristate
depends on MFD_WM5110 && MFD_ARIZONA
select SND_SOC_WM_ADSP
config SND_SOC_WM8350
tristate

View File

@@ -361,6 +361,7 @@ snd-soc-wcd938x-sdw-y := wcd938x-sdw.o
snd-soc-wcd939x-y := wcd939x.o
snd-soc-wcd939x-sdw-y := wcd939x-sdw.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
snd-soc-wm1250-ev1-y := wm1250-ev1.o
snd-soc-wm2000-y := wm2000.o
@@ -862,6 +863,7 @@ obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o
obj-$(CONFIG_SND_SOC_WM_ADSP_TEST) += snd-soc-wm-adsp-test.o
obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o
obj-$(CONFIG_SND_SOC_WSA883X) += snd-soc-wsa883x.o

View File

@@ -38,7 +38,6 @@ static const char *ak5558_supply_names[AK5558_NUM_SUPPLIES] = {
/* AK5558 Codec Private Data */
struct ak5558_priv {
struct regulator_bulk_data supplies[AK5558_NUM_SUPPLIES];
struct snd_soc_component component;
struct regmap *regmap;
struct i2c_client *i2c;
struct gpio_desc *reset_gpiod; /* Reset & Power down GPIO */

View File

@@ -11,7 +11,6 @@
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
@@ -459,11 +458,6 @@ static int arizona_hpdet_do_id(struct arizona_priv *info, int *reading,
bool *mic)
{
struct arizona *arizona = info->arizona;
#ifdef CONFIG_GPIOLIB_LEGACY
int id_gpio = arizona->pdata.hpdet_id_gpio;
#else
int id_gpio = 0;
#endif
if (!arizona->pdata.hpdet_acc_id)
return 0;
@@ -474,9 +468,8 @@ static int arizona_hpdet_do_id(struct arizona_priv *info, int *reading,
*/
info->hpdet_res[info->num_hpdet_res++] = *reading;
#ifdef CONFIG_GPIOLIB_LEGACY
/* Only check the mic directly if we didn't already ID it */
if (id_gpio && info->num_hpdet_res == 1) {
if (info->hpdet_id_gpio && info->num_hpdet_res == 1) {
dev_dbg(arizona->dev, "Measuring mic\n");
regmap_update_bits(arizona->regmap,
@@ -486,13 +479,12 @@ static int arizona_hpdet_do_id(struct arizona_priv *info, int *reading,
ARIZONA_ACCDET_MODE_HPR |
info->micd_modes[0].src);
gpio_set_value_cansleep(id_gpio, 1);
gpiod_set_value_cansleep(info->hpdet_id_gpio, 1);
regmap_update_bits(arizona->regmap, ARIZONA_HEADPHONE_DETECT_1,
ARIZONA_HP_POLL, ARIZONA_HP_POLL);
return -EAGAIN;
}
#endif
/* OK, got both. Now, compare... */
dev_dbg(arizona->dev, "HPDET measured %d %d\n",
@@ -514,7 +506,7 @@ static int arizona_hpdet_do_id(struct arizona_priv *info, int *reading,
/*
* If we measure the mic as high impedance
*/
if (!id_gpio || info->hpdet_res[1] > 50) {
if (!info->hpdet_id_gpio || info->hpdet_res[1] > 50) {
dev_dbg(arizona->dev, "Detected mic\n");
*mic = true;
info->detecting = true;
@@ -533,9 +525,6 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
{
struct arizona_priv *info = data;
struct arizona *arizona = info->arizona;
#ifdef CONFIG_GPIOLIB_LEGACY
int id_gpio = arizona->pdata.hpdet_id_gpio;
#endif
int ret, reading, state, report;
bool mic = false;
@@ -591,10 +580,8 @@ done:
arizona_extcon_hp_clamp(info, false);
#ifdef CONFIG_GPIOLIB_LEGACY
if (id_gpio)
gpio_set_value_cansleep(id_gpio, 0);
#endif
if (info->hpdet_id_gpio)
gpiod_set_value_cansleep(info->hpdet_id_gpio, 0);
/* If we have a mic then reenable MICDET */
if (state && (mic || info->mic))
@@ -1325,58 +1312,33 @@ int arizona_jack_codec_dev_probe(struct arizona_priv *info, struct device *dev)
regmap_update_bits(arizona->regmap, ARIZONA_GP_SWITCH_1,
ARIZONA_SW1_MODE_MASK, arizona->pdata.gpsw);
#ifdef CONFIG_GPIOLIB_LEGACY
if (pdata->micd_pol_gpio > 0) {
if (info->micd_modes[0].gpio)
mode = GPIOF_OUT_INIT_HIGH;
else
mode = GPIOF_OUT_INIT_LOW;
if (info->micd_modes[0].gpio)
mode = GPIOD_OUT_HIGH;
else
mode = GPIOD_OUT_LOW;
ret = devm_gpio_request_one(dev, pdata->micd_pol_gpio,
mode, "MICD polarity");
if (ret != 0) {
dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
pdata->micd_pol_gpio, ret);
return ret;
}
info->micd_pol_gpio = gpio_to_desc(pdata->micd_pol_gpio);
} else
#endif
{
if (info->micd_modes[0].gpio)
mode = GPIOD_OUT_HIGH;
else
mode = GPIOD_OUT_LOW;
/* We can't use devm here because we need to do the get
* against the MFD device, as that is where the of_node
* will reside, but if we devm against that the GPIO
* will not be freed if the extcon driver is unloaded.
*/
info->micd_pol_gpio = gpiod_get_optional(arizona->dev,
"wlf,micd-pol",
mode);
if (IS_ERR(info->micd_pol_gpio)) {
ret = PTR_ERR(info->micd_pol_gpio);
dev_err_probe(arizona->dev, ret, "getting microphone polarity GPIO\n");
return ret;
}
/* We can't use devm here because we need to do the get
* against the MFD device, as that is where the of_node
* will reside, but if we devm against that the GPIO
* will not be freed if the extcon driver is unloaded.
*/
info->micd_pol_gpio = gpiod_get_optional(arizona->dev,
"wlf,micd-pol",
mode);
if (IS_ERR(info->micd_pol_gpio)) {
ret = PTR_ERR(info->micd_pol_gpio);
dev_err_probe(arizona->dev, ret, "getting microphone polarity GPIO\n");
return ret;
}
#ifdef CONFIG_GPIOLIB_LEGACY
if (arizona->pdata.hpdet_id_gpio > 0) {
ret = devm_gpio_request_one(dev, arizona->pdata.hpdet_id_gpio,
GPIOF_OUT_INIT_LOW,
"HPDET");
if (ret != 0) {
dev_err(arizona->dev, "Failed to request GPIO%d: %d\n",
arizona->pdata.hpdet_id_gpio, ret);
gpiod_put(info->micd_pol_gpio);
return ret;
}
info->hpdet_id_gpio = gpiod_get_optional(arizona->dev,
"wlf,hpdet-id-gpio",
mode);
if (IS_ERR(info->hpdet_id_gpio)) {
ret = PTR_ERR(info->hpdet_id_gpio);
dev_err_probe(arizona->dev, ret, "getting headphone detect ID GPIO\n");
return ret;
}
#endif
return 0;
}
@@ -1385,6 +1347,7 @@ EXPORT_SYMBOL_GPL(arizona_jack_codec_dev_probe);
int arizona_jack_codec_dev_remove(struct arizona_priv *info)
{
gpiod_put(info->micd_pol_gpio);
gpiod_put(info->hpdet_id_gpio);
return 0;
}
EXPORT_SYMBOL_GPL(arizona_jack_codec_dev_remove);

View File

@@ -100,6 +100,7 @@ struct arizona_priv {
struct snd_soc_jack *jack;
struct regulator *micvdd;
struct gpio_desc *micd_pol_gpio;
struct gpio_desc *hpdet_id_gpio;
u16 last_jackdet;

View File

@@ -544,8 +544,7 @@ static int aw87390_i2c_probe(struct i2c_client *i2c)
const struct snd_soc_component_driver *priv;
int ret;
ret = i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C);
if (!ret)
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
return dev_err_probe(&i2c->dev, -ENXIO, "check_functionality failed\n");
aw87390 = devm_kzalloc(&i2c->dev, sizeof(*aw87390), GFP_KERNEL);

View File

@@ -1253,8 +1253,7 @@ static int aw88081_i2c_probe(struct i2c_client *i2c)
struct aw88081 *aw88081;
int ret;
ret = i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C);
if (!ret)
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
return dev_err_probe(&i2c->dev, -ENXIO, "check_functionality failed");
aw88081 = devm_kzalloc(&i2c->dev, sizeof(*aw88081), GFP_KERNEL);

View File

@@ -1574,18 +1574,22 @@ static int aw88166_dev_init(struct aw88166 *aw88166, struct aw_container *aw_cfg
static int aw88166_request_firmware_file(struct aw88166 *aw88166)
{
const struct firmware *cont = NULL;
const char *fw_name;
int ret;
aw88166->aw_pa->fw_status = AW88166_DEV_FW_FAILED;
ret = request_firmware(&cont, AW88166_ACF_FILE, aw88166->aw_pa->dev);
if (device_property_read_string(aw88166->aw_pa->dev, "firmware-name", &fw_name) < 0)
fw_name = AW88166_ACF_FILE;
ret = request_firmware(&cont, fw_name, aw88166->aw_pa->dev);
if (ret) {
dev_err(aw88166->aw_pa->dev, "request [%s] failed!\n", AW88166_ACF_FILE);
dev_err(aw88166->aw_pa->dev, "request [%s] failed!\n", fw_name);
return ret;
}
dev_dbg(aw88166->aw_pa->dev, "loaded %s - size: %zu\n",
AW88166_ACF_FILE, cont ? cont->size : 0);
fw_name, cont ? cont->size : 0);
aw88166->aw_cfg = devm_kzalloc(aw88166->aw_pa->dev,
struct_size(aw88166->aw_cfg, data, cont->size), GFP_KERNEL);
@@ -1599,7 +1603,7 @@ static int aw88166_request_firmware_file(struct aw88166 *aw88166)
ret = aw88395_dev_load_acf_check(aw88166->aw_pa, aw88166->aw_cfg);
if (ret) {
dev_err(aw88166->aw_pa->dev, "load [%s] failed!\n", AW88166_ACF_FILE);
dev_err(aw88166->aw_pa->dev, "load [%s] failed!\n", fw_name);
return ret;
}

View File

@@ -1094,17 +1094,22 @@ static int aw88261_dev_init(struct aw88261 *aw88261, struct aw_container *aw_cfg
static int aw88261_request_firmware_file(struct aw88261 *aw88261)
{
const struct firmware *cont = NULL;
const char *fw_name;
int ret;
aw88261->aw_pa->fw_status = AW88261_DEV_FW_FAILED;
ret = request_firmware(&cont, AW88261_ACF_FILE, aw88261->aw_pa->dev);
ret = device_property_read_string(aw88261->aw_pa->dev, "firmware-name", &fw_name);
if (ret)
fw_name = AW88261_ACF_FILE;
ret = request_firmware(&cont, fw_name, aw88261->aw_pa->dev);
if (ret)
return dev_err_probe(aw88261->aw_pa->dev, ret,
"load [%s] failed!", AW88261_ACF_FILE);
"load [%s] failed!", fw_name);
dev_info(aw88261->aw_pa->dev, "loaded %s - size: %zu\n",
AW88261_ACF_FILE, cont ? cont->size : 0);
fw_name, cont ? cont->size : 0);
aw88261->aw_cfg = devm_kzalloc(aw88261->aw_pa->dev, cont->size + sizeof(int), GFP_KERNEL);
if (!aw88261->aw_cfg) {
@@ -1117,7 +1122,7 @@ static int aw88261_request_firmware_file(struct aw88261 *aw88261)
ret = aw88395_dev_load_acf_check(aw88261->aw_pa, aw88261->aw_cfg);
if (ret) {
dev_err(aw88261->aw_pa->dev, "load [%s] failed !", AW88261_ACF_FILE);
dev_err(aw88261->aw_pa->dev, "load [%s] failed !", fw_name);
return ret;
}
@@ -1237,8 +1242,7 @@ static int aw88261_i2c_probe(struct i2c_client *i2c)
struct aw88261 *aw88261;
int ret;
ret = i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C);
if (!ret)
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
return dev_err_probe(&i2c->dev, -ENXIO, "check_functionality failed");
aw88261 = devm_kzalloc(&i2c->dev, sizeof(*aw88261), GFP_KERNEL);

View File

@@ -948,7 +948,7 @@ static const struct snd_soc_component_driver wov_component_driver = {
.hw_params = wov_pcm_hw_params,
.hw_free = wov_pcm_hw_free,
.pointer = wov_pcm_pointer,
.pcm_construct = wov_pcm_new,
.pcm_new = wov_pcm_new,
};
static int cros_ec_codec_platform_probe(struct platform_device *pdev)

View File

@@ -17,7 +17,6 @@
#include <linux/module.h>
#include <linux/overflow.h>
#include <linux/pci_ids.h>
#include <linux/platform_device.h>
#include <linux/random.h>
#include <sound/cs-amp-lib.h>

View File

@@ -716,6 +716,8 @@ int cs_amp_get_vendor_spkid(struct device *dev)
{
int i, ret;
KUNIT_STATIC_STUB_REDIRECT(cs_amp_get_vendor_spkid, dev);
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE) &&
!IS_ENABLED(CONFIG_SND_SOC_CS_AMP_LIB_TEST_HOOKS))
return -ENOENT;

View File

@@ -1404,6 +1404,7 @@ static int cs35l41_runtime_suspend(struct device *dev)
if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running)
return 0;
wm_adsp_hibernate(&cs35l41->dsp, true);
cs35l41_enter_hibernate(dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type);
regcache_cache_only(cs35l41->regmap, true);
@@ -1432,10 +1433,14 @@ static int cs35l41_runtime_resume(struct device *dev)
cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap);
ret = regcache_sync(cs35l41->regmap);
cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap);
wm_adsp_hibernate(&cs35l41->dsp, false);
if (ret) {
dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret);
return ret;
}
cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, &cs35l41->hw_cfg);
return 0;

View File

@@ -984,6 +984,7 @@ static int cs35l45_runtime_suspend(struct device *dev)
if (!cs35l45->dsp.preloaded || !cs35l45->dsp.cs_dsp.running)
return 0;
wm_adsp_hibernate(&cs35l45->dsp, true);
cs35l45_enter_hibernate(cs35l45);
regcache_cache_only(cs35l45->regmap, true);
@@ -1014,6 +1015,8 @@ static int cs35l45_runtime_resume(struct device *dev)
if (ret != 0)
dev_warn(cs35l45->dev, "regcache_sync failed: %d\n", ret);
wm_adsp_hibernate(&cs35l45->dsp, false);
/* Clear global error status */
regmap_clear_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK);
regmap_set_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK);

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