Merge remote-tracking branch 'asoc/for-7.3' into asoc-next

This commit is contained in:
Mark Brown
2026-08-03 13:18:29 +01:00
397 changed files with 12373 additions and 6722 deletions

View File

@@ -30,7 +30,7 @@ properties:
minItems: 1
maxItems: 3
description:
Base PLL clocks of audio susbsytem, used to configure base clock
Base PLL clocks of audio subsystem, used to configure base clock
frequencies for different audio use-cases.
patternProperties:

View File

@@ -31,7 +31,7 @@ properties:
minItems: 1
maxItems: 3
description:
Base PLL clocks of audio susbsytem, used to configure base clock
Base PLL clocks of audio subsystem, used to configure base clock
frequencies for different audio use-cases.
patternProperties:

View File

@@ -0,0 +1,240 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/cirrus,cs35l36.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Cirrus Logic CS35L36 Speaker Amplifier
maintainers:
- David Rhodes <drhodes@opensource.cirrus.com>
- patches@opensource.cirrus.com
description:
CS35L36 is a boosted mono Class D amplifier
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
enum:
- cirrus,cs35l36
reg:
maxItems: 1
interrupts:
maxItems: 1
VA-supply:
description: Voltage regulator of analog internal section
VP-supply:
description: Voltage regulator of boost converter
reset-gpios:
maxItems: 1
cirrus,boost-ctl-millivolt:
description: Boost converter output voltage (step 50)
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 2550
maximum: 12000
cirrus,boost-peak-milliamp:
description: Boost-converter peak current limit (step 50)
$ref: /schemas/types.yaml#/definitions/uint32
default: 4500
minimum: 1600
maximum: 4500
cirrus,boost-ind-nanohenry:
description: Initial inductor estimation reference value (1000=1μH, 1200=1.2μH)
$ref: /schemas/types.yaml#/definitions/uint32
default: 1000
cirrus,multi-amp-mode:
description: Hi-Z ASP port when more than one amplifier in system
type: boolean
cirrus,boost-ctl-select:
description: Boost converter control source selection
$ref: /schemas/types.yaml#/definitions/uint32
default: 1
enum:
- 0 # Control Port
- 1 # Class
- 2 # Sync
cirrus,amp-pcm-inv:
description: Invert incoming PCM data when true
type: boolean
cirrus,imon-pol-inv:
description: Invert polarity of outbound IMON feedback when true
type: boolean
cirrus,vmon-pol-inv:
description: Invert polarity of outbound VMON feedback when true
type: boolean
cirrus,dcm-mode-enable:
description: Enable boost converter automatic Discontinuous Conduction Mode
type: boolean
cirrus,weak-fet-disable:
description: Reduce output driver strength in Weak-FET Drive Mode when true
type: boolean
cirrus,classh-wk-fet-delay-ms:
description: Weak-FET entry delay
default: 100
enum: [0, 5, 10, 50, 100, 200, 500, 1000]
cirrus,classh-weak-fet-thld-millivolt:
description: Weak-FET drive threshold
$ref: /schemas/types.yaml#/definitions/uint32
enum: [50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700]
cirrus,temp-warn-threshold:
description: Overtemperature warning threshold
$ref: /schemas/types.yaml#/definitions/uint32
default: 2
enum:
- 0 # 105°C
- 1 # 115°C
- 2 # 125°C
- 3 # 135°C
cirrus,irq-drive-select:
description: Interrupt output driver type
$ref: /schemas/types.yaml#/definitions/uint32
default: 1
enum:
- 0 # open-drain
- 1 # push-pull
cirrus,irq-gpio-select:
description: Programmable IRQ pin selection
$ref: /schemas/types.yaml#/definitions/uint32
enum:
- 0 # PDM_DATA/SWIRE_SD/INT
- 1 # GPIO
cirrus,vpbr-config:
$ref: "#/$defs/vpbr-config"
$defs:
vpbr-config:
description: Brownout prevention configuration sub-node
type: object
additionalProperties: false
properties:
cirrus,vpbr-en:
description: VBST brownout prevention enable
$ref: /schemas/types.yaml#/definitions/uint32
default: 0
enum:
- 0 # disabled
- 1 # enabled
cirrus,vpbr-thld:
description: Initial VPBR threshold voltage
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 2
maximum: 31
cirrus,vpbr-atk-rate:
description: Attenuation attack step rate
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 7
cirrus,vpbr-atk-vol:
description: VP brownout prevention step size
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 7
cirrus,vpbr-max-attn:
description: Maximum attenuation during VP brownout prevention (dB)
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 15
cirrus,vpbr-wait:
description: Delay between brownout clearance and attenuation release (ms)
$ref: /schemas/types.yaml#/definitions/uint32
default: 1
enum:
- 0 # 10
- 1 # 100
- 2 # 250
- 3 # 500
cirrus,vpbr-rel-rate:
description: Attenuation release step rate
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 7
cirrus,vpbr-mute-en:
description: Mute audio if maximum attenuation reached
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 1
required:
- compatible
- reg
- interrupts
- VA-supply
- cirrus,boost-ctl-millivolt
- cirrus,boost-peak-milliamp
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
codec@40 {
compatible = "cirrus,cs35l36";
reg = <0x40>;
VA-supply = <&dummy_vreg>;
VP-supply = <&dummy_vreg>;
reset-gpios = <&gpio0 54 GPIO_ACTIVE_HIGH>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
cirrus,boost-ind-nanohenry = <1000>;
cirrus,boost-ctl-millivolt = <10000>;
cirrus,boost-peak-milliamp = <4500>;
cirrus,boost-ctl-select = <0>;
cirrus,classh-wk-fet-delay-ms = <100>;
cirrus,classh-weak-fet-thld-millivolt = <100>;
cirrus,temp-warn-threshold = <1>;
cirrus,multi-amp-mode;
cirrus,irq-drive-select = <1>;
cirrus,irq-gpio-select = <1>;
cirrus,vpbr-config {
cirrus,vpbr-en = <0>;
cirrus,vpbr-thld = <5>;
cirrus,vpbr-atk-rate = <2>;
cirrus,vpbr-atk-vol = <1>;
cirrus,vpbr-max-attn = <9>;
cirrus,vpbr-wait = <1>;
cirrus,vpbr-rel-rate = <5>;
cirrus,vpbr-mute-en = <0>;
};
};
};
...

View File

@@ -1,168 +0,0 @@
CS35L36 Speaker Amplifier
Required properties:
- compatible : "cirrus,cs35l36"
- reg : the I2C address of the device for I2C
- VA-supply, VP-supply : power supplies for the device,
as covered in
Documentation/devicetree/bindings/regulator/regulator.txt.
- cirrus,boost-ctl-millivolt : Boost Voltage Value. Configures the boost
converter's output voltage in mV. The range is from 2550mV to 12000mV with
increments of 50mV.
(Default) VP
- cirrus,boost-peak-milliamp : Boost-converter peak current limit in mA.
Configures the peak current by monitoring the current through the boost FET.
Range starts at 1600mA and goes to a maximum of 4500mA with increments of
50mA.
(Default) 4.50 Amps
- cirrus,boost-ind-nanohenry : Inductor estimation LBST reference value.
Seeds the digital boost converter's inductor estimation block with the initial
inductance value to reference.
1000 = 1uH (Default)
1200 = 1.2uH
Optional properties:
- cirrus,multi-amp-mode : Boolean to determine if there are more than
one amplifier in the system. If more than one it is best to Hi-Z the ASP
port to prevent bus contention on the output signal
- cirrus,boost-ctl-select : Boost converter control source selection.
Selects the source of the BST_CTL target VBST voltage for the boost
converter to generate.
0x00 - Control Port Value
0x01 - Class H Tracking (Default)
0x10 - MultiDevice Sync Value
- cirrus,amp-pcm-inv : Boolean to determine Amplifier will invert incoming
PCM data
- cirrus,imon-pol-inv : Boolean to determine Amplifier will invert the
polarity of outbound IMON feedback data
- cirrus,vmon-pol-inv : Boolean to determine Amplifier will invert the
polarity of outbound VMON feedback data
- cirrus,dcm-mode-enable : Boost converter automatic DCM Mode enable.
This enables the digital boost converter to operate in a low power
(Discontinuous Conduction) mode during low loading conditions.
- cirrus,weak-fet-disable : Boolean : The strength of the output drivers is
reduced when operating in a Weak-FET Drive Mode and must not be used to drive
a large load.
- cirrus,classh-wk-fet-delay : Weak-FET entry delay. Controls the delay
(in ms) before the Class H algorithm switches to the weak-FET voltage
(after the audio falls and remains below the value specified in WKFET_AMP_THLD).
0 = 0ms
1 = 5ms
2 = 10ms
3 = 50ms
4 = 100ms (Default)
5 = 200ms
6 = 500ms
7 = 1000ms
- cirrus,classh-weak-fet-thld-millivolt : Weak-FET amplifier drive threshold.
Configures the signal threshold at which the PWM output stage enters
weak-FET operation. The range is 50mV to 700mV in 50mV increments.
- cirrus,temp-warn-threshold : Amplifier overtemperature warning threshold.
Configures the threshold at which the overtemperature warning condition occurs.
When the threshold is met, the overtemperature warning attenuation is applied
and the TEMP_WARN_EINT interrupt status bit is set.
If TEMP_WARN_MASK = 0, INTb is asserted.
0 = 105C
1 = 115C
2 = 125C (Default)
3 = 135C
- cirrus,irq-drive-select : Selects the driver type of the selected interrupt
output.
0 = Open-drain
1 = Push-pull (Default)
- cirrus,irq-gpio-select : Selects the pin to serve as the programmable
interrupt output.
0 = PDM_DATA / SWIRE_SD / INT (Default)
1 = GPIO
Optional properties for the "cirrus,vpbr-config" Sub-node
- cirrus,vpbr-en : VBST brownout prevention enable. Configures whether the
VBST brownout prevention algorithm is enabled or disabled.
0 = VBST brownout prevention disabled (default)
1 = VBST brownout prevention enabled
See Section 7.31.1 VPBR Config for configuration options & further details
- cirrus,vpbr-thld : Initial VPBR threshold. Configures the VP brownout
threshold voltage
- cirrus,cirrus,vpbr-atk-rate : Attenuation attack step rate. Configures the
amount delay between consecutive volume attenuation steps when a brownout
condition is present and the VP brownout condition is in an attacking state.
- cirrus,vpbr-atk-vol : VP brownout prevention step size. Configures the VP
brownout prevention attacking attenuation step size when operating in either
digital volume or analog gain modes.
- cirrus,vpbr-max-attn : Maximum attenuation that the VP brownout prevention
can apply to the audio signal.
- cirrus,vpbr-wait : Configures the delay time between a brownout condition
no longer being present and the VP brownout prevention entering an attenuation
release state.
- cirrus,vpbr-rel-rate : Attenuation release step rate. Configures the delay
between consecutive volume attenuation release steps when a brownout condition
is not longer present and the VP brownout is in an attenuation release state.
- cirrus,vpbr-mute-en : During the attack state, if the vpbr-max-attn value
is reached, the error condition still remains, and this bit is set, the audio
is muted.
Example:
cs35l36: cs35l36@40 {
compatible = "cirrus,cs35l36";
reg = <0x40>;
VA-supply = <&dummy_vreg>;
VP-supply = <&dummy_vreg>;
reset-gpios = <&gpio0 54 0>;
interrupt-parent = <&gpio8>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
cirrus,boost-ind-nanohenry = <1000>;
cirrus,boost-ctl-millivolt = <10000>;
cirrus,boost-peak-milliamp = <4500>;
cirrus,boost-ctl-select = <0x00>;
cirrus,weak-fet-delay = <0x04>;
cirrus,weak-fet-thld = <0x01>;
cirrus,temp-warn-threshold = <0x01>;
cirrus,multi-amp-mode;
cirrus,irq-drive-select = <0x01>;
cirrus,irq-gpio-select = <0x01>;
cirrus,vpbr-config {
cirrus,vpbr-en = <0x00>;
cirrus,vpbr-thld = <0x05>;
cirrus,vpbr-atk-rate = <0x02>;
cirrus,vpbr-atk-vol = <0x01>;
cirrus,vpbr-max-attn = <0x09>;
cirrus,vpbr-wait = <0x01>;
cirrus,vpbr-rel-rate = <0x05>;
cirrus,vpbr-mute-en = <0x00>;
};
};

View File

@@ -39,6 +39,10 @@ properties:
wakeup-delay-ms:
description: Delay (in ms) after enabling the DMIC
port:
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
required:
- compatible

View File

@@ -0,0 +1,61 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/eukrea,asoc-tlv320.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Audio complex for Eukrea boards with tlv320aic23 codec.
maintainers:
- Frank Li <Frank.Li@nxp.com>
properties:
compatible:
const: eukrea,asoc-tlv320
eukrea,model:
$ref: /schemas/types.yaml#/definitions/string
description:
The user-visible name of this sound complex.
ssi-controller:
$ref: /schemas/types.yaml#/definitions/phandle
description:
The phandle of the SSI controller.
fsl,mux-int-port:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
The internal port of the i.MX audio muxer (AUDMUX).
Note: The AUDMUX port numbering should start at 1, which is consistent with
hardware manual.
minimum: 1
maximum: 8
fsl,mux-ext-port:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
The external port of the i.MX audio muxer.
Note: The AUDMUX port numbering should start at 1, which is consistent with
hardware manual.
minimum: 1
maximum: 8
required:
- compatible
- eukrea,model
- ssi-controller
- fsl,mux-int-port
- fsl,mux-ext-port
additionalProperties: false
examples:
- |
sound {
compatible = "eukrea,asoc-tlv320";
eukrea,model = "imx51-eukrea-tlv320aic23";
ssi-controller = <&ssi2>;
fsl,mux-int-port = <2>;
fsl,mux-ext-port = <3>;
};

View File

@@ -1,26 +0,0 @@
Audio complex for Eukrea boards with tlv320aic23 codec.
Required properties:
- compatible : "eukrea,asoc-tlv320"
- eukrea,model : The user-visible name of this sound complex.
- ssi-controller : The phandle of the SSI controller.
- fsl,mux-int-port : The internal port of the i.MX audio muxer (AUDMUX).
- fsl,mux-ext-port : The external port of the i.MX audio muxer.
Note: The AUDMUX port numbering should start at 1, which is consistent with
hardware manual.
Example:
sound {
compatible = "eukrea,asoc-tlv320";
eukrea,model = "imx51-eukrea-tlv320aic23";
ssi-controller = <&ssi2>;
fsl,mux-int-port = <2>;
fsl,mux-ext-port = <3>;
};

View File

@@ -66,6 +66,10 @@ properties:
"#sound-dai-cells":
const: 0
port:
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
required:
- compatible
- reg

View File

@@ -8,19 +8,22 @@ title: Loongson 7axxx/2kxxx ASoC audio sound card driver
maintainers:
- Yingkun Meng <mengyingkun@loongson.cn>
- Binbin Zhou <zhoubinbin@loongson.cn>
description:
The binding describes the sound card present in loongson
7axxx/2kxxx platform. The sound card is an ASoC component
which uses Loongson I2S controller to transfer the audio data.
allOf:
- $ref: sound-card-common.yaml#
properties:
compatible:
const: loongson,ls-audio-card
model:
$ref: /schemas/types.yaml#/definitions/string
description: User specified audio sound card name
enum:
- loongson,ls-audio-card # Loongson-2K1000/Loongson-2K2000/LS7A
- loongson,ls2k0300-forever-pi-audio-card # CTCISZ Forever Pi
- loongson,ls2k0300-dl2k0300b-audio-card # ATK-DL2K0300B
mclk-fs:
$ref: simple-card.yaml#/definitions/mclk-fs
@@ -45,14 +48,25 @@ properties:
required:
- sound-dai
spkr-en-gpios:
maxItems: 1
description: The GPIO that enables the speakers
hp-ctl-gpios:
maxItems: 1
description: The GPIO that control the headphones
hp-det-gpios:
maxItems: 1
description: The GPIO that detect headphones are plugged in
required:
- compatible
- model
- mclk-fs
- cpu
- codec
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@@ -68,3 +82,28 @@ examples:
sound-dai = <&es8323>;
};
};
- |
#include <dt-bindings/gpio/gpio.h>
sound {
compatible = "loongson,ls2k0300-dl2k0300b-audio-card";
model = "loongson-audio";
mclk-fs = <512>;
hp-det-gpios = <&gpio 81 GPIO_ACTIVE_HIGH>;
spkr-en-gpios = <&gpio 86 GPIO_ACTIVE_HIGH>;
hp-ctl-gpios = <&gpio 87 GPIO_ACTIVE_HIGH>;
audio-routing =
"Headphone", "LOUT1",
"Headphone", "ROUT1",
"Speaker", "LOUT2",
"Speaker", "ROUT2";
cpu {
sound-dai = <&i2s>;
};
codec {
sound-dai = <&es8388>;
};
};

View File

@@ -14,9 +14,12 @@ allOf:
properties:
compatible:
const: loongson,ls2k1000-i2s
enum:
- loongson,ls2k0300-i2s
- loongson,ls2k1000-i2s
reg:
minItems: 1
items:
- description: Loongson I2S controller Registers.
- description: APB DMA config register for Loongson I2S controller.
@@ -49,6 +52,23 @@ required:
unevaluatedProperties: false
if:
properties:
compatible:
contains:
enum:
- loongson,ls2k1000-i2s
then:
properties:
reg:
minItems: 2
else:
properties:
reg:
maxItems: 1
examples:
- |
#include <dt-bindings/clock/loongson,ls2k-clk.h>

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/mediatek,mtk-btcvsd-snd.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek ALSA BT SCO CVSD/MSBC
maintainers:
- Luca Leonardo Scorcia <l.scorcia@gmail.com>
properties:
compatible:
const: mediatek,mtk-btcvsd-snd
reg:
items:
- description: PKV region
- description: SRAM_BANK2 region
interrupts:
items:
- description: BT-SCO interrupt
mediatek,infracfg:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of the infracfg controller
mediatek,offset:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: Array of register offsets and masks
items:
- description: infra_misc_offset
- description: infra_conn_bt_cvsd_mask
- description: cvsd_mcu_read_offset
- description: cvsd_mcu_write_offset
- description: cvsd_packet_indicator_offset
required:
- compatible
- reg
- interrupts
- mediatek,infracfg
- mediatek,offset
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
mtk-btcvsd-snd@18000000 {
compatible = "mediatek,mtk-btcvsd-snd";
reg = <0x18000000 0x1000>,
<0x18080000 0x8000>;
interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_LOW>;
mediatek,infracfg = <&infrasys>;
mediatek,offset = <0xf00 0x800 0xfd0 0xfd4 0xfd8>;
};

View File

@@ -1,24 +0,0 @@
Mediatek ALSA BT SCO CVSD/MSBC Driver
Required properties:
- compatible = "mediatek,mtk-btcvsd-snd";
- reg: register location and size of PKV and SRAM_BANK2
- interrupts: should contain BTSCO interrupt
- mediatek,infracfg: the phandles of INFRASYS
- mediatek,offset: Array contains of register offset and mask
infra_misc_offset,
infra_conn_bt_cvsd_mask,
cvsd_mcu_read_offset,
cvsd_mcu_write_offset,
cvsd_packet_indicator_offset
Example:
mtk-btcvsd-snd@18000000 {
compatible = "mediatek,mtk-btcvsd-snd";
reg=<0 0x18000000 0 0x1000>,
<0 0x18080000 0 0x8000>;
interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_LOW>;
mediatek,infracfg = <&infrasys>;
mediatek,offset = <0xf00 0x800 0xfd0 0xfd4 0xfd8>;
};

View File

@@ -1,20 +0,0 @@
* Texas Instruments OMAP4+ Digital Microphone Module
Required properties:
- compatible: "ti,omap4-dmic"
- reg: Register location and size as an array:
<MPU access base address, size>,
<L3 interconnect address, size>;
- interrupts: Interrupt number for DMIC
- ti,hwmods: Name of the hwmod associated with OMAP dmic IP
Example:
dmic: dmic@4012e000 {
compatible = "ti,omap4-dmic";
reg = <0x4012e000 0x7f>, /* MPU private access */
<0x4902e000 0x7f>; /* L3 Interconnect */
interrupts = <0 114 0x4>;
interrupt-parent = <&gic>;
ti,hwmods = "dmic";
};

View File

@@ -14,7 +14,13 @@ description:
properties:
compatible:
const: qcom,msm8916-wcd-digital-codec
oneOf:
- items:
- enum:
- qcom,sdm660-wcd-digital-codec
- const: qcom,msm8916-wcd-digital-codec
- const: qcom,msm8916-wcd-digital-codec
reg:
maxItems: 1

View File

@@ -14,7 +14,16 @@ description:
properties:
compatible:
const: qcom,pm8916-wcd-analog-codec
oneOf:
- items:
- enum:
- qcom,pm660l-wcd-analog-codec
- const: qcom,pm8953-wcd-analog-codec
- enum:
- qcom,pm8916-wcd-analog-codec
- qcom,pm8950-wcd-analog-codec
- qcom,pm8953-wcd-analog-codec
reg:
maxItems: 1

View File

@@ -21,6 +21,43 @@ properties:
'#sound-dai-cells':
const: 1
'#address-cells':
const: 1
'#size-cells':
const: 0
# Digital Audio Interfaces
patternProperties:
'^dai@[0-9a-f]+$':
type: object
description:
Q6DSP Digital Audio Interfaces.
properties:
reg:
maxItems: 1
description:
Digital Audio Interface ID
clocks:
minItems: 1
maxItems: 2
clock-names:
minItems: 1
items:
- enum: [bclk, mclk]
- const: mclk
dependencies:
clocks: [clock-names]
required:
- reg
additionalProperties: false
required:
- compatible
- '#sound-dai-cells'
@@ -29,7 +66,20 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/sound/qcom,q6afe.h>
dais {
compatible = "qcom,q6apm-lpass-dais";
#sound-dai-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
dai@10 {
reg = <PRIMARY_MI2S_RX>;
clocks = <&q6prmcc LPASS_CLK_ID_PRI_MI2S_IBIT
LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
<&q6prmcc LPASS_CLK_ID_MCLK_1
LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
clock-names = "bclk", "mclk";
};
};

View File

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

View File

@@ -24,12 +24,15 @@ properties:
- items:
- enum:
- qcom,eliza-sndcard
- qcom,hawi-sndcard
- qcom,kaanapali-sndcard
- qcom,sm8475-sndcard
- qcom,sm8550-sndcard
- qcom,sm8650-sndcard
- qcom,sm8750-sndcard
- const: qcom,sm8450-sndcard
- enum:
- ayaneo,pocket-s2-sndcard
- fairphone,fp4-sndcard
- fairphone,fp5-sndcard
- qcom,apq8096-sndcard
@@ -45,6 +48,7 @@ properties:
- qcom,qrb5165-rb5-sndcard
- qcom,sc7180-qdsp6-sndcard
- qcom,sc8280xp-sndcard
- qcom,sdm660-sndcard
- qcom,sdm845-sndcard
- qcom,sm8250-sndcard
- qcom,sm8450-sndcard

View File

@@ -0,0 +1,93 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/qcom,wsa8855.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm WSA8855 stereo smart speaker amplifier
maintainers:
- Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
- Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
description:
WSA885X is a Qualcomm Aqstic stereo smart speaker amplifier. It uses a PCM
audio interface, an I2C control interface, and a Class-H amplifier path for
high efficiency, low output noise, and low idle power consumption.
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
const: qcom,wsa8855
reg:
maxItems: 1
'#sound-dai-cells':
const: 0
powerdown-gpios:
description: GPIO controlling the SD_N powerdown pin.
maxItems: 1
reset-gpios:
description: GPIO controlling the SD_N powerdown pin.
maxItems: 1
interrupts:
maxItems: 1
vdd-1p8-supply: true
vdd-io-supply: true
qcom,battery-config:
description:
Battery topology connected to the speaker amplifier. 1S indicates one
battery cell in series, while 2S indicates two battery cells in series.
$ref: /schemas/types.yaml#/definitions/string
default: 1s
enum:
- 1s
- 2s
required:
- compatible
- reg
- '#sound-dai-cells'
- interrupts
- vdd-1p8-supply
- vdd-io-supply
oneOf:
- required:
- powerdown-gpios
- required:
- reset-gpios
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
speaker@c {
compatible = "qcom,wsa8855";
reg = <0x0c>;
#sound-dai-cells = <0>;
powerdown-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>;
interrupt-parent = <&tlmm>;
interrupts = <77 IRQ_TYPE_EDGE_FALLING>;
vdd-1p8-supply = <&vreg_l2g_1p8>;
vdd-io-supply = <&vreg_l1g_1p2>;
qcom,battery-config = "1s";
};
};
...

View File

@@ -19,7 +19,7 @@ properties:
realtek,power-up-delay-ms:
description: Set a delay time for flush work to be completed,
this vlaue is adjustable depending on platform.
this value is adjustable depending on platform.
maxItems: 1
required:

View File

@@ -23,9 +23,9 @@ allOf:
then:
properties:
clocks:
minItems: 7
minItems: 6
clock-names:
minItems: 7
minItems: 6
else:
properties:
clocks:
@@ -43,26 +43,50 @@ properties:
maxItems: 1
clocks:
minItems: 4
items:
- description: clock for I2S sysclk
- description: clock for I2S bclk
- description: clock for I2S bus
- description: clock for I2S controller
- description: clock for I2S sysclk divider
- description: clock for I2S common sysclk
- description: clock for I2S common bclk
oneOf:
- items:
- description: clock for I2S sysclk
- description: clock for I2S bclk
- description: clock for I2S bus
- description: clock for I2S controller
- items:
- description: clock for I2S sysclk
- description: clock for I2S bclk
- description: clock for I2S bus
- description: clock for I2S controller
- description: clock for I2S common sysclk
- description: clock for I2S common bclk
- items:
- description: clock for I2S sysclk
- description: clock for I2S bclk
- description: clock for I2S bus
- description: clock for I2S controller
- description: clock for I2S sysclk divider
- description: clock for I2S common sysclk
- description: clock for I2S common bclk
clock-names:
minItems: 4
items:
- const: sysclk
- const: bclk
- const: bus
- const: func
- const: sysclk_div
- const: c_sysclk
- const: c_bclk
oneOf:
- items:
- const: sysclk
- const: bclk
- const: bus
- const: func
- items:
- const: sysclk
- const: bclk
- const: bus
- const: func
- const: c_sysclk
- const: c_bclk
- items:
- const: sysclk
- const: bclk
- const: bus
- const: func
- const: sysclk_div
- const: c_sysclk
- const: c_bclk
dmas:
minItems: 1

View File

@@ -73,7 +73,7 @@ Optional properties:
- st,odd-pwm-speed-mode:
If present, PWM speed mode run on odd speed mode (341.3 kHz) on all
channels. If not present, normal PWM spped mode (384 kHz) will be used.
channels. If not present, normal PWM speed mode (384 kHz) will be used.
- st,invalid-input-detect-mute:
If present, automatic invalid input detect mute is enabled.

View File

@@ -0,0 +1,58 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/ti,omap4-dmic.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments OMAP4+ Digital Microphone Module
maintainers:
- Peter Ujfalusi <peter.ujfalusi@ti.com>
properties:
compatible:
const: ti,omap4-dmic
reg:
items:
- description: MPU access base address
- description: L3 interconnect address
reg-names:
items:
- const: mpu
- const: dma
interrupts:
maxItems: 1
dmas:
maxItems: 1
dma-names:
items:
- const: up_link
required:
- compatible
- reg
- reg-names
- interrupts
- dmas
- dma-names
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
dmic@0 {
compatible = "ti,omap4-dmic";
reg = <0x0 0x7f>, /* MPU private access */
<0x4902e000 0x7f>; /* L3 Interconnect */
reg-names = "mpu", "dma";
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&sdma 67>;
dma-names = "up_link";
};

View File

@@ -24,6 +24,10 @@ properties:
description:
a GPIO spec for the MUTE pin.
port:
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
required:
- compatible
- wlf,mute-gpios

View File

@@ -152,6 +152,10 @@
#define LPI_MI2S_TX_4 146
#define SENARY_MI2S_RX 147
#define SENARY_MI2S_TX 148
#define LPI_MI2S_RX_5 149
#define LPI_MI2S_TX_5 150
#define LPI_MI2S_RX_6 151
#define LPI_MI2S_TX_6 152
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2
@@ -236,8 +240,7 @@
#define LPASS_HW_AVTIMER_VOTE 101
#define LPASS_HW_MACRO_VOTE 102
#define LPASS_HW_DCODEC_VOTE 103
#define Q6AFE_MAX_CLK_ID 104
#define LPASS_HW_LPR_VOTE 104
#define LPASS_CLK_ATTRIBUTE_INVALID 0x0
#define LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1

View File

@@ -1,42 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/**
* omap-twl4030.h - ASoC machine driver for TI SoC based boards with twl4030
* codec, header.
*
* Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com
* All rights reserved.
*
* Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
*/
#ifndef _OMAP_TWL4030_H_
#define _OMAP_TWL4030_H_
/* To select if only one channel is connected in a stereo port */
#define OMAP_TWL4030_LEFT (1 << 0)
#define OMAP_TWL4030_RIGHT (1 << 1)
struct omap_tw4030_pdata {
const char *card_name;
/* Voice port is connected to McBSP3 */
bool voice_connected;
/* The driver will parse the connection flags if this flag is set */
bool custom_routing;
/* Flags to indicate connected audio ports. */
u8 has_hs;
u8 has_hf;
u8 has_predriv;
u8 has_carkit;
bool has_ear;
bool has_mainmic;
bool has_submic;
bool has_hsmic;
bool has_carkitmic;
bool has_digimic0;
bool has_digimic1;
u8 has_linein;
};
#endif /* _OMAP_TWL4030_H_ */

621
include/sound/aw88399.h Normal file
View File

@@ -0,0 +1,621 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* linux/sound/aw88399.h -- Platform data for AW88399
*
* Copyright (c) 2023 AWINIC Technology CO., LTD
*
* Author: Weidong Wang <wangweidong.a@awinic.com>
*/
#ifndef __SOUND_AW88399_H
#define __SOUND_AW88399_H
#include <linux/mutex.h>
#include <linux/workqueue.h>
/* registers list */
#define AW88399_ID_REG (0x00)
#define AW88399_SYSST_REG (0x01)
#define AW88399_SYSINT_REG (0x02)
#define AW88399_SYSINTM_REG (0x03)
#define AW88399_SYSCTRL_REG (0x04)
#define AW88399_SYSCTRL2_REG (0x05)
#define AW88399_I2SCTRL1_REG (0x06)
#define AW88399_I2SCTRL2_REG (0x07)
#define AW88399_I2SCTRL3_REG (0x08)
#define AW88399_DACCFG1_REG (0x09)
#define AW88399_DACCFG2_REG (0x0A)
#define AW88399_DACCFG3_REG (0x0B)
#define AW88399_DACCFG4_REG (0x0C)
#define AW88399_DACCFG5_REG (0x0D)
#define AW88399_DACCFG6_REG (0x0E)
#define AW88399_DACCFG7_REG (0x0F)
#define AW88399_MPDCFG1_REG (0x10)
#define AW88399_MPDCFG2_REG (0x11)
#define AW88399_MPDCFG3_REG (0x12)
#define AW88399_MPDCFG4_REG (0x13)
#define AW88399_PWMCTRL1_REG (0x14)
#define AW88399_PWMCTRL2_REG (0x15)
#define AW88399_PWMCTRL3_REG (0x16)
#define AW88399_I2SCFG1_REG (0x17)
#define AW88399_DBGCTRL_REG (0x18)
#define AW88399_HAGCST_REG (0x20)
#define AW88399_VBAT_REG (0x21)
#define AW88399_TEMP_REG (0x22)
#define AW88399_PVDD_REG (0x23)
#define AW88399_ISNDAT_REG (0x24)
#define AW88399_VSNDAT_REG (0x25)
#define AW88399_I2SINT_REG (0x26)
#define AW88399_I2SCAPCNT_REG (0x27)
#define AW88399_ANASTA1_REG (0x28)
#define AW88399_ANASTA2_REG (0x29)
#define AW88399_ANASTA3_REG (0x2A)
#define AW88399_TESTDET_REG (0x2B)
#define AW88399_DSMCFG1_REG (0x30)
#define AW88399_DSMCFG2_REG (0x31)
#define AW88399_DSMCFG3_REG (0x32)
#define AW88399_DSMCFG4_REG (0x33)
#define AW88399_DSMCFG5_REG (0x34)
#define AW88399_DSMCFG6_REG (0x35)
#define AW88399_DSMCFG7_REG (0x36)
#define AW88399_DSMCFG8_REG (0x37)
#define AW88399_TESTIN_REG (0x38)
#define AW88399_TESTOUT_REG (0x39)
#define AW88399_MEMTEST_REG (0x3A)
#define AW88399_VSNCTRL1_REG (0x3B)
#define AW88399_ISNCTRL1_REG (0x3C)
#define AW88399_ISNCTRL2_REG (0x3D)
#define AW88399_DSPMADD_REG (0x40)
#define AW88399_DSPMDAT_REG (0x41)
#define AW88399_WDT_REG (0x42)
#define AW88399_ACR1_REG (0x43)
#define AW88399_ACR2_REG (0x44)
#define AW88399_ASR1_REG (0x45)
#define AW88399_ASR2_REG (0x46)
#define AW88399_DSPCFG_REG (0x47)
#define AW88399_ASR3_REG (0x48)
#define AW88399_ASR4_REG (0x49)
#define AW88399_DSPVCALB_REG (0x4A)
#define AW88399_CRCCTRL_REG (0x4B)
#define AW88399_DSPDBG1_REG (0x4C)
#define AW88399_DSPDBG2_REG (0x4D)
#define AW88399_DSPDBG3_REG (0x4E)
#define AW88399_PLLCTRL1_REG (0x50)
#define AW88399_PLLCTRL2_REG (0x51)
#define AW88399_PLLCTRL3_REG (0x52)
#define AW88399_CDACTRL1_REG (0x53)
#define AW88399_CDACTRL2_REG (0x54)
#define AW88399_CDACTRL3_REG (0x55)
#define AW88399_SADCCTRL1_REG (0x56)
#define AW88399_SADCCTRL2_REG (0x57)
#define AW88399_BOPCTRL1_REG (0x58)
#define AW88399_BOPCTRL2_REG (0x5A)
#define AW88399_BOPCTRL3_REG (0x5B)
#define AW88399_BOPCTRL4_REG (0x5C)
#define AW88399_BOPCTRL5_REG (0x5D)
#define AW88399_BOPCTRL6_REG (0x5E)
#define AW88399_BOPCTRL7_REG (0x5F)
#define AW88399_BSTCTRL1_REG (0x60)
#define AW88399_BSTCTRL2_REG (0x61)
#define AW88399_BSTCTRL3_REG (0x62)
#define AW88399_BSTCTRL4_REG (0x63)
#define AW88399_BSTCTRL5_REG (0x64)
#define AW88399_BSTCTRL6_REG (0x65)
#define AW88399_BSTCTRL7_REG (0x66)
#define AW88399_BSTCTRL8_REG (0x67)
#define AW88399_BSTCTRL9_REG (0x68)
#define AW88399_BSTCTRL10_REG (0x69)
#define AW88399_CPCTRL_REG (0x6A)
#define AW88399_EFWH_REG (0x6C)
#define AW88399_EFWM2_REG (0x6D)
#define AW88399_EFWM1_REG (0x6E)
#define AW88399_EFWL_REG (0x6F)
#define AW88399_TESTCTRL1_REG (0x70)
#define AW88399_TESTCTRL2_REG (0x71)
#define AW88399_EFCTRL1_REG (0x72)
#define AW88399_EFCTRL2_REG (0x73)
#define AW88399_EFRH4_REG (0x74)
#define AW88399_EFRH3_REG (0x75)
#define AW88399_EFRH2_REG (0x76)
#define AW88399_EFRH1_REG (0x77)
#define AW88399_EFRL4_REG (0x78)
#define AW88399_EFRL3_REG (0x79)
#define AW88399_EFRL2_REG (0x7A)
#define AW88399_EFRL1_REG (0x7B)
#define AW88399_TM_REG (0x7C)
#define AW88399_TM2_REG (0x7D)
#define AW88399_REG_MAX (0x7E)
#define AW88399_MUTE_VOL (1023)
#define AW88399_DSP_CFG_ADDR (0x9B00)
#define AW88399_DSP_REG_CFG_ADPZ_RA (0x9B68)
#define AW88399_DSP_FW_ADDR (0x8980)
#define AW88399_DSP_ROM_CHECK_ADDR (0x1F40)
#define AW88399_DSP_ROM_CHECK_DATA (0x4638)
#define AW88399_CALI_RE_HBITS_MASK (~(0xFFFF0000))
#define AW88399_CALI_RE_HBITS_SHIFT (16)
#define AW88399_CALI_RE_LBITS_MASK (~(0xFFFF))
#define AW88399_CALI_RE_LBITS_SHIFT (0)
#define AW88399_I2STXEN_START_BIT (9)
#define AW88399_I2STXEN_BITS_LEN (1)
#define AW88399_I2STXEN_MASK \
(~(((1<<AW88399_I2STXEN_BITS_LEN)-1) << AW88399_I2STXEN_START_BIT))
#define AW88399_I2STXEN_DISABLE (0)
#define AW88399_I2STXEN_DISABLE_VALUE \
(AW88399_I2STXEN_DISABLE << AW88399_I2STXEN_START_BIT)
#define AW88399_I2STXEN_ENABLE (1)
#define AW88399_I2STXEN_ENABLE_VALUE \
(AW88399_I2STXEN_ENABLE << AW88399_I2STXEN_START_BIT)
#define AW88399_VOL_START_BIT (0)
#define AW88399_VOL_BITS_LEN (10)
#define AW88399_VOL_MASK \
(~(((1<<AW88399_VOL_BITS_LEN)-1) << AW88399_VOL_START_BIT))
#define AW88399_PWDN_START_BIT (0)
#define AW88399_PWDN_BITS_LEN (1)
#define AW88399_PWDN_MASK \
(~(((1<<AW88399_PWDN_BITS_LEN)-1) << AW88399_PWDN_START_BIT))
#define AW88399_PWDN_POWER_DOWN (1)
#define AW88399_PWDN_POWER_DOWN_VALUE \
(AW88399_PWDN_POWER_DOWN << AW88399_PWDN_START_BIT)
#define AW88399_PWDN_WORKING (0)
#define AW88399_PWDN_WORKING_VALUE \
(AW88399_PWDN_WORKING << AW88399_PWDN_START_BIT)
#define AW88399_DSPBY_START_BIT (2)
#define AW88399_DSPBY_BITS_LEN (1)
#define AW88399_DSPBY_MASK \
(~(((1<<AW88399_DSPBY_BITS_LEN)-1) << AW88399_DSPBY_START_BIT))
#define AW88399_DSPBY_WORKING (0)
#define AW88399_DSPBY_WORKING_VALUE \
(AW88399_DSPBY_WORKING << AW88399_DSPBY_START_BIT)
#define AW88399_DSPBY_BYPASS (1)
#define AW88399_DSPBY_BYPASS_VALUE \
(AW88399_DSPBY_BYPASS << AW88399_DSPBY_START_BIT)
#define AW88399_MEM_CLKSEL_START_BIT (3)
#define AW88399_MEM_CLKSEL_BITS_LEN (1)
#define AW88399_MEM_CLKSEL_MASK \
(~(((1<<AW88399_MEM_CLKSEL_BITS_LEN)-1) << AW88399_MEM_CLKSEL_START_BIT))
#define AW88399_MEM_CLKSEL_OSCCLK (0)
#define AW88399_MEM_CLKSEL_OSCCLK_VALUE \
(AW88399_MEM_CLKSEL_OSCCLK << AW88399_MEM_CLKSEL_START_BIT)
#define AW88399_MEM_CLKSEL_DAPHCLK (1)
#define AW88399_MEM_CLKSEL_DAPHCLK_VALUE \
(AW88399_MEM_CLKSEL_DAPHCLK << AW88399_MEM_CLKSEL_START_BIT)
#define AW88399_DITHER_EN_START_BIT (15)
#define AW88399_DITHER_EN_BITS_LEN (1)
#define AW88399_DITHER_EN_MASK \
(~(((1<<AW88399_DITHER_EN_BITS_LEN)-1) << AW88399_DITHER_EN_START_BIT))
#define AW88399_DITHER_EN_DISABLE (0)
#define AW88399_DITHER_EN_DISABLE_VALUE \
(AW88399_DITHER_EN_DISABLE << AW88399_DITHER_EN_START_BIT)
#define AW88399_DITHER_EN_ENABLE (1)
#define AW88399_DITHER_EN_ENABLE_VALUE \
(AW88399_DITHER_EN_ENABLE << AW88399_DITHER_EN_START_BIT)
#define AW88399_HMUTE_START_BIT (8)
#define AW88399_HMUTE_BITS_LEN (1)
#define AW88399_HMUTE_MASK \
(~(((1<<AW88399_HMUTE_BITS_LEN)-1) << AW88399_HMUTE_START_BIT))
#define AW88399_HMUTE_DISABLE (0)
#define AW88399_HMUTE_DISABLE_VALUE \
(AW88399_HMUTE_DISABLE << AW88399_HMUTE_START_BIT)
#define AW88399_HMUTE_ENABLE (1)
#define AW88399_HMUTE_ENABLE_VALUE \
(AW88399_HMUTE_ENABLE << AW88399_HMUTE_START_BIT)
#define AW88399_EF_DBMD_START_BIT (2)
#define AW88399_EF_DBMD_BITS_LEN (1)
#define AW88399_EF_DBMD_MASK \
(~(((1<<AW88399_EF_DBMD_BITS_LEN)-1) << AW88399_EF_DBMD_START_BIT))
#define AW88399_EF_DBMD_OR (1)
#define AW88399_EF_DBMD_OR_VALUE \
(AW88399_EF_DBMD_OR << AW88399_EF_DBMD_START_BIT)
#define AW88399_VDSEL_START_BIT (5)
#define AW88399_VDSEL_BITS_LEN (1)
#define AW88399_VDSEL_MASK \
(~(((1<<AW88399_VDSEL_BITS_LEN)-1) << AW88399_VDSEL_START_BIT))
#define AW88399_EF_ISN_GESLP_H_START_BIT (0)
#define AW88399_EF_ISN_GESLP_H_BITS_LEN (10)
#define AW88399_EF_ISN_GESLP_H_MASK \
(~(((1<<AW88399_EF_ISN_GESLP_H_BITS_LEN)-1) << AW88399_EF_ISN_GESLP_H_START_BIT))
/* EF_VSN_GESLP_H bit 9:0 (EFRH3 0x75) */
#define AW88399_EF_VSN_GESLP_H_START_BIT (0)
#define AW88399_EF_VSN_GESLP_H_BITS_LEN (10)
#define AW88399_EF_VSN_GESLP_H_MASK \
(~(((1<<AW88399_EF_VSN_GESLP_H_BITS_LEN)-1) << AW88399_EF_VSN_GESLP_H_START_BIT))
#define AW88399_EF_ISN_GESLP_L_START_BIT (0)
#define AW88399_EF_ISN_GESLP_L_BITS_LEN (10)
#define AW88399_EF_ISN_GESLP_L_MASK \
(~(((1<<AW88399_EF_ISN_GESLP_L_BITS_LEN)-1) << AW88399_EF_ISN_GESLP_L_START_BIT))
/* EF_VSN_GESLP_L bit 9:0 (EFRL3 0x79) */
#define AW88399_EF_VSN_GESLP_L_START_BIT (0)
#define AW88399_EF_VSN_GESLP_L_BITS_LEN (10)
#define AW88399_EF_VSN_GESLP_L_MASK \
(~(((1<<AW88399_EF_VSN_GESLP_L_BITS_LEN)-1) << AW88399_EF_VSN_GESLP_L_START_BIT))
#define AW88399_INTERNAL_VSN_TRIM_H_START_BIT (9)
#define AW88399_INTERNAL_VSN_TRIM_H_BITS_LEN (6)
#define AW88399_INTERNAL_VSN_TRIM_H_MASK \
(~(((1<<AW88399_INTERNAL_VSN_TRIM_H_BITS_LEN)-1) << AW88399_INTERNAL_VSN_TRIM_H_START_BIT))
#define AW88399_INTERNAL_VSN_TRIM_L_START_BIT (9)
#define AW88399_INTERNAL_VSN_TRIM_L_BITS_LEN (6)
#define AW88399_INTERNAL_VSN_TRIM_L_MASK \
(~(((1<<AW88399_INTERNAL_VSN_TRIM_L_BITS_LEN)-1) << AW88399_INTERNAL_VSN_TRIM_L_START_BIT))
#define AW88399_RCV_MODE_START_BIT (7)
#define AW88399_RCV_MODE_BITS_LEN (1)
#define AW88399_RCV_MODE_MASK \
(~(((1<<AW88399_RCV_MODE_BITS_LEN)-1) << AW88399_RCV_MODE_START_BIT))
#define AW88399_CLKI_START_BIT (4)
#define AW88399_NOCLKI_START_BIT (5)
#define AW88399_PLLI_START_BIT (0)
#define AW88399_PLLI_INT_VALUE (1)
#define AW88399_PLLI_INT_INTERRUPT \
(AW88399_PLLI_INT_VALUE << AW88399_PLLI_START_BIT)
#define AW88399_CLKI_INT_VALUE (1)
#define AW88399_CLKI_INT_INTERRUPT \
(AW88399_CLKI_INT_VALUE << AW88399_CLKI_START_BIT)
#define AW88399_NOCLKI_INT_VALUE (1)
#define AW88399_NOCLKI_INT_INTERRUPT \
(AW88399_NOCLKI_INT_VALUE << AW88399_NOCLKI_START_BIT)
#define AW88399_BIT_SYSINT_CHECK \
(AW88399_PLLI_INT_INTERRUPT | \
AW88399_CLKI_INT_INTERRUPT | \
AW88399_NOCLKI_INT_INTERRUPT)
#define AW88399_CRC_CHECK_START_BIT (12)
#define AW88399_CRC_CHECK_BITS_LEN (3)
#define AW88399_CRC_CHECK_BITS_MASK \
(~(((1<<AW88399_CRC_CHECK_BITS_LEN)-1) << AW88399_CRC_CHECK_START_BIT))
#define AW88399_RCV_MODE_RECEIVER (1)
#define AW88399_RCV_MODE_RECEIVER_VALUE \
(AW88399_RCV_MODE_RECEIVER << AW88399_RCV_MODE_START_BIT)
#define AW88399_AMPPD_START_BIT (1)
#define AW88399_AMPPD_BITS_LEN (1)
#define AW88399_AMPPD_MASK \
(~(((1<<AW88399_AMPPD_BITS_LEN)-1) << AW88399_AMPPD_START_BIT))
#define AW88399_AMPPD_WORKING (0)
#define AW88399_AMPPD_WORKING_VALUE \
(AW88399_AMPPD_WORKING << AW88399_AMPPD_START_BIT)
#define AW88399_AMPPD_POWER_DOWN (1)
#define AW88399_AMPPD_POWER_DOWN_VALUE \
(AW88399_AMPPD_POWER_DOWN << AW88399_AMPPD_START_BIT)
#define AW88399_RAM_CG_BYP_START_BIT (0)
#define AW88399_RAM_CG_BYP_BITS_LEN (1)
#define AW88399_RAM_CG_BYP_MASK \
(~(((1<<AW88399_RAM_CG_BYP_BITS_LEN)-1) << AW88399_RAM_CG_BYP_START_BIT))
#define AW88399_RAM_CG_BYP_WORK (0)
#define AW88399_RAM_CG_BYP_WORK_VALUE \
(AW88399_RAM_CG_BYP_WORK << AW88399_RAM_CG_BYP_START_BIT)
#define AW88399_RAM_CG_BYP_BYPASS (1)
#define AW88399_RAM_CG_BYP_BYPASS_VALUE \
(AW88399_RAM_CG_BYP_BYPASS << AW88399_RAM_CG_BYP_START_BIT)
#define AW88399_CRC_END_ADDR_START_BIT (0)
#define AW88399_CRC_END_ADDR_BITS_LEN (12)
#define AW88399_CRC_END_ADDR_MASK \
(~(((1<<AW88399_CRC_END_ADDR_BITS_LEN)-1) << AW88399_CRC_END_ADDR_START_BIT))
#define AW88399_CRC_CODE_EN_START_BIT (13)
#define AW88399_CRC_CODE_EN_BITS_LEN (1)
#define AW88399_CRC_CODE_EN_MASK \
(~(((1<<AW88399_CRC_CODE_EN_BITS_LEN)-1) << AW88399_CRC_CODE_EN_START_BIT))
#define AW88399_CRC_CODE_EN_DISABLE (0)
#define AW88399_CRC_CODE_EN_DISABLE_VALUE \
(AW88399_CRC_CODE_EN_DISABLE << AW88399_CRC_CODE_EN_START_BIT)
#define AW88399_CRC_CODE_EN_ENABLE (1)
#define AW88399_CRC_CODE_EN_ENABLE_VALUE \
(AW88399_CRC_CODE_EN_ENABLE << AW88399_CRC_CODE_EN_START_BIT)
#define AW88399_CRC_CFG_EN_START_BIT (12)
#define AW88399_CRC_CFG_EN_BITS_LEN (1)
#define AW88399_CRC_CFG_EN_MASK \
(~(((1<<AW88399_CRC_CFG_EN_BITS_LEN)-1) << AW88399_CRC_CFG_EN_START_BIT))
#define AW88399_CRC_CFG_EN_DISABLE (0)
#define AW88399_CRC_CFG_EN_DISABLE_VALUE \
(AW88399_CRC_CFG_EN_DISABLE << AW88399_CRC_CFG_EN_START_BIT)
#define AW88399_CRC_CFG_EN_ENABLE (1)
#define AW88399_CRC_CFG_EN_ENABLE_VALUE \
(AW88399_CRC_CFG_EN_ENABLE << AW88399_CRC_CFG_EN_START_BIT)
#define AW88399_OCDS_START_BIT (3)
#define AW88399_OCDS_OC (1)
#define AW88399_OCDS_OC_VALUE \
(AW88399_OCDS_OC << AW88399_OCDS_START_BIT)
#define AW88399_NOCLKS_START_BIT (5)
#define AW88399_NOCLKS_NO_CLOCK (1)
#define AW88399_NOCLKS_NO_CLOCK_VALUE \
(AW88399_NOCLKS_NO_CLOCK << AW88399_NOCLKS_START_BIT)
#define AW88399_SWS_START_BIT (8)
#define AW88399_SWS_SWITCHING (1)
#define AW88399_SWS_SWITCHING_VALUE \
(AW88399_SWS_SWITCHING << AW88399_SWS_START_BIT)
#define AW88399_BSTS_START_BIT (9)
#define AW88399_BSTS_FINISHED (1)
#define AW88399_BSTS_FINISHED_VALUE \
(AW88399_BSTS_FINISHED << AW88399_BSTS_START_BIT)
#define AW88399_UVLS_START_BIT (14)
#define AW88399_UVLS_NORMAL (0)
#define AW88399_UVLS_NORMAL_VALUE \
(AW88399_UVLS_NORMAL << AW88399_UVLS_START_BIT)
#define AW88399_BSTOCS_START_BIT (11)
#define AW88399_BSTOCS_OVER_CURRENT (1)
#define AW88399_BSTOCS_OVER_CURRENT_VALUE \
(AW88399_BSTOCS_OVER_CURRENT << AW88399_BSTOCS_START_BIT)
#define AW88399_OTHS_START_BIT (1)
#define AW88399_OTHS_OT (1)
#define AW88399_OTHS_OT_VALUE \
(AW88399_OTHS_OT << AW88399_OTHS_START_BIT)
#define AW88399_PLLS_START_BIT (0)
#define AW88399_PLLS_LOCKED (1)
#define AW88399_PLLS_LOCKED_VALUE \
(AW88399_PLLS_LOCKED << AW88399_PLLS_START_BIT)
#define AW88399_CLKS_START_BIT (4)
#define AW88399_CLKS_STABLE (1)
#define AW88399_CLKS_STABLE_VALUE \
(AW88399_CLKS_STABLE << AW88399_CLKS_START_BIT)
#define AW88399_BIT_PLL_CHECK \
(AW88399_CLKS_STABLE_VALUE | \
AW88399_PLLS_LOCKED_VALUE)
#define AW88399_BIT_SYSST_CHECK_MASK \
(~(AW88399_UVLS_NORMAL_VALUE | \
AW88399_BSTOCS_OVER_CURRENT_VALUE | \
AW88399_BSTS_FINISHED_VALUE | \
AW88399_SWS_SWITCHING_VALUE | \
AW88399_NOCLKS_NO_CLOCK_VALUE | \
AW88399_CLKS_STABLE_VALUE | \
AW88399_OCDS_OC_VALUE | \
AW88399_OTHS_OT_VALUE | \
AW88399_PLLS_LOCKED_VALUE))
#define AW88399_BIT_SYSST_NOSWS_CHECK \
(AW88399_BSTS_FINISHED_VALUE | \
AW88399_CLKS_STABLE_VALUE | \
AW88399_PLLS_LOCKED_VALUE)
#define AW88399_BIT_SYSST_SWS_CHECK \
(AW88399_BSTS_FINISHED_VALUE | \
AW88399_CLKS_STABLE_VALUE | \
AW88399_PLLS_LOCKED_VALUE | \
AW88399_SWS_SWITCHING_VALUE)
#define AW88399_CCO_MUX_START_BIT (14)
#define AW88399_CCO_MUX_BITS_LEN (1)
#define AW88399_CCO_MUX_MASK \
(~(((1<<AW88399_CCO_MUX_BITS_LEN)-1) << AW88399_CCO_MUX_START_BIT))
#define AW88399_CCO_MUX_DIVIDED (0)
#define AW88399_CCO_MUX_DIVIDED_VALUE \
(AW88399_CCO_MUX_DIVIDED << AW88399_CCO_MUX_START_BIT)
#define AW88399_CCO_MUX_BYPASS (1)
#define AW88399_CCO_MUX_BYPASS_VALUE \
(AW88399_CCO_MUX_BYPASS << AW88399_CCO_MUX_START_BIT)
#define AW88399_NOISE_GATE_EN_START_BIT (13)
#define AW88399_NOISE_GATE_EN_BITS_LEN (1)
#define AW88399_NOISE_GATE_EN_MASK \
(~(((1<<AW88399_NOISE_GATE_EN_BITS_LEN)-1) << AW88399_NOISE_GATE_EN_START_BIT))
#define AW88399_WDT_CNT_START_BIT (0)
#define AW88399_WDT_CNT_BITS_LEN (8)
#define AW88399_WDT_CNT_MASK \
(~(((1<<AW88399_WDT_CNT_BITS_LEN)-1) << AW88399_WDT_CNT_START_BIT))
#define AW88399_REABS_START_BIT (3)
#define AW88399_REABS_BITS_LEN (1)
#define AW88399_REABS_MASK \
(~(((1<<AW88399_REABS_BITS_LEN)-1) << AW88399_REABS_START_BIT))
#define AW88399_DSP_VOL_START_BIT (8)
#define AW88399_DSP_VOL_BITS_LEN (8)
#define AW88399_DSP_VOL_MASK \
(~(((1<<AW88399_DSP_VOL_BITS_LEN)-1) << AW88399_DSP_VOL_START_BIT))
#define AW883XX_DSP_NG_EN_START (13)
#define AW883XX_DSP_NG_EN_LEN (1)
#define AW883XX_DSP_NG_EN_MASK \
(~(((1 << AW883XX_DSP_NG_EN_LEN) - 1) << AW883XX_DSP_NG_EN_START))
#define AW883XX_DSP_NG_EN_DISABLE (0)
#define AW883XX_DSP_NG_EN_DISABLE_VALUE \
(AW883XX_DSP_NG_EN_DISABLE << AW883XX_DSP_NG_EN_START)
#define AW88399_VOLUME_STEP_DB (64)
#define AW88399_VOL_DEFAULT_VALUE (0)
#define AW88399_DSP_ODD_NUM_BIT_TEST (0x5555)
#define AW88399_EF_ISN_GESLP_SIGN_MASK (~(1 << 9))
#define AW88399_EF_ISN_GESLP_SIGN_NEG (0xfe00)
#define AW88399_EF_VSN_GESLP_SIGN_MASK (~(1 << 9))
#define AW88399_EF_VSN_GESLP_SIGN_NEG (0xfe00)
#define AW88399_TEM4_SIGN_MASK (~(1 << 5))
#define AW88399_TEM4_SIGN_NEG (0xffc0)
#define AW88399_ICABLK_FACTOR (1)
#define AW88399_VCABLK_FACTOR (1)
#define AW88399_VCABLK_DAC_FACTOR (2)
#define AW88399_VCALB_ADJ_FACTOR (12)
#define AW88399_VCALB_ACCURACY (1 << 12)
#define AW88399_ISCAL_FACTOR (3125)
#define AW88399_VSCAL_FACTOR (18875)
#define AW88399_ISCAL_DAC_FACTOR (3125)
#define AW88399_VSCAL_DAC_FACTOR (12600)
#define AW88399_CABL_BASE_VALUE (1000)
#define AW88399_DEV_DEFAULT_CH (0)
#define AW88399_DEV_DSP_CHECK_MAX (5)
#define AW88399_MAX_RAM_WRITE_BYTE_SIZE (128)
#define AW88399_DSP_RE_SHIFT (12)
#define AW88399_CALI_RE_MAX (15000)
#define AW88399_CALI_RE_MIN (4000)
#define AW_FW_ADDR_LEN (4)
#define AW88399_DSP_RE_TO_SHOW_RE(re, shift) (((re) * (1000)) >> (shift))
#define AW88399_SHOW_RE_TO_DSP_RE(re, shift) (((re) << shift) / (1000))
#define AW88399_CRC_CHECK_PASS_VAL (0x4)
#define AW88399_CRC_CFG_BASE_ADDR (0xD80)
#define AW88399_CRC_FW_BASE_ADDR (0x4C0)
#define AW88399_ACF_FILE "aw88399_acf.bin"
#define AW88399_DEV_SYSST_CHECK_MAX (10)
#define AW88399_CHIP_ID 0x2183
#define AW88399_START_RETRIES (5)
#define AW88399_START_WORK_DELAY_MS (0)
enum {
AW_EF_AND_CHECK = 0,
AW_EF_OR_CHECK,
};
enum {
AW88399_DEV_VDSEL_DAC = 0,
AW88399_DEV_VDSEL_VSENSE = 32,
};
enum {
AW88399_DSP_CRC_NA = 0,
AW88399_DSP_CRC_OK = 1,
};
enum {
AW88399_DSP_FW_UPDATE_OFF = 0,
AW88399_DSP_FW_UPDATE_ON = 1,
};
enum {
AW88399_FORCE_UPDATE_OFF = 0,
AW88399_FORCE_UPDATE_ON = 1,
};
enum {
AW88399_1000_US = 1000,
AW88399_2000_US = 2000,
AW88399_3000_US = 3000,
AW88399_4000_US = 4000,
};
enum AW88399_DEV_STATUS {
AW88399_DEV_PW_OFF = 0,
AW88399_DEV_PW_ON,
};
enum AW88399_DEV_FW_STATUS {
AW88399_DEV_FW_FAILED = 0,
AW88399_DEV_FW_OK,
};
enum AW88399_DEV_MEMCLK {
AW88399_DEV_MEMCLK_OSC = 0,
AW88399_DEV_MEMCLK_PLL = 1,
};
enum AW88399_DEV_DSP_CFG {
AW88399_DEV_DSP_WORK = 0,
AW88399_DEV_DSP_BYPASS = 1,
};
enum {
AW88399_NOT_RCV_MODE = 0,
AW88399_RCV_MODE = 1,
};
enum {
AW88399_SYNC_START = 0,
AW88399_ASYNC_START,
};
struct aw_device;
struct aw_container;
struct aw_cali_desc;
struct gpio_desc;
struct i2c_client;
struct regmap;
struct aw88399 {
struct aw_device *aw_pa;
struct mutex lock;
struct gpio_desc *reset_gpio;
struct delayed_work start_work;
struct regmap *regmap;
struct aw_container *aw_cfg;
unsigned int check_val;
unsigned int crc_init_val;
unsigned int vcalb_init_val;
unsigned int dither_st;
bool bsts_unreliable;
bool fw_needs_reload;
};
int aw_dev_check_syspll(struct aw_device *aw_dev);
void aw_dev_dsp_enable(struct aw_device *aw_dev, bool is_enable);
int aw_dev_get_dsp_status(struct aw_device *aw_dev);
int aw_dev_set_volume(struct aw_device *aw_dev, unsigned int value);
int aw_dev_update_cali_re(struct aw_cali_desc *cali_desc);
int aw88399_dev_get_prof_name(struct aw_device *aw_dev, int index, char **prof_name);
void aw88399_dev_mute(struct aw_device *aw_dev, bool is_mute);
void aw88399_dev_set_channel(struct aw88399 *aw88399, int channel);
void aw88399_hw_reset(struct aw88399 *aw88399);
int aw88399_init(struct aw88399 *aw88399, struct i2c_client *i2c, struct regmap *regmap);
extern const struct regmap_config aw88399_remap_config;
int aw88399_request_firmware_file(struct aw88399 *aw88399);
void aw88399_start(struct aw88399 *aw88399, bool sync_start);
void aw88399_startup_work(struct work_struct *work);
int aw88399_stop(struct aw_device *aw_dev);
#endif /* __SOUND_AW88399_H */

View File

@@ -9,6 +9,22 @@
struct hdac_bus;
struct hdac_ext_link;
/**
* enum hda_bus_ml_link_type - mlink link type, used by SOF link DMA
* allocator constraints (see struct sof_intel_hda_dev).
*
* @HDA_BUS_ML_LINK_HDA: non-alt link, i.e. HDA codec or iDisp
* @HDA_BUS_ML_LINK_SDW: alt link, SoundWire
* @HDA_BUS_ML_LINK_UAOL: alt link, USB Audio Offload
* @HDA_BUS_ML_LINK_OTHER: alt link, SSP or DMIC
*/
enum hda_bus_ml_link_type {
HDA_BUS_ML_LINK_HDA,
HDA_BUS_ML_LINK_SDW,
HDA_BUS_ML_LINK_UAOL,
HDA_BUS_ML_LINK_OTHER,
};
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_MLINK)
int hda_bus_ml_init(struct hdac_bus *bus);
@@ -49,11 +65,12 @@ int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num);
int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
int channel_mask, int stream_id, int dir);
void hda_bus_ml_put_all(struct hdac_bus *bus);
void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
int hda_bus_ml_resume(struct hdac_bus *bus);
int hda_bus_ml_suspend(struct hdac_bus *bus);
enum hda_bus_ml_link_type hda_bus_ml_link_get_type(struct hdac_ext_link *hlink);
struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus);
struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus);
struct hdac_ext_link *hdac_bus_eml_sdw_get_hlink(struct hdac_bus *bus);
@@ -169,11 +186,13 @@ hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
return 0;
}
static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { }
static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; }
static inline int hda_bus_ml_suspend(struct hdac_bus *bus) { return 0; }
static inline enum hda_bus_ml_link_type
hda_bus_ml_link_get_type(struct hdac_ext_link *hlink) { return HDA_BUS_ML_LINK_HDA; }
static inline struct hdac_ext_link *
hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus) { return NULL; }

View File

@@ -25,6 +25,8 @@ struct snd_soc_dai_driver;
struct snd_soc_dai_ops;
struct snd_soc_dapm_route;
struct snd_soc_dapm_widget;
struct snd_soc_pcm_stream;
struct sdca_entity;
/* 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) \
@@ -82,6 +84,11 @@ int sdca_asoc_populate_component(struct device *dev,
struct snd_soc_dai_driver **dai_drv, int *num_dai_drv,
const struct snd_soc_dai_ops *ops);
int sdca_asoc_populate_rate_format(struct device *dev,
struct sdca_function_data *function,
struct sdca_entity *entity,
struct snd_soc_pcm_stream *stream);
int sdca_asoc_set_constraints(struct device *dev, struct regmap *regmap,
struct sdca_function_data *function,
struct snd_pcm_substream *substream,

View File

@@ -83,6 +83,10 @@ static inline int sdca_fdl_alloc_state(struct sdca_interrupt *interrupt)
return 0;
}
static inline void sdca_fdl_free_state(struct sdca_interrupt *interrupt)
{
}
static inline int sdca_fdl_process(struct sdca_interrupt *interrupt)
{
return 0;

View File

@@ -1469,5 +1469,7 @@ struct sdca_control_range *sdca_selector_find_range(struct device *dev,
struct sdca_cluster *sdca_id_find_cluster(struct device *dev,
struct sdca_function_data *function,
const int id);
struct sdca_entity *sdca_find_entity_by_label(struct sdca_function_data *function,
const char *entity_label);
#endif

View File

@@ -181,7 +181,7 @@ void simple_util_canonicalize_platform(struct snd_soc_dai_link_component *platfo
void simple_util_canonicalize_cpu(struct snd_soc_dai_link_component *cpus,
int is_single_links);
void simple_util_clean_reference(struct snd_soc_card *card);
void simple_util_clean_reference(struct simple_util_priv *priv);
void simple_util_parse_convert(struct device_node *np, char *prefix,
struct simple_util_data *data);
@@ -189,18 +189,37 @@ bool simple_util_is_convert_required(const struct simple_util_data *data);
int simple_util_get_sample_fmt(struct simple_util_data *data);
int simple_util_parse_routing(struct snd_soc_card *card,
char *prefix);
int simple_util_parse_widgets(struct snd_soc_card *card,
char *prefix);
int simple_util_parse_pin_switches(struct snd_soc_card *card,
char *prefix);
int simple_util_parse_property(struct simple_util_priv *priv,
int (*func)(struct snd_soc_card *card, const char *propname),
char *prefix, char *property);
static inline int simple_util_parse_routing(struct simple_util_priv *priv, char *prefix)
{
return simple_util_parse_property(priv, snd_soc_of_parse_audio_routing,
prefix, "routing");
}
static inline int simple_util_parse_widgets(struct simple_util_priv *priv, char *prefix)
{
return simple_util_parse_property(priv, snd_soc_of_parse_audio_simple_widgets,
prefix, "widgets");
}
static inline int simple_util_parse_pin_switches(struct simple_util_priv *priv, char *prefix)
{
return simple_util_parse_property(priv, snd_soc_of_parse_pin_switches,
prefix, "pin-switches");
}
static inline int simple_util_parse_aux_devs(struct simple_util_priv *priv, char *prefix)
{
return simple_util_parse_property(priv, snd_soc_of_parse_aux_devs,
prefix, "aux-devs");
}
int simple_util_init_jack(struct snd_soc_card *card,
struct simple_util_jack *sjack,
int is_hp, char *prefix, char *pin);
int simple_util_init_aux_jacks(struct simple_util_priv *priv,
char *prefix);
int simple_util_init_aux_jacks(struct snd_soc_card *card, char *prefix);
int simple_util_init_priv(struct simple_util_priv *priv,
struct link_info *li);
void simple_util_remove(struct platform_device *pdev);

View File

@@ -44,6 +44,18 @@
struct asoc_sdw_codec_info;
struct asoc_sdw_mc_private {
struct snd_soc_card card;
struct snd_soc_jack sdw_headset;
struct device *headset_codec_dev; /* only one headset per card */
struct device *amp_dev1, *amp_dev2;
bool append_dai_type;
bool ignore_internal_dmic;
void *private;
unsigned long mc_quirk;
int codec_info_list_count;
};
struct asoc_sdw_dai_info {
const bool direction[2]; /* playback & capture support */
const char *codec_name;
@@ -88,25 +100,13 @@ struct asoc_sdw_codec_info {
int (*codec_card_late_probe)(struct snd_soc_card *card);
int (*count_sidecar)(struct snd_soc_card *card,
int (*count_sidecar)(struct asoc_sdw_mc_private *ctx,
int *num_dais, int *num_devs);
int (*add_sidecar)(struct snd_soc_card *card,
struct snd_soc_dai_link **dai_links,
struct snd_soc_codec_conf **codec_conf);
};
struct asoc_sdw_mc_private {
struct snd_soc_card card;
struct snd_soc_jack sdw_headset;
struct device *headset_codec_dev; /* only one headset per card */
struct device *amp_dev1, *amp_dev2;
bool append_dai_type;
bool ignore_internal_dmic;
void *private;
unsigned long mc_quirk;
int codec_info_list_count;
};
struct asoc_sdw_endpoint {
struct list_head list;
@@ -182,7 +182,8 @@ struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks
const struct snd_soc_acpi_endpoint *new);
int asoc_sdw_get_dai_type(u32 type);
int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
int asoc_sdw_parse_sdw_endpoints(struct device *dev,
struct asoc_sdw_mc_private *ctx,
struct snd_soc_aux_dev *soc_aux,
struct asoc_sdw_dailink *soc_dais,
struct asoc_sdw_endpoint *soc_ends,
@@ -235,7 +236,7 @@ int asoc_sdw_es9356_amp_init(struct snd_soc_card *card,
int asoc_sdw_es9356_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
/* CS AMP support */
int asoc_sdw_bridge_cs35l56_count_sidecar(struct snd_soc_card *card,
int asoc_sdw_bridge_cs35l56_count_sidecar(struct asoc_sdw_mc_private *ctx,
int *num_dais, int *num_devs);
int asoc_sdw_bridge_cs35l56_add_sidecar(struct snd_soc_card *card,
struct snd_soc_dai_link **dai_links,

View File

@@ -18,6 +18,7 @@ struct sof_ipc_dai_acp_params {
uint32_t fsync_rate; /* FSYNC frequency in Hz */
uint32_t tdm_slots;
uint32_t tdm_mode;
uint32_t format;
} __packed;
/* ACPDMIC Configuration Request - SOF_IPC_DAI_AMD_CONFIG */

View File

@@ -90,6 +90,8 @@ enum sof_ipc_dai_type {
SOF_DAI_AMD_HS_VIRTUAL, /**< AMD ACP HS VIRTUAL */
SOF_DAI_IMX_MICFIL, /** < i.MX MICFIL PDM */
SOF_DAI_AMD_SDW, /**< AMD ACP SDW */
SOF_DAI_INTEL_UAOL, /**< Intel UAOL */
SOF_DAI_AMD_I2S, /**< AMD ACP I2S */
};
/* general purpose DAI configuration */
@@ -121,6 +123,7 @@ struct sof_ipc_dai_config {
struct sof_ipc_dai_mtk_afe_params afe;
struct sof_ipc_dai_micfil_params micfil;
struct sof_ipc_dai_acp_sdw_params acp_sdw;
struct sof_ipc_dai_acp_params acp_i2s;
};
} __packed;

View File

@@ -179,7 +179,7 @@ struct sof_ipc_compound_hdr {
uint32_t count; /**< count of 0 means end of compound sequence */
} __packed;
/**
/*
* OOPS header architecture specific data.
*/
struct sof_ipc_dsp_oops_arch_hdr {
@@ -187,7 +187,7 @@ struct sof_ipc_dsp_oops_arch_hdr {
uint32_t totalsize; /* Total size of oops message */
} __packed;
/**
/*
* OOPS header platform specific data.
*/
struct sof_ipc_dsp_oops_plat_hdr {

View File

@@ -187,6 +187,10 @@ enum sof_ipc4_pipeline_state {
#define SOF_IPC4_GLB_PIPE_EXT_CORE_ID_MASK GENMASK(23, 20)
#define SOF_IPC4_GLB_PIPE_EXT_CORE_ID(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_CORE_ID_SHIFT)
#define SOF_IPC4_GLB_PIPE_PAYLOAD_SHIFT 29
#define SOF_IPC4_GLB_PIPE_PAYLOAD_MASK BIT(29)
#define SOF_IPC4_GLB_PIPE_PAYLOAD(x) ((x) << SOF_IPC4_GLB_PIPE_PAYLOAD_SHIFT)
/* pipeline set state ipc msg */
#define SOF_IPC4_GLB_PIPE_STATE_ID_SHIFT 16
#define SOF_IPC4_GLB_PIPE_STATE_ID_MASK GENMASK(23, 16)
@@ -536,12 +540,63 @@ enum sof_ipc4_notification_type {
SOF_IPC4_NOTIFY_TYPE_LAST,
};
enum sof_ipc4_resource_type {
SOF_IPC4_MODULE_INSTANCE,
SOF_IPC4_PIPELINE,
SOF_IPC4_GATEWAY,
SOF_IPC4_EDF_TASK,
SOF_IPC4_INVALID_RESOURCE_TYPE,
};
enum sof_ipc4_event_type {
/* Underrun detected by the Mixer */
SOF_IPC4_MIXER_UNDERRUN_DETECTED = 1,
/* Error caught during data processing */
SOF_IPC4_PROCESS_DATA_ERROR = 3,
/* Underrun detected by gateway. */
SOF_IPC4_GATEWAY_UNDERRUN_DETECTED = 6,
/* Overrun detected by gateway */
SOF_IPC4_GATEWAY_OVERRUN_DETECTED,
};
/**
* struct sof_ipc4_process_data_error_event_data - process data error event payload
* @error_code: Error code returned by data processing function
*/
struct sof_ipc4_process_data_error_event_data {
uint32_t error_code;
};
/**
* struct sof_ipc4_mixer_underrun_event_data - mixer underrun event payload
* @eos_flag: Indicates EndOfStream
* @data_mixed: Data processed by module (in bytes)
* @expected_data_mixed: Expected data to be processed (in bytes)
*/
struct sof_ipc4_mixer_underrun_event_data {
uint32_t eos_flag;
uint32_t data_mixed;
uint32_t expected_data_mixed;
};
/**
* union sof_ipc4_resource_event_data - resource event specific payload
* @dws: Raw event data payload as six dwords
* @process_data_error: SOF_IPC4_PROCESS_DATA_ERROR payload
* @mixer_underrun: SOF_IPC4_MIXER_UNDERRUN_DETECTED payload
*/
union sof_ipc4_resource_event_data {
uint32_t dws[6];
struct sof_ipc4_process_data_error_event_data process_data_error;
struct sof_ipc4_mixer_underrun_event_data mixer_underrun;
};
struct sof_ipc4_notify_resource_data {
uint32_t resource_type;
uint32_t resource_id;
uint32_t event_type;
uint32_t reserved;
uint32_t data[6];
union sof_ipc4_resource_event_data data;
} __packed __aligned(4);
#define SOF_IPC4_DEBUG_DESCRIPTOR_SIZE 12 /* 3 x u32 */
@@ -654,11 +709,81 @@ enum sof_ipc4_mod_init_ext_obj_id {
SOF_IPC4_MOD_INIT_DATA_ID_MAX = SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA,
};
/* DP module memory configuration data object for ext_init object array */
/* DP module memory configuration data object for object array */
struct sof_ipc4_mod_init_ext_dp_memory_data {
u32 domain_id; /* userspace domain ID */
u32 stack_bytes; /* required stack size in bytes */
u32 heap_bytes; /* required heap size in bytes */
} __packed __aligned(4);
/*
* This set of macros are very similar to the set above, but these are
* for building payload to SOF_IPC4_GLB_CREATE_PIPELINE message.
*
* Macros for creating struct sof_ipc4_glb_pipe_payload payload with
* its associated data. struct sof_ipc4_glb_pipe_payload should be the
* first piece of payload following SOF_IPC4_GLB_CREATE_PIPELINE msg,
* and its existence is indicated with SOF_IPC4_GLB_PIPE_PAYLOAD bit.
*
* The macros below apply to sof_ipc4_glb_pipe_payload.word0
*/
#define SOF_IPC4_GLB_PIPE_PAYLOAD_WORDS_SHIFT 0
#define SOF_IPC4_GLB_PIPE_PAYLOAD_WORDS_MASK GENMASK(23, 0)
#define SOF_IPC4_GLB_PIPE_PAYLOAD_WORDS(x) ((x) << SOF_IPC4_GLB_PIPE_PAYLOAD_WORDS_SHIFT)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY_SHIFT 24
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY_MASK BIT(24)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY_SHIFT)
struct sof_ipc4_glb_pipe_payload {
u32 word0;
u32 rsvd1;
u32 rsvd2;
} __packed __aligned(4);
/*
* SOF_IPC4_GLB_CREATE_PIPELINE payload may be followed by arbitrary
* number of object array objects. SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY-bit
* indicates that an array object follows struct
* sof_ipc4_glb_pipe_payload.
*
* The object header's SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST-bit in struct
* sof_ipc4_glb_pipe_ext_object indicates if the array is continued
* with another object. The header has also fields to identify the
* object, SOF_IPC4_GLB_PIPE_EXT_OBJ_ID, and to indicate the object's
* size in 32-bit words, SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS, not
* including the header itself.
*
* The macros below apply to sof_ipc4_glb_pipe_ext_object.header
*/
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST_SHIFT 0
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST_MASK BIT(0)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST_SHIFT)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_ID_SHIFT 1
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_ID_MASK GENMASK(15, 1)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_ID(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_OBJ_ID_SHIFT)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS_SHIFT 16
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS_MASK GENMASK(31, 16)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS_SHIFT)
struct sof_ipc4_glb_pipe_ext_object {
u32 header;
u32 data[];
} __packed __aligned(4);
enum sof_ipc4_glb_pipe_ext_obj_id {
SOF_IPC4_GLB_PIPE_DATA_ID_INVALID = 0,
SOF_IPC4_GLB_PIPE_DATA_ID_MEM_DATA,
SOF_IPC4_GLB_PIPE_DATA_ID_MAX = SOF_IPC4_GLB_PIPE_DATA_ID_MEM_DATA,
};
/* Pipeline memory configuration data object for ext_init object array */
struct sof_ipc4_glb_pipe_ext_obj_memory_data {
u32 domain_id; /* userspace domain ID */
u32 stack_bytes; /* stack size in bytes, 0 means default size */
u32 heap_bytes; /* stack size in bytes, 0 means default size */
u32 stack_bytes; /* stack size in bytes */
u32 heap_bytes; /* heap size in bytes */
} __packed __aligned(4);
/** @}*/

View File

@@ -1,43 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* tlv320aic32x4.h -- TLV320AIC32X4 Soc Audio driver platform data
*
* Copyright 2011 Vista Silicon S.L.
*
* Author: Javier Martin <javier.martin@vista-silicon.com>
*/
#ifndef _AIC32X4_PDATA_H
#define _AIC32X4_PDATA_H
#define AIC32X4_PWR_MICBIAS_2075_LDOIN 0x00000001
#define AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE 0x00000002
#define AIC32X4_PWR_AIC32X4_LDO_ENABLE 0x00000004
#define AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36 0x00000008
#define AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED 0x00000010
#define AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K 0x00000001
#define AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K 0x00000002
/* GPIO API */
#define AIC32X4_MFPX_DEFAULT_VALUE 0xff
#define AIC32X4_MFP1_DIN_DISABLED 0
#define AIC32X4_MFP1_DIN_ENABLED 0x2
#define AIC32X4_MFP1_GPIO_IN 0x4
#define AIC32X4_MFP2_GPIO_OUT_LOW 0x0
#define AIC32X4_MFP2_GPIO_OUT_HIGH 0x1
#define AIC32X4_MFP_GPIO_ENABLED 0x4
#define AIC32X4_MFP5_GPIO_DISABLED 0x0
#define AIC32X4_MFP5_GPIO_INPUT 0x8
#define AIC32X4_MFP5_GPIO_OUTPUT 0xc
#define AIC32X4_MFP5_GPIO_OUT_LOW 0x0
#define AIC32X4_MFP5_GPIO_OUT_HIGH 0x1
struct aic32x4_setup_data {
unsigned int gpio_func[5];
};
#endif

View File

@@ -111,8 +111,8 @@
#define SOF_TKN_COMP_SCHED_DOMAIN 418
#define SOF_TKN_COMP_DOMAIN_ID 419
#define SOF_TKN_COMP_HEAP_BYTES_REQUIREMENT 420
#define SOF_TKN_COMP_STACK_BYTES_REQUIREMENT 421
#define SOF_TKN_COMP_STACK_BYTES_REQUIREMENT 420
#define SOF_TKN_COMP_HEAP_BYTES_REQUIREMENT 421
/* SSP */
#define SOF_TKN_INTEL_SSP_CLKS_CONTROL 500
@@ -223,6 +223,7 @@
#define SOF_TKN_AMD_ACPI2S_RATE 1700
#define SOF_TKN_AMD_ACPI2S_CH 1701
#define SOF_TKN_AMD_ACPI2S_TDM_MODE 1702
#define SOF_TKN_AMD_ACPI2S_FORMAT 1703
/* MICFIL PDM */
#define SOF_TKN_IMX_MICFIL_RATE 2000

View File

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

View File

@@ -686,6 +686,10 @@ static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_d
return 0;
}
static const u64 acp_i2s_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_DSP_A;
const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops = {
.startup = acp_i2s_startup,
.hw_params = acp_i2s_hwparams,
@@ -693,6 +697,8 @@ const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops = {
.trigger = acp_i2s_trigger,
.set_fmt = acp_i2s_set_fmt,
.set_tdm_slot = acp_i2s_set_tdm_slot,
.auto_selectable_formats = &acp_i2s_selectable_formats,
.num_auto_selectable_formats = 1,
};
EXPORT_SYMBOL_NS_GPL(asoc_acp_cpu_dai_ops, "SND_SOC_ACP_COMMON");

View File

@@ -938,15 +938,10 @@ static int acp_max98388_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *codec_dai =
snd_soc_card_get_codec_dai(card,
MAX98388_CODEC_DAI);
int ret;
ret = snd_soc_dai_set_fmt(codec_dai,
SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF);
if (ret < 0)
return ret;
return ret;
return snd_soc_dai_set_fmt(codec_dai,
SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF);
}
static const struct snd_soc_ops acp_max98388_ops = {

View File

@@ -118,17 +118,10 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id
if (!chip)
return -ENOMEM;
if (pci_enable_device(pci))
if (pcim_enable_device(pci))
return dev_err_probe(&pci->dev, -ENODEV,
"pci_enable_device failed\n");
ret = pci_request_regions(pci, "AMD ACP3x audio");
if (ret < 0) {
dev_err(&pci->dev, "pci_request_regions failed\n");
ret = -ENOMEM;
goto disable_pci;
}
pci_set_master(pci);
chip->acp_rev = pci->revision;
@@ -161,24 +154,21 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id
break;
default:
dev_err(dev, "Unsupported device revision:0x%x\n", pci->revision);
ret = -EINVAL;
goto release_regions;
return -EINVAL;
}
chip->flag = flag;
addr = pci_resource_start(pci, 0);
chip->base = devm_ioremap(&pci->dev, addr, pci_resource_len(pci, 0));
if (!chip->base) {
ret = -ENOMEM;
goto release_regions;
}
chip->base = pcim_iomap_region(pci, 0, "AMD ACP3x audio");
if (IS_ERR(chip->base))
return PTR_ERR(chip->base);
chip->addr = addr;
chip->acp_hw_ops_init(chip);
ret = acp_hw_init(chip);
if (ret)
goto release_regions;
goto de_init;
ret = devm_request_irq(dev, pci->irq, irq_handler,
IRQF_SHARED, "ACP_I2S_IRQ", chip);
@@ -214,10 +204,6 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id
de_init:
acp_hw_deinit(chip);
release_regions:
pci_release_regions(pci);
disable_pci:
pci_disable_device(pci);
return ret;
};

View File

@@ -432,7 +432,7 @@ static int soc_card_dai_links_create(struct snd_soc_card *card)
if (!soc_aux)
return -ENOMEM;
ret = asoc_sdw_parse_sdw_endpoints(card, soc_aux, soc_dais, soc_ends, &num_confs);
ret = asoc_sdw_parse_sdw_endpoints(dev, ctx, soc_aux, soc_dais, soc_ends, &num_confs);
if (ret < 0)
return ret;
@@ -521,15 +521,15 @@ static int mc_probe(struct platform_device *pdev)
dmi_check_system(soc_sdw_quirk_table);
if (quirk_override != -1) {
dev_info(card->dev, "Overriding quirk 0x%lx => 0x%x\n",
dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n",
soc_sdw_quirk, quirk_override);
soc_sdw_quirk = quirk_override;
}
log_quirks(card->dev);
log_quirks(&pdev->dev);
ctx->mc_quirk = soc_sdw_quirk;
dev_dbg(card->dev, "legacy quirk 0x%lx\n", ctx->mc_quirk);
dev_dbg(&pdev->dev, "legacy quirk 0x%lx\n", ctx->mc_quirk);
/* reset amp_num to ensure amp_num++ starts from 0 in each probe */
for (i = 0; i < ctx->codec_info_list_count; i++)
codec_info_list[i].amp_num = 0;
@@ -546,12 +546,12 @@ static int mc_probe(struct platform_device *pdev)
for (i = 0; i < ctx->codec_info_list_count; i++)
amp_num += codec_info_list[i].amp_num;
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
card->components = devm_kasprintf(&pdev->dev, GFP_KERNEL,
" cfg-amp:%d", amp_num);
if (!card->components)
return -ENOMEM;
if (soc_sdw_quirk & ASOC_SDW_ACP_DMIC) {
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
card->components = devm_kasprintf(&pdev->dev, GFP_KERNEL,
"%s mic:acp-dmic cfg-mics:%d",
card->components,
1);
@@ -560,9 +560,9 @@ static int mc_probe(struct platform_device *pdev)
}
/* Register the card */
ret = devm_snd_soc_register_card(card->dev, card);
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) {
dev_err_probe(card->dev, ret, "snd_soc_register_card failed %d\n", ret);
dev_err_probe(&pdev->dev, ret, "snd_soc_register_card failed %d\n", ret);
asoc_sdw_mc_dailink_exit_loop(card);
return ret;
}
@@ -580,8 +580,8 @@ static void mc_remove(struct platform_device *pdev)
}
static const struct platform_device_id mc_id_table[] = {
{ "amd_sdw", },
{}
{ .name = "amd_sdw" },
{ }
};
MODULE_DEVICE_TABLE(platform, mc_id_table);

View File

@@ -303,7 +303,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
if (!sof_aux)
return -ENOMEM;
ret = asoc_sdw_parse_sdw_endpoints(card, sof_aux, sof_dais, sof_ends, &num_devs);
ret = asoc_sdw_parse_sdw_endpoints(dev, ctx, sof_aux, sof_dais, sof_ends, &num_devs);
if (ret < 0)
return ret;
@@ -388,12 +388,12 @@ static int mc_probe(struct platform_device *pdev)
dmi_check_system(sof_sdw_quirk_table);
if (quirk_override != -1) {
dev_info(card->dev, "Overriding quirk 0x%lx => 0x%x\n",
dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n",
sof_sdw_quirk, quirk_override);
sof_sdw_quirk = quirk_override;
}
log_quirks(card->dev);
log_quirks(&pdev->dev);
ctx->mc_quirk = sof_sdw_quirk;
/* reset amp_num to ensure amp_num++ starts from 0 in each probe */
@@ -412,15 +412,15 @@ static int mc_probe(struct platform_device *pdev)
for (i = 0; i < ctx->codec_info_list_count; i++)
amp_num += codec_info_list[i].amp_num;
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
card->components = devm_kasprintf(&pdev->dev, GFP_KERNEL,
" cfg-amp:%d", amp_num);
if (!card->components)
return -ENOMEM;
/* Register the card */
ret = devm_snd_soc_register_card(card->dev, card);
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) {
dev_err_probe(card->dev, ret, "snd_soc_register_card failed %d\n", ret);
dev_err_probe(&pdev->dev, ret, "snd_soc_register_card failed %d\n", ret);
asoc_sdw_mc_dailink_exit_loop(card);
return ret;
}
@@ -438,8 +438,8 @@ static void mc_remove(struct platform_device *pdev)
}
static const struct platform_device_id mc_id_table[] = {
{ "amd_sof_sdw", },
{}
{ .name = "amd_sof_sdw" },
{ }
};
MODULE_DEVICE_TABLE(platform, mc_id_table);

View File

@@ -128,31 +128,31 @@ static int acp_sof_probe(struct platform_device *pdev)
static const struct platform_device_id board_ids[] = {
{
.name = "rt5682-rt1019",
.driver_data = (kernel_ulong_t)&sof_rt5682_rt1019_data
.driver_data = (kernel_ulong_t)&sof_rt5682_rt1019_data,
},
{
.name = "rt5682-max",
.driver_data = (kernel_ulong_t)&sof_rt5682_max_data
.driver_data = (kernel_ulong_t)&sof_rt5682_max_data,
},
{
.name = "rt5682s-max",
.driver_data = (kernel_ulong_t)&sof_rt5682s_max_data
.driver_data = (kernel_ulong_t)&sof_rt5682s_max_data,
},
{
.name = "rt5682s-rt1019",
.driver_data = (kernel_ulong_t)&sof_rt5682s_rt1019_data
.driver_data = (kernel_ulong_t)&sof_rt5682s_rt1019_data,
},
{
.name = "nau8825-max",
.driver_data = (kernel_ulong_t)&sof_nau8825_data
.driver_data = (kernel_ulong_t)&sof_nau8825_data,
},
{
.name = "rt5682s-hs-rt1019",
.driver_data = (kernel_ulong_t)&sof_rt5682s_hs_rt1019_data
.driver_data = (kernel_ulong_t)&sof_rt5682s_hs_rt1019_data,
},
{
.name = "nau8821-max",
.driver_data = (kernel_ulong_t)&sof_nau8821_max98388_data
.driver_data = (kernel_ulong_t)&sof_nau8821_max98388_data,
},
{ }
};

View File

@@ -28,6 +28,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sof_sdw_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sof_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sof_sdw_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_amd_acp7x_sof_machines[];
struct config_entry {
u32 flags;

View File

@@ -250,11 +250,17 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
return ret;
}
static const u64 acp3x_i2s_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_DSP_A;
static const struct snd_soc_dai_ops acp3x_i2s_dai_ops = {
.hw_params = acp3x_i2s_hwparams,
.trigger = acp3x_i2s_trigger,
.set_fmt = acp3x_i2s_set_fmt,
.set_tdm_slot = acp3x_i2s_set_tdm_slot,
.auto_selectable_formats = &acp3x_i2s_selectable_formats,
.num_auto_selectable_formats = 1,
};
static const struct snd_soc_component_driver acp3x_dai_component = {

View File

@@ -337,11 +337,17 @@ static int acp5x_i2s_trigger(struct snd_pcm_substream *substream,
return ret;
}
static const u64 acp5x_i2s_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_DSP_A;
static const struct snd_soc_dai_ops acp5x_i2s_dai_ops = {
.hw_params = acp5x_i2s_hwparams,
.trigger = acp5x_i2s_trigger,
.set_fmt = acp5x_i2s_set_fmt,
.set_tdm_slot = acp5x_i2s_set_tdm_slot,
.auto_selectable_formats = &acp5x_i2s_selectable_formats,
.num_auto_selectable_formats = 1,
};
static const struct snd_soc_component_driver acp5x_dai_component = {

View File

@@ -781,12 +781,12 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "Vivobook_ASUSLaptop M6501RR_M6501RR"),
}
},
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "Vivobook_ASUSLaptop M6501RR_M6501RR"),
}
},
{
.driver_data = &acp6x_card,
.matches = {

View File

@@ -133,12 +133,17 @@ struct mca_cluster {
struct clk *clk_parent;
struct dma_chan *dma_chans[SNDRV_PCM_STREAM_LAST + 1];
bool port_started[SNDRV_PCM_STREAM_LAST + 1];
int port_driver; /* The cluster driving this cluster's port */
bool clk_provider;
bool port_clk_started[SNDRV_PCM_STREAM_LAST + 1];
int port_clk_driver; /* The cluster driving this cluster's port */
bool clocks_in_use[SNDRV_PCM_STREAM_LAST + 1];
struct device_link *pd_link;
/* In case of clock consumer FE */
int syncgen_in_use;
unsigned int bclk_ratio;
/* Masks etc. picked up via the set_tdm_slot method */
@@ -157,7 +162,7 @@ struct mca_data {
struct reset_control *rstc;
struct device_link *pd_link;
/* Mutex for accessing port_driver of foreign clusters */
/* Mutex for accessing port_clk_driver of foreign clusters */
struct mutex port_mutex;
int nclusters;
@@ -210,16 +215,22 @@ static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
SERDES_STATUS_EN | SERDES_STATUS_RST,
SERDES_STATUS_RST);
/*
* Experiments suggest that it takes at most ~1 us
* for the bit to clear, so wait 2 us for good measure.
* The SERDES cluster needs a bit of time to reset itself
* and settle before we start poking it. This is... slow...
*/
udelay(2);
udelay(25);
WARN_ON(readl_relaxed(cl->base + serdes_unit + REG_SERDES_STATUS) &
SERDES_STATUS_RST);
mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
FIELD_PREP(SERDES_CONF_SYNC_SEL, 0));
mca_modify(cl, serdes_conf, SERDES_CONF_SYNC_SEL,
FIELD_PREP(SERDES_CONF_SYNC_SEL, cl->no + 1));
/*
* ADMAC gets started right after this. This delay seems
* to be needed for that to be reliable, e.g. ensure the
* clock is stable?
*/
udelay(100);
break;
default:
break;
@@ -256,11 +267,29 @@ static int mca_fe_trigger(struct snd_pcm_substream *substream, int cmd,
return 0;
}
static int mca_fe_get_portmask(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *fe = snd_soc_substream_to_rtd(substream);
struct snd_soc_dpcm *dpcm;
int mask = 0;
for_each_dpcm_be(fe, substream->stream, dpcm) {
int no = mca_dai_to_cluster(snd_soc_rtd_to_cpu(dpcm->be, 0))->no;
mask |= 1 << no;
}
return mask;
}
static int mca_fe_enable_clocks(struct mca_cluster *cl)
{
struct mca_data *mca = cl->host;
int ret;
if (!cl->clk_provider)
return -EINVAL;
ret = clk_prepare_enable(cl->clk_parent);
if (ret) {
dev_err(mca->dev,
@@ -311,7 +340,7 @@ static bool mca_fe_clocks_in_use(struct mca_cluster *cl)
for (i = 0; i < mca->nclusters; i++) {
be_cl = &mca->clusters[i];
if (be_cl->port_driver != cl->no)
if (be_cl->port_clk_driver != cl->no)
continue;
for_each_pcm_streams(stream) {
@@ -323,36 +352,6 @@ static bool mca_fe_clocks_in_use(struct mca_cluster *cl)
return false;
}
static int mca_be_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct mca_cluster *cl = mca_dai_to_cluster(dai);
struct mca_data *mca = cl->host;
struct mca_cluster *fe_cl;
int ret;
if (cl->port_driver < 0)
return -EINVAL;
fe_cl = &mca->clusters[cl->port_driver];
/*
* Typically the CODECs we are paired with will require clocks
* to be present at time of unmute with the 'mute_stream' op
* or at time of DAPM widget power-up. We need to enable clocks
* here at the latest (frontend prepare would be too late).
*/
if (!mca_fe_clocks_in_use(fe_cl)) {
ret = mca_fe_enable_clocks(fe_cl);
if (ret < 0)
return ret;
}
cl->clocks_in_use[substream->stream] = true;
return 0;
}
static int mca_be_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -360,7 +359,7 @@ static int mca_be_hw_free(struct snd_pcm_substream *substream,
struct mca_data *mca = cl->host;
struct mca_cluster *fe_cl;
if (cl->port_driver < 0)
if (cl->port_clk_driver < 0)
return -EINVAL;
/*
@@ -368,7 +367,7 @@ static int mca_be_hw_free(struct snd_pcm_substream *substream,
* belong to the same PCM, accesses should have been
* synchronized at ASoC level.
*/
fe_cl = &mca->clusters[cl->port_driver];
fe_cl = &mca->clusters[cl->port_clk_driver];
if (!mca_fe_clocks_in_use(fe_cl))
return 0; /* Nothing to do */
@@ -380,6 +379,56 @@ static int mca_be_hw_free(struct snd_pcm_substream *substream,
return 0;
}
static int mca_fe_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct mca_cluster *cl = mca_dai_to_cluster(dai);
struct mca_data *mca = cl->host;
if (cl->clk_provider)
return 0;
/* Turn on the cluster power domain if not already in use */
if (!cl->syncgen_in_use) {
int port = ffs(mca_fe_get_portmask(substream));
cl->pd_link = device_link_add(mca->dev, cl->pd_dev,
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
DL_FLAG_RPM_ACTIVE);
if (!cl->pd_link) {
dev_err(mca->dev,
"cluster %d: unable to prop-up power domain\n", cl->no);
return -EINVAL;
}
mca_modify(cl, REG_SYNCGEN_MCLK_SEL, SYNCGEN_MCLK_SEL, BIT(port));
mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN,
SYNCGEN_STATUS_EN);
}
cl->syncgen_in_use |= 1 << substream->stream;
return 0;
}
static int mca_fe_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct mca_cluster *cl = mca_dai_to_cluster(dai);
if (cl->clk_provider)
return 0;
cl->syncgen_in_use &= ~(1 << substream->stream);
if (cl->syncgen_in_use)
return 0;
mca_modify(cl, REG_SYNCGEN_STATUS, SYNCGEN_STATUS_EN, 0);
if (cl->pd_link)
device_link_del(cl->pd_link);
return 0;
}
static unsigned int mca_crop_mask(unsigned int mask, int nchans)
{
while (hweight32(mask) > nchans)
@@ -390,7 +439,7 @@ static unsigned int mca_crop_mask(unsigned int mask, int nchans)
static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit,
unsigned int mask, int slots, int nchans,
int slot_width, bool is_tx, int port)
int slot_width, bool is_tx, int portmask)
{
__iomem void *serdes_base = cl->base + serdes_unit;
u32 serdes_conf, serdes_conf_mask;
@@ -449,7 +498,7 @@ static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit,
serdes_base + REG_RX_SERDES_SLOTMASK);
writel_relaxed(~((u32)mca_crop_mask(mask, nchans)),
serdes_base + REG_RX_SERDES_SLOTMASK + 0x4);
writel_relaxed(1 << port,
writel_relaxed(portmask,
serdes_base + REG_RX_SERDES_PORT);
}
@@ -505,9 +554,18 @@ static int mca_fe_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
u32 serdes_conf = 0;
u32 bitstart;
if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) !=
SND_SOC_DAIFMT_BP_FP)
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
case SND_SOC_DAIFMT_BP_FP:
cl->clk_provider = true;
break;
case SND_SOC_DAIFMT_BC_FC:
cl->clk_provider = false;
break;
default:
goto err;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
@@ -564,24 +622,6 @@ static int mca_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
return 0;
}
static int mca_fe_get_port(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *fe = snd_soc_substream_to_rtd(substream);
struct snd_soc_pcm_runtime *be;
struct snd_soc_dpcm *dpcm;
be = NULL;
for_each_dpcm_be(fe, substream->stream, dpcm) {
be = dpcm->be;
break;
}
if (!be)
return -EINVAL;
return mca_dai_to_cluster(snd_soc_rtd_to_cpu(be, 0))->no;
}
static int mca_fe_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -595,7 +635,7 @@ static int mca_fe_hw_params(struct snd_pcm_substream *substream,
unsigned long bclk_ratio;
unsigned int tdm_slots, tdm_slot_width, tdm_mask;
u32 regval, pad;
int ret, port, nchans_ceiled;
int ret, portmask, nchans_ceiled;
if (!cl->tdm_slot_width) {
/*
@@ -644,13 +684,13 @@ static int mca_fe_hw_params(struct snd_pcm_substream *substream,
tdm_mask = (1 << tdm_slots) - 1;
}
port = mca_fe_get_port(substream);
if (port < 0)
return port;
portmask = mca_fe_get_portmask(substream);
if (!portmask)
return -EINVAL;
ret = mca_configure_serdes(cl, is_tx ? CLUSTER_TX_OFF : CLUSTER_RX_OFF,
tdm_mask, tdm_slots, params_channels(params),
tdm_slot_width, is_tx, port);
tdm_slot_width, is_tx, portmask);
if (ret)
return ret;
@@ -699,6 +739,19 @@ static int mca_fe_hw_params(struct snd_pcm_substream *substream,
return 0;
}
static const u64 mca_fe_selectable_formats[] =
{
/* pattern 1 */
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_NB_IF |
SND_SOC_POSSIBLE_DAIFMT_IB_IF,
/* pattern 2 */
SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
SND_SOC_POSSIBLE_DAIFMT_NB_NF |
SND_SOC_POSSIBLE_DAIFMT_IB_NF
};
static const struct snd_soc_dai_ops mca_fe_ops = {
.startup = mca_fe_startup,
.set_fmt = mca_fe_set_fmt,
@@ -706,66 +759,128 @@ static const struct snd_soc_dai_ops mca_fe_ops = {
.set_tdm_slot = mca_fe_set_tdm_slot,
.hw_params = mca_fe_hw_params,
.trigger = mca_fe_trigger,
.prepare = mca_fe_prepare,
.hw_free = mca_fe_hw_free,
.auto_selectable_formats = mca_fe_selectable_formats,
.num_auto_selectable_formats = ARRAY_SIZE(mca_fe_selectable_formats),
};
static bool mca_be_started(struct mca_cluster *cl)
/*
* Is there a FE attached which will be feeding this port's clocks?
*/
static bool mca_be_clk_started(struct mca_cluster *cl)
{
int stream;
for_each_pcm_streams(stream)
if (cl->port_started[stream])
if (cl->port_clk_started[stream])
return true;
return false;
}
static struct snd_soc_pcm_runtime *mca_be_get_fe(struct snd_soc_pcm_runtime *be,
int stream)
{
struct snd_soc_pcm_runtime *fe = NULL;
struct snd_soc_dpcm *dpcm;
for_each_dpcm_fe(be, stream, dpcm) {
if (fe && dpcm->fe != fe) {
dev_err(be->dev, "many FE per one BE unsupported\n");
return NULL;
}
fe = dpcm->fe;
}
return fe;
}
static int mca_be_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *be = snd_soc_substream_to_rtd(substream);
struct snd_soc_pcm_runtime *fe = mca_be_get_fe(be, substream->stream);
struct mca_cluster *cl = mca_dai_to_cluster(dai);
struct mca_data *mca = cl->host;
struct mca_cluster *fe_cl, *fe_clk_cl;
int ret;
fe_cl = mca_dai_to_cluster(snd_soc_rtd_to_cpu(fe, 0));
if (!fe_cl->clk_provider)
return 0;
if (cl->port_clk_driver < 0)
return 0;
fe_clk_cl = &mca->clusters[cl->port_clk_driver];
/*
* Typically the CODECs we are paired with will require clocks
* to be present at time of unmute with the 'mute_stream' op
* or at time of DAPM widget power-up. We need to enable clocks
* here at the latest (frontend prepare would be too late).
*/
if (!mca_fe_clocks_in_use(fe_clk_cl)) {
ret = mca_fe_enable_clocks(fe_clk_cl);
if (ret < 0)
return ret;
}
cl->clocks_in_use[substream->stream] = true;
return 0;
}
static int mca_be_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *be = snd_soc_substream_to_rtd(substream);
struct snd_soc_pcm_runtime *fe;
struct snd_soc_pcm_runtime *fe = mca_be_get_fe(be, substream->stream);
struct mca_cluster *cl = mca_dai_to_cluster(dai);
struct mca_cluster *fe_cl;
struct mca_data *mca = cl->host;
struct snd_soc_dpcm *dpcm;
fe = NULL;
for_each_dpcm_fe(be, substream->stream, dpcm) {
if (fe && dpcm->fe != fe) {
dev_err(mca->dev, "many FE per one BE unsupported\n");
return -EINVAL;
}
fe = dpcm->fe;
}
if (!fe)
return -EINVAL;
fe_cl = mca_dai_to_cluster(snd_soc_rtd_to_cpu(fe, 0));
if (mca_be_started(cl)) {
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no),
cl->base + REG_PORT_DATA_SEL);
mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_TX_DATA,
PORT_ENABLES_TX_DATA);
}
if (!fe_cl->clk_provider)
return 0;
if (mca_be_clk_started(cl)) {
/*
* Port is already started in the other direction.
* Make sure there isn't a conflict with another cluster
* driving the port.
* driving the port clocks.
*/
if (cl->port_driver != fe_cl->no)
if (cl->port_clk_driver != fe_cl->no)
return -EINVAL;
cl->port_started[substream->stream] = true;
cl->port_clk_started[substream->stream] = true;
return 0;
}
writel_relaxed(PORT_ENABLES_CLOCKS | PORT_ENABLES_TX_DATA,
cl->base + REG_PORT_ENABLES);
writel_relaxed(FIELD_PREP(PORT_CLOCK_SEL, fe_cl->no + 1),
cl->base + REG_PORT_CLOCK_SEL);
writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no),
cl->base + REG_PORT_DATA_SEL);
mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_CLOCKS,
PORT_ENABLES_CLOCKS);
scoped_guard(mutex, &mca->port_mutex)
cl->port_driver = fe_cl->no;
cl->port_started[substream->stream] = true;
cl->port_clk_driver = fe_cl->no;
cl->port_clk_started[substream->stream] = true;
return 0;
}
@@ -773,20 +888,34 @@ static int mca_be_startup(struct snd_pcm_substream *substream,
static void mca_be_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *be = snd_soc_substream_to_rtd(substream);
struct snd_soc_pcm_runtime *fe = mca_be_get_fe(be, substream->stream);
struct mca_cluster *cl = mca_dai_to_cluster(dai);
struct mca_cluster *fe_cl;
struct mca_data *mca = cl->host;
cl->port_started[substream->stream] = false;
if (!fe)
return;
fe_cl = mca_dai_to_cluster(snd_soc_rtd_to_cpu(fe, 0));
if (!mca_be_started(cl)) {
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_TX_DATA, 0);
writel_relaxed(0, cl->base + REG_PORT_DATA_SEL);
}
if (!fe_cl->clk_provider)
return;
cl->port_clk_started[substream->stream] = false;
if (!mca_be_clk_started(cl)) {
/*
* Were we the last direction to shutdown?
* Turn off the lights.
* Turn off the lights (clocks).
*/
writel_relaxed(0, cl->base + REG_PORT_ENABLES);
writel_relaxed(0, cl->base + REG_PORT_DATA_SEL);
mca_modify(cl, REG_PORT_ENABLES, PORT_ENABLES_CLOCKS, 0);
writel_relaxed(0, cl->base + REG_PORT_CLOCK_SEL);
scoped_guard(mutex, &mca->port_mutex)
cl->port_driver = -1;
cl->port_clk_driver = -1;
}
}
@@ -1092,7 +1221,7 @@ static int apple_mca_probe(struct platform_device *pdev)
cl->host = mca;
cl->no = i;
cl->base = base + CLUSTER_STRIDE * i;
cl->port_driver = -1;
cl->port_clk_driver = -1;
cl->clk_parent = of_clk_get(pdev->dev.of_node, i);
if (IS_ERR(cl->clk_parent)) {
dev_err(&pdev->dev, "unable to obtain clock %d: %ld\n",

View File

@@ -540,12 +540,16 @@ static int atmel_i2s_dai_probe(struct snd_soc_dai *dai)
return 0;
}
static const u64 atmel_i2s_selectable_formats = SND_SOC_POSSIBLE_DAIFMT_I2S;
static const struct snd_soc_dai_ops atmel_i2s_dai_ops = {
.probe = atmel_i2s_dai_probe,
.prepare = atmel_i2s_prepare,
.trigger = atmel_i2s_trigger,
.hw_params = atmel_i2s_hw_params,
.set_fmt = atmel_i2s_set_dai_fmt,
.auto_selectable_formats = &atmel_i2s_selectable_formats,
.num_auto_selectable_formats = 1,
};
static struct snd_soc_dai_driver atmel_i2s_dai = {

View File

@@ -825,6 +825,11 @@ static int atmel_ssc_resume(struct snd_soc_component *component)
#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S32_LE)
static const u64 atmel_ssc_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
SND_SOC_POSSIBLE_DAIFMT_DSP_A;
static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
.startup = atmel_ssc_startup,
.shutdown = atmel_ssc_shutdown,
@@ -833,6 +838,8 @@ static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
.hw_params = atmel_ssc_hw_params,
.set_fmt = atmel_ssc_set_dai_fmt,
.set_clkdiv = atmel_ssc_set_dai_clkdiv,
.auto_selectable_formats = &atmel_ssc_selectable_formats,
.num_auto_selectable_formats = 1,
};
static struct snd_soc_dai_driver atmel_ssc_dai = {

View File

@@ -82,32 +82,33 @@ static struct snd_soc_card atmel_asoc_wm8904_card = {
static int atmel_asoc_wm8904_dt_init(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct device_node *codec_np, *cpu_np;
struct snd_soc_card *card = &atmel_asoc_wm8904_card;
struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;
int ret;
if (!np) {
dev_err(&pdev->dev, "only device tree supported\n");
dev_err(dev, "only device tree supported\n");
return -EINVAL;
}
ret = snd_soc_of_parse_card_name(card, "atmel,model");
if (ret) {
dev_err(&pdev->dev, "failed to parse card name\n");
dev_err(dev, "failed to parse card name\n");
return ret;
}
ret = snd_soc_of_parse_audio_routing(card, "atmel,audio-routing");
if (ret) {
dev_err(&pdev->dev, "failed to parse audio routing\n");
dev_err(dev, "failed to parse audio routing\n");
return ret;
}
cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
if (!cpu_np) {
dev_err(&pdev->dev, "failed to get dai and pcm info\n");
dev_err(dev, "failed to get dai and pcm info\n");
ret = -EINVAL;
return ret;
}
@@ -117,7 +118,7 @@ static int atmel_asoc_wm8904_dt_init(struct platform_device *pdev)
codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
if (!codec_np) {
dev_err(&pdev->dev, "failed to get codec info\n");
dev_err(dev, "failed to get codec info\n");
ret = -EINVAL;
return ret;
}

View File

@@ -912,6 +912,13 @@ static int mchp_i2s_mcc_dai_probe(struct snd_soc_dai *dai)
return 0;
}
static const u64 mchp_i2s_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
SND_SOC_POSSIBLE_DAIFMT_DSP_A |
SND_SOC_POSSIBLE_DAIFMT_GATED |
SND_SOC_POSSIBLE_DAIFMT_NB_NF;
static const struct snd_soc_dai_ops mchp_i2s_mcc_dai_ops = {
.probe = mchp_i2s_mcc_dai_probe,
.set_sysclk = mchp_i2s_mcc_set_sysclk,
@@ -922,6 +929,8 @@ static const struct snd_soc_dai_ops mchp_i2s_mcc_dai_ops = {
.hw_free = mchp_i2s_mcc_hw_free,
.set_fmt = mchp_i2s_mcc_set_dai_fmt,
.set_tdm_slot = mchp_i2s_mcc_set_dai_tdm_slot,
.auto_selectable_formats = &mchp_i2s_selectable_formats,
.num_auto_selectable_formats = 1,
};
#define MCHP_I2SMCC_RATES SNDRV_PCM_RATE_8000_192000

View File

@@ -741,6 +741,8 @@ static int mchp_pdmc_pcm_new(struct snd_soc_pcm_runtime *rtd,
return ret;
}
static const u64 mchp_selectable_formats = SND_SOC_POSSIBLE_DAIFMT_PDM;
static const struct snd_soc_dai_ops mchp_pdmc_dai_ops = {
.probe = mchp_pdmc_dai_probe,
.set_fmt = mchp_pdmc_set_fmt,
@@ -748,6 +750,8 @@ static const struct snd_soc_dai_ops mchp_pdmc_dai_ops = {
.hw_params = mchp_pdmc_hw_params,
.trigger = mchp_pdmc_trigger,
.pcm_new = &mchp_pdmc_pcm_new,
.auto_selectable_formats = &mchp_selectable_formats,
.num_auto_selectable_formats = 1,
};
static struct snd_soc_dai_driver mchp_pdmc_dai = {

View File

@@ -42,7 +42,7 @@ static const struct platform_device_id db1200_pids[] = {
.name = "db1550-i2s",
.driver_data = 5,
},
{},
{ }
};
MODULE_DEVICE_TABLE(platform, db1200_pids);

View File

@@ -202,11 +202,22 @@ static int au1xi2s_startup(struct snd_pcm_substream *substream,
return 0;
}
static const u64 au1xi2s_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_RIGHT_J |
SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
SND_SOC_POSSIBLE_DAIFMT_NB_NF |
SND_SOC_POSSIBLE_DAIFMT_NB_IF |
SND_SOC_POSSIBLE_DAIFMT_IB_NF |
SND_SOC_POSSIBLE_DAIFMT_IB_IF;
static const struct snd_soc_dai_ops au1xi2s_dai_ops = {
.startup = au1xi2s_startup,
.trigger = au1xi2s_trigger,
.hw_params = au1xi2s_hw_params,
.set_fmt = au1xi2s_set_fmt,
.auto_selectable_formats = &au1xi2s_selectable_formats,
.num_auto_selectable_formats = 1,
};
static struct snd_soc_dai_driver au1xi2s_dai_driver = {

View File

@@ -210,9 +210,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
{
struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai);
unsigned long r, ro, stat;
int chans, t, stype = substream->stream;
chans = params_channels(params);
int t, stype = substream->stream;
r = ro = __raw_readl(AC97_CFG(pscdata));
stat = __raw_readl(AC97_STAT(pscdata));

View File

@@ -262,11 +262,22 @@ static int au1xpsc_i2s_startup(struct snd_pcm_substream *substream,
return 0;
}
static const u64 au1xpsc_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_RIGHT_J |
SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
SND_SOC_POSSIBLE_DAIFMT_NB_NF |
SND_SOC_POSSIBLE_DAIFMT_NB_IF |
SND_SOC_POSSIBLE_DAIFMT_IB_NF |
SND_SOC_POSSIBLE_DAIFMT_IB_IF;
static const struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
.startup = au1xpsc_i2s_startup,
.trigger = au1xpsc_i2s_trigger,
.hw_params = au1xpsc_i2s_hw_params,
.set_fmt = au1xpsc_i2s_set_fmt,
.auto_selectable_formats = &au1xpsc_selectable_formats,
.num_auto_selectable_formats = 1,
};
static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = {

View File

@@ -748,6 +748,17 @@ static int bcm2835_i2s_dai_probe(struct snd_soc_dai *dai)
return 0;
}
static const u64 bcm2835_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_RIGHT_J |
SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
SND_SOC_POSSIBLE_DAIFMT_DSP_A |
SND_SOC_POSSIBLE_DAIFMT_DSP_B |
SND_SOC_POSSIBLE_DAIFMT_NB_NF |
SND_SOC_POSSIBLE_DAIFMT_NB_IF |
SND_SOC_POSSIBLE_DAIFMT_IB_NF |
SND_SOC_POSSIBLE_DAIFMT_IB_IF;
static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = {
.probe = bcm2835_i2s_dai_probe,
.startup = bcm2835_i2s_startup,
@@ -758,6 +769,8 @@ static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = {
.set_fmt = bcm2835_i2s_set_dai_fmt,
.set_bclk_ratio = bcm2835_i2s_set_dai_bclk_ratio,
.set_tdm_slot = bcm2835_i2s_set_dai_tdm_slot,
.auto_selectable_formats = &bcm2835_selectable_formats,
.num_auto_selectable_formats = 1,
};
static struct snd_soc_dai_driver bcm2835_i2s_dai = {

View File

@@ -1133,6 +1133,11 @@ static int cygnus_ssp_resume(struct snd_soc_component *component)
#define cygnus_ssp_resume NULL
#endif
static const u64 cygnus_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_DSP_A |
SND_SOC_POSSIBLE_DAIFMT_DSP_B;
static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = {
.startup = cygnus_ssp_startup,
.shutdown = cygnus_ssp_shutdown,
@@ -1141,6 +1146,8 @@ static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = {
.set_fmt = cygnus_ssp_set_fmt,
.set_sysclk = cygnus_ssp_set_sysclk,
.set_tdm_slot = cygnus_set_dai_tdm_slot,
.auto_selectable_formats = &cygnus_selectable_formats,
.num_auto_selectable_formats = 1,
};
static const struct snd_soc_dai_ops cygnus_spdif_dai_ops = {

View File

@@ -401,6 +401,15 @@ static int ep93xx_i2s_resume(struct snd_soc_component *component)
#define ep93xx_i2s_resume NULL
#endif
static const u64 ep93xx_selectable_formats =
SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_RIGHT_J |
SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
SND_SOC_POSSIBLE_DAIFMT_NB_NF |
SND_SOC_POSSIBLE_DAIFMT_NB_IF |
SND_SOC_POSSIBLE_DAIFMT_IB_NF |
SND_SOC_POSSIBLE_DAIFMT_IB_IF;
static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
.probe = ep93xx_i2s_dai_probe,
.startup = ep93xx_i2s_startup,
@@ -408,6 +417,8 @@ static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
.hw_params = ep93xx_i2s_hw_params,
.set_sysclk = ep93xx_i2s_set_sysclk,
.set_fmt = ep93xx_i2s_set_dai_fmt,
.auto_selectable_formats = &ep93xx_selectable_formats,
.num_auto_selectable_formats = 1,
};
#define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)

View File

@@ -367,6 +367,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_WSA881X
imply SND_SOC_WSA883X
imply SND_SOC_WSA884X
imply SND_SOC_WSA885X
imply SND_SOC_ZL38060
help
Normally ASoC codec drivers are only built if a machine driver which
@@ -615,8 +616,8 @@ config SND_SOC_AK4613
depends on I2C
config SND_SOC_AK4619
tristate "AKM AK4619 CODEC"
depends on I2C
tristate "AKM AK4619 CODEC"
depends on I2C
config SND_SOC_AK4642
tristate "AKM AK4642 CODEC"
@@ -726,6 +727,10 @@ config SND_SOC_AW87390
sound quality, which is a new high efficiency, low
noise, constant large volume, 6th Smart K audio amplifier.
config SND_SOC_AW88399_LIB
tristate
select SND_SOC_AW88395_LIB
config SND_SOC_AW88399
tristate "Soc Audio for awinic aw88399"
depends on I2C
@@ -733,6 +738,7 @@ config SND_SOC_AW88399
select REGMAP_I2C
select GPIOLIB
select SND_SOC_AW88395_LIB
select SND_SOC_AW88399_LIB
help
This option enables support for aw88399 Smart PA.
The awinic AW88399 is an I2S/TDM input, high efficiency
@@ -1201,16 +1207,16 @@ config SND_SOC_JZ4725B_CODEC
will be called snd-soc-jz4725b-codec.
config SND_SOC_JZ4760_CODEC
depends on MACH_INGENIC || COMPILE_TEST
depends on OF
select REGMAP
tristate "Ingenic JZ4760 internal CODEC"
help
Enable support for the internal CODEC found in the JZ4760 SoC
from Ingenic.
depends on MACH_INGENIC || COMPILE_TEST
depends on OF
select REGMAP
tristate "Ingenic JZ4760 internal CODEC"
help
Enable support for the internal CODEC found in the JZ4760 SoC
from Ingenic.
This driver can also be built as a module. If so, the module
will be called snd-soc-jz4760-codec.
This driver can also be built as a module. If so, the module
will be called snd-soc-jz4760-codec.
config SND_SOC_JZ4770_CODEC
depends on MACH_INGENIC || COMPILE_TEST
@@ -1888,7 +1894,7 @@ config SND_SOC_RT5670
depends on I2C
config SND_SOC_RT5677
tristate
tristate "Realtek RT5677 Codec"
depends on I2C
select REGMAP_I2C
select REGMAP_IRQ
@@ -2296,8 +2302,8 @@ config SND_SOC_TLV320ADC3XXX
depends on I2C
depends on GPIOLIB
help
Enable support for Texas Instruments TLV320ADC3001 and TLV320ADC3101
ADCs.
Enable support for Texas Instruments TLV320ADC3001 and TLV320ADC3101
ADCs.
config SND_SOC_TLV320AIC23
tristate
@@ -2770,6 +2776,16 @@ config SND_SOC_WSA884X
This enables support for Qualcomm WSA8840/WSA8845/WSA8845H Class-D
Smart Speaker Amplifier.
config SND_SOC_WSA885X
tristate "WSA885X Codec"
depends on I2C
select REGMAP_I2C
help
This enables support for Qualcomm WSA885X Stereo Smart Speaker
Amplifier. The codec driver programs the amplifier register
map and exposes the DAI and mixer controls used by Qualcomm
audio machine drivers.
config SND_SOC_ZL38060
tristate "Microsemi ZL38060 Connected Home Audio Processor"
depends on SPI_MASTER
@@ -2893,28 +2909,32 @@ config SND_SOC_TPA6130A2
depends on I2C
config SND_SOC_LPASS_MACRO_COMMON
tristate
tristate
config SND_SOC_LPASS_WSA_MACRO
depends on COMMON_CLK
depends on PM_CLK
select REGMAP_MMIO
select SND_SOC_LPASS_MACRO_COMMON
tristate "Qualcomm WSA Macro in LPASS(Low Power Audio SubSystem)"
config SND_SOC_LPASS_VA_MACRO
depends on COMMON_CLK
depends on PM_CLK
select REGMAP_MMIO
select SND_SOC_LPASS_MACRO_COMMON
tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)"
config SND_SOC_LPASS_RX_MACRO
depends on COMMON_CLK
depends on PM_CLK
select REGMAP_MMIO
select SND_SOC_LPASS_MACRO_COMMON
tristate "Qualcomm RX Macro in LPASS(Low Power Audio SubSystem)"
config SND_SOC_LPASS_TX_MACRO
depends on COMMON_CLK
depends on PM_CLK
select REGMAP_MMIO
select SND_SOC_LPASS_MACRO_COMMON
tristate "Qualcomm TX Macro in LPASS(Low Power Audio SubSystem)"

View File

@@ -55,6 +55,7 @@ snd-soc-aw88395-y := aw88395/aw88395.o
snd-soc-aw88166-y := aw88166.o
snd-soc-aw88261-y := aw88261.o
snd-soc-aw88399-y := aw88399.o
snd-soc-aw88399-lib-y := aw88399-lib.o
snd-soc-bd28623-y := bd28623.o
snd-soc-bt-sco-y := bt-sco.o
snd-soc-chv3-codec-y := chv3-codec.o
@@ -426,6 +427,7 @@ snd-soc-wm-hubs-y := wm_hubs.o
snd-soc-wsa881x-y := wsa881x.o
snd-soc-wsa883x-y := wsa883x.o
snd-soc-wsa884x-y := wsa884x.o
snd-soc-wsa885x-y := wsa885x.o
snd-soc-zl38060-y := zl38060.o
# Amp
snd-soc-max9877-y := max9877.o
@@ -496,6 +498,7 @@ obj-$(CONFIG_SND_SOC_AW88395) +=snd-soc-aw88395.o
obj-$(CONFIG_SND_SOC_AW88166) +=snd-soc-aw88166.o
obj-$(CONFIG_SND_SOC_AW88261) +=snd-soc-aw88261.o
obj-$(CONFIG_SND_SOC_AW88399) += snd-soc-aw88399.o
obj-$(CONFIG_SND_SOC_AW88399_LIB) += snd-soc-aw88399-lib.o
obj-$(CONFIG_SND_SOC_BD28623) += snd-soc-bd28623.o
obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o
obj-$(CONFIG_SND_SOC_CHV3_CODEC) += snd-soc-chv3-codec.o
@@ -876,6 +879,7 @@ 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
obj-$(CONFIG_SND_SOC_WSA884X) += snd-soc-wsa884x.o
obj-$(CONFIG_SND_SOC_WSA885X) += snd-soc-wsa885x.o
obj-$(CONFIG_SND_SOC_ZL38060) += snd-soc-zl38060.o
# Amp

View File

@@ -14,6 +14,7 @@
* for ST-Ericsson.
*/
#include <linux/cleanup.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
@@ -989,9 +990,8 @@ static int sid_status_control_get(struct snd_kcontrol *kcontrol,
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
mutex_lock(&drvdata->ctrl_lock);
guard(mutex)(&drvdata->ctrl_lock);
ucontrol->value.enumerated.item[0] = drvdata->sid_status;
mutex_unlock(&drvdata->ctrl_lock);
return 0;
}
@@ -1014,7 +1014,7 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
return -EIO;
}
mutex_lock(&drvdata->ctrl_lock);
guard(mutex)(&drvdata->ctrl_lock);
sidconf = snd_soc_component_read(component, AB8500_SIDFIRCONF);
if (((sidconf & BIT(AB8500_SIDFIRCONF_FIRSIDBUSY)) != 0)) {
@@ -1025,7 +1025,8 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
} else {
status = -EBUSY;
}
goto out;
dev_dbg(component->dev, "%s: Exit\n", __func__);
return status;
}
snd_soc_component_write(component, AB8500_SIDFIRADR, 0);
@@ -1043,9 +1044,6 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
drvdata->sid_status = SID_FIR_CONFIGURED;
out:
mutex_unlock(&drvdata->ctrl_lock);
dev_dbg(component->dev, "%s: Exit\n", __func__);
return status;

View File

@@ -22,7 +22,7 @@ static const struct of_device_id adau7118_of_match[] = {
MODULE_DEVICE_TABLE(of, adau7118_of_match);
static const struct platform_device_id adau7118_id[] = {
{ .name = "adau7118" },
{ .name = "adau7118" },
{ }
};
MODULE_DEVICE_TABLE(platform, adau7118_id);

View File

@@ -95,6 +95,7 @@
* see
* AK4613_ENABLE_TDM_TEST
*/
#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/i2c.h>
@@ -384,7 +385,7 @@ static void ak4613_dai_shutdown(struct snd_pcm_substream *substream,
struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
struct device *dev = component->dev;
mutex_lock(&priv->lock);
guard(mutex)(&priv->lock);
priv->cnt--;
if (priv->cnt < 0) {
dev_err(dev, "unexpected counter error\n");
@@ -392,7 +393,6 @@ static void ak4613_dai_shutdown(struct snd_pcm_substream *substream,
}
if (!priv->cnt)
priv->ctrl1 = 0;
mutex_unlock(&priv->lock);
}
static void ak4613_hw_constraints(struct ak4613_priv *priv,
@@ -507,10 +507,9 @@ static int ak4613_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component;
struct ak4613_priv *priv = snd_soc_component_get_drvdata(component);
mutex_lock(&priv->lock);
guard(mutex)(&priv->lock);
ak4613_hw_constraints(priv, substream);
priv->cnt++;
mutex_unlock(&priv->lock);
return 0;
}
@@ -599,45 +598,47 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
*/
ret = -EINVAL;
mutex_lock(&priv->lock);
if (priv->cnt > 1) {
/*
* If it was already working, use current priv->ctrl1
*/
ret = 0;
} else {
/*
* It is not yet working,
*/
unsigned int channel = params_channels(params);
u8 tdm;
scoped_guard(mutex, &priv->lock) {
if (priv->cnt > 1) {
/*
* If it was already working, use current priv->ctrl1
*/
ret = 0;
} else {
/*
* It is not yet working,
*/
unsigned int channel = params_channels(params);
u8 tdm;
/* STEREO or TDM */
if (channel == 2)
tdm = AK4613_CONFIG_MODE_STEREO;
else
tdm = AK4613_CONFIG_GET(priv, MODE);
/* STEREO or TDM */
if (channel == 2)
tdm = AK4613_CONFIG_MODE_STEREO;
else
tdm = AK4613_CONFIG_GET(priv, MODE);
for (i = ARRAY_SIZE(ak4613_iface) - 1; i >= 0; i--) {
const struct ak4613_interface *iface = ak4613_iface + i;
for (i = ARRAY_SIZE(ak4613_iface) - 1; i >= 0; i--) {
const struct ak4613_interface *iface = ak4613_iface + i;
if ((iface->fmt == fmt) && (iface->width == width)) {
/*
* Ctrl1
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
* |TDM1|TDM0|DIF2|DIF1|DIF0|ATS1|ATS0|SMUTE|
* < tdm > < iface->dif >
*/
priv->ctrl1 = (tdm << 6) | (iface->dif << 3);
ret = 0;
break;
if (iface->fmt == fmt && iface->width == width) {
/*
* Ctrl1
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
* |TDM1|TDM0|DIF2|DIF1|DIF0|ATS1|ATS0|SMUTE|
* < tdm > < iface->dif >
*/
priv->ctrl1 = (tdm << 6) | (iface->dif << 3);
ret = 0;
break;
}
}
}
}
mutex_unlock(&priv->lock);
if (ret < 0)
goto hw_params_end;
if (ret < 0) {
dev_warn(dev, "unsupported data width/format combination\n");
return ret;
}
snd_soc_component_update_bits(component, CTRL1, FMT_MASK, priv->ctrl1);
snd_soc_component_update_bits(component, CTRL2, DFS_MASK, ctrl2);
@@ -645,10 +646,6 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
snd_soc_component_update_bits(component, ICTRL, ICTRL_MASK, priv->ic);
snd_soc_component_update_bits(component, OCTRL, OCTRL_MASK, priv->oc);
hw_params_end:
if (ret < 0)
dev_warn(dev, "unsupported data width/format combination\n");
return ret;
}

View File

@@ -5,6 +5,7 @@
* Copyright (C) 2012-2014 Wolfson Microelectronics plc
*/
#include <linux/cleanup.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -707,15 +708,13 @@ static void arizona_micd_timeout_work(struct work_struct *work)
struct arizona_priv,
micd_timeout_work.work);
mutex_lock(&info->lock);
guard(mutex)(&info->lock);
dev_dbg(info->arizona->dev, "MICD timed out, reporting HP\n");
info->detecting = false;
arizona_identify_headphone(info);
mutex_unlock(&info->lock);
}
static int arizona_micd_adc_read(struct arizona_priv *info)
@@ -921,12 +920,11 @@ static void arizona_micd_detect(struct work_struct *work)
cancel_delayed_work_sync(&info->micd_timeout_work);
mutex_lock(&info->lock);
guard(mutex)(&info->lock);
/* If the cable was removed while measuring ignore the result */
if (!(info->jack->status & SND_JACK_MECHANICAL)) {
dev_dbg(arizona->dev, "Ignoring MICDET for removed cable\n");
mutex_unlock(&info->lock);
return;
}
@@ -936,7 +934,6 @@ static void arizona_micd_detect(struct work_struct *work)
arizona_button_reading(info);
pm_runtime_mark_last_busy(arizona->dev);
mutex_unlock(&info->lock);
}
static irqreturn_t arizona_micdet(int irq, void *data)
@@ -948,10 +945,10 @@ static irqreturn_t arizona_micdet(int irq, void *data)
cancel_delayed_work_sync(&info->micd_detect_work);
cancel_delayed_work_sync(&info->micd_timeout_work);
mutex_lock(&info->lock);
if (!info->detecting)
debounce = 0;
mutex_unlock(&info->lock);
scoped_guard(mutex, &info->lock) {
if (!info->detecting)
debounce = 0;
}
if (debounce)
queue_delayed_work(system_power_efficient_wq,
@@ -969,9 +966,8 @@ static void arizona_hpdet_work(struct work_struct *work)
struct arizona_priv,
hpdet_work.work);
mutex_lock(&info->lock);
guard(mutex)(&info->lock);
arizona_start_hpdet_acc_id(info);
mutex_unlock(&info->lock);
}
static int arizona_hpdet_wait(struct arizona_priv *info)
@@ -1018,9 +1014,9 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
cancelled_hp = cancel_delayed_work_sync(&info->hpdet_work);
cancelled_mic = cancel_delayed_work_sync(&info->micd_timeout_work);
pm_runtime_get_sync(arizona->dev);
guard(pm_runtime_active_auto)(arizona->dev);
mutex_lock(&info->lock);
guard(mutex)(&info->lock);
if (info->micd_clamp) {
mask = ARIZONA_MICD_CLAMP_STS;
@@ -1036,8 +1032,6 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
if (ret) {
dev_err(arizona->dev, "Failed to read jackdet status: %d\n", ret);
mutex_unlock(&info->lock);
pm_runtime_put_autosuspend(arizona->dev);
return IRQ_NONE;
}
@@ -1056,62 +1050,61 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
&info->micd_timeout_work,
msecs_to_jiffies(micd_timeout));
}
} else {
info->last_jackdet = val;
goto out;
}
info->last_jackdet = val;
if (info->last_jackdet == present) {
dev_dbg(arizona->dev, "Detected jack\n");
snd_soc_jack_report(info->jack, SND_JACK_MECHANICAL, SND_JACK_MECHANICAL);
if (info->last_jackdet == present) {
dev_dbg(arizona->dev, "Detected jack\n");
snd_soc_jack_report(info->jack, SND_JACK_MECHANICAL, SND_JACK_MECHANICAL);
info->detecting = true;
info->mic = false;
info->jack_flips = 0;
info->detecting = true;
info->mic = false;
info->jack_flips = 0;
if (!arizona->pdata.hpdet_acc_id) {
arizona_start_mic(info);
} else {
queue_delayed_work(system_power_efficient_wq,
&info->hpdet_work,
msecs_to_jiffies(HPDET_DEBOUNCE));
}
if (!arizona->pdata.hpdet_acc_id) {
arizona_start_mic(info);
if (info->micd_clamp || !arizona->pdata.jd_invert)
regmap_update_bits(arizona->regmap,
ARIZONA_JACK_DETECT_DEBOUNCE,
ARIZONA_MICD_CLAMP_DB |
ARIZONA_JD1_DB, 0);
} else {
queue_delayed_work(system_power_efficient_wq,
&info->hpdet_work,
msecs_to_jiffies(HPDET_DEBOUNCE));
}
dev_dbg(arizona->dev, "Detected jack removal\n");
arizona_stop_mic(info);
info->num_hpdet_res = 0;
for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
info->hpdet_res[i] = 0;
info->mic = false;
info->hpdet_done = false;
info->hpdet_retried = false;
snd_soc_jack_report(info->jack, 0,
ARIZONA_JACK_MASK | info->micd_button_mask);
/*
* If the jack was removed during a headphone detection we
* need to wait for the headphone detection to finish, as
* it can not be aborted. We don't want to be able to start
* a new headphone detection from a fresh insert until this
* one is finished.
*/
arizona_hpdet_wait(info);
if (info->micd_clamp || !arizona->pdata.jd_invert)
regmap_update_bits(arizona->regmap,
ARIZONA_JACK_DETECT_DEBOUNCE,
ARIZONA_MICD_CLAMP_DB |
ARIZONA_JD1_DB, 0);
} else {
dev_dbg(arizona->dev, "Detected jack removal\n");
arizona_stop_mic(info);
info->num_hpdet_res = 0;
for (i = 0; i < ARRAY_SIZE(info->hpdet_res); i++)
info->hpdet_res[i] = 0;
info->mic = false;
info->hpdet_done = false;
info->hpdet_retried = false;
snd_soc_jack_report(info->jack, 0, ARIZONA_JACK_MASK | info->micd_button_mask);
/*
* If the jack was removed during a headphone detection we
* need to wait for the headphone detection to finish, as
* it can not be aborted. We don't want to be able to start
* a new headphone detection from a fresh insert until this
* one is finished.
*/
arizona_hpdet_wait(info);
regmap_update_bits(arizona->regmap,
ARIZONA_JACK_DETECT_DEBOUNCE,
ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,
ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB,
ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB);
}
}
out:
/* Clear trig_sts to make sure DCVDD is not forced up */
regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
@@ -1119,10 +1112,6 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
ARIZONA_JD1_FALL_TRIG_STS |
ARIZONA_JD1_RISE_TRIG_STS);
mutex_unlock(&info->lock);
pm_runtime_put_autosuspend(arizona->dev);
return IRQ_HANDLED;
}

View File

@@ -7,6 +7,7 @@
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*/
#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/gcd.h>
#include <linux/module.h>
@@ -1158,17 +1159,16 @@ int arizona_dvfs_up(struct snd_soc_component *component, unsigned int flags)
struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
int ret = 0;
mutex_lock(&priv->dvfs_lock);
guard(mutex)(&priv->dvfs_lock);
if (!priv->dvfs_cached && !priv->dvfs_reqs) {
ret = arizona_dvfs_enable(component);
if (ret)
goto err;
return ret;
}
priv->dvfs_reqs |= flags;
err:
mutex_unlock(&priv->dvfs_lock);
return ret;
}
EXPORT_SYMBOL_GPL(arizona_dvfs_up);
@@ -1179,7 +1179,7 @@ int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags)
unsigned int old_reqs;
int ret = 0;
mutex_lock(&priv->dvfs_lock);
guard(mutex)(&priv->dvfs_lock);
old_reqs = priv->dvfs_reqs;
priv->dvfs_reqs &= ~flags;
@@ -1187,7 +1187,6 @@ int arizona_dvfs_down(struct snd_soc_component *component, unsigned int flags)
if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
ret = arizona_dvfs_disable(component);
mutex_unlock(&priv->dvfs_lock);
return ret;
}
EXPORT_SYMBOL_GPL(arizona_dvfs_down);
@@ -1199,7 +1198,7 @@ int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
struct arizona_priv *priv = snd_soc_component_get_drvdata(component);
int ret = 0;
mutex_lock(&priv->dvfs_lock);
guard(mutex)(&priv->dvfs_lock);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
@@ -1222,7 +1221,6 @@ int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
break;
}
mutex_unlock(&priv->dvfs_lock);
return ret;
}
EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev);
@@ -1657,13 +1655,11 @@ static void arizona_wm5102_set_dac_comp(struct snd_soc_component *component,
{ 0x80, 0x0 },
};
mutex_lock(&arizona->dac_comp_lock);
dac_comp[1].def = arizona->dac_comp_coeff;
if (rate >= 176400)
dac_comp[2].def = arizona->dac_comp_enabled;
mutex_unlock(&arizona->dac_comp_lock);
scoped_guard(mutex, &arizona->dac_comp_lock) {
dac_comp[1].def = arizona->dac_comp_coeff;
if (rate >= 176400)
dac_comp[2].def = arizona->dac_comp_enabled;
}
regmap_multi_reg_write(arizona->regmap,
dac_comp,

View File

@@ -7,6 +7,7 @@
// Author: Weidong Wang <wangweidong.a@awinic.com>
//
#include <linux/cleanup.h>
#include <linux/i2c.h>
#include <linux/firmware.h>
#include <linux/regmap.h>
@@ -225,11 +226,10 @@ static int aw87390_profile_set(struct snd_kcontrol *kcontrol,
struct aw87390 *aw87390 = snd_soc_component_get_drvdata(codec);
int ret;
mutex_lock(&aw87390->lock);
guard(mutex)(&aw87390->lock);
ret = aw87390_dev_set_profile_index(aw87390->aw_pa, ucontrol->value.integer.value[0]);
if (ret) {
dev_dbg(codec->dev, "profile index does not change\n");
mutex_unlock(&aw87390->lock);
return 0;
}
@@ -238,8 +238,6 @@ static int aw87390_profile_set(struct snd_kcontrol *kcontrol,
aw87390_power_on(aw87390->aw_pa);
}
mutex_unlock(&aw87390->lock);
return 1;
}
@@ -280,14 +278,12 @@ static int aw87390_request_firmware_file(struct aw87390 *aw87390)
return ret;
}
mutex_lock(&aw87390->lock);
guard(mutex)(&aw87390->lock);
ret = aw88395_dev_cfg_load(aw87390->aw_pa, aw87390->aw_cfg);
if (ret)
dev_err(aw87390->aw_pa->dev, "aw_dev acf parse failed\n");
mutex_unlock(&aw87390->lock);
return ret;
}

View File

@@ -7,6 +7,7 @@
// Author: Weidong Wang <wangweidong.a@awinic.com>
//
#include <linux/cleanup.h>
#include <linux/firmware.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
@@ -763,9 +764,8 @@ static void aw88081_startup_work(struct work_struct *work)
struct aw88081 *aw88081 =
container_of(work, struct aw88081, start_work.work);
mutex_lock(&aw88081->lock);
guard(mutex)(&aw88081->lock);
aw88081_start_pa(aw88081);
mutex_unlock(&aw88081->lock);
}
static void aw88081_start(struct aw88081 *aw88081, bool sync_start)
@@ -942,11 +942,10 @@ static int aw88081_profile_set(struct snd_kcontrol *kcontrol,
int ret;
/* pa stop or stopping just set profile */
mutex_lock(&aw88081->lock);
guard(mutex)(&aw88081->lock);
ret = aw88081_dev_set_profile_index(aw88081->aw_pa, ucontrol->value.integer.value[0]);
if (ret) {
dev_dbg(codec->dev, "profile index does not change");
mutex_unlock(&aw88081->lock);
return 0;
}
@@ -955,8 +954,6 @@ static int aw88081_profile_set(struct snd_kcontrol *kcontrol,
aw88081_start(aw88081, AW88081_SYNC_START);
}
mutex_unlock(&aw88081->lock);
return 1;
}
@@ -1165,11 +1162,9 @@ static int aw88081_request_firmware_file(struct aw88081 *aw88081)
if (ret)
return ret;
mutex_lock(&aw88081->lock);
ret = aw88081_dev_init(aw88081, aw88081->aw_cfg);
mutex_unlock(&aw88081->lock);
guard(mutex)(&aw88081->lock);
return ret;
return aw88081_dev_init(aw88081, aw88081->aw_cfg);
}
static int aw88081_playback_event(struct snd_soc_dapm_widget *w,
@@ -1178,7 +1173,7 @@ static int aw88081_playback_event(struct snd_soc_dapm_widget *w,
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct aw88081 *aw88081 = snd_soc_component_get_drvdata(component);
mutex_lock(&aw88081->lock);
guard(mutex)(&aw88081->lock);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
aw88081_start(aw88081, AW88081_ASYNC_START);
@@ -1189,7 +1184,6 @@ static int aw88081_playback_event(struct snd_soc_dapm_widget *w,
default:
break;
}
mutex_unlock(&aw88081->lock);
return 0;
}

View File

@@ -7,6 +7,7 @@
// Author: Weidong Wang <wangweidong.a@awinic.com>
//
#include <linux/cleanup.h>
#include <linux/crc32.h>
#include <linux/firmware.h>
#include <linux/gpio/consumer.h>
@@ -1173,9 +1174,8 @@ static void aw88166_startup_work(struct work_struct *work)
struct aw88166 *aw88166 =
container_of(work, struct aw88166, start_work.work);
mutex_lock(&aw88166->lock);
guard(mutex)(&aw88166->lock);
aw88166_start_pa(aw88166);
mutex_unlock(&aw88166->lock);
}
static void aw88166_start(struct aw88166 *aw88166, bool sync_start)
@@ -1413,11 +1413,10 @@ static int aw88166_profile_set(struct snd_kcontrol *kcontrol,
struct aw88166 *aw88166 = snd_soc_component_get_drvdata(codec);
int ret;
mutex_lock(&aw88166->lock);
guard(mutex)(&aw88166->lock);
ret = aw88166_dev_set_profile_index(aw88166->aw_pa, ucontrol->value.integer.value[0]);
if (ret) {
dev_dbg(codec->dev, "profile index does not change");
mutex_unlock(&aw88166->lock);
return 0;
}
@@ -1426,8 +1425,6 @@ static int aw88166_profile_set(struct snd_kcontrol *kcontrol,
aw88166_start(aw88166, AW88166_SYNC_START);
}
mutex_unlock(&aw88166->lock);
return 1;
}
@@ -1607,12 +1604,12 @@ static int aw88166_request_firmware_file(struct aw88166 *aw88166)
return ret;
}
mutex_lock(&aw88166->lock);
/* aw device init */
ret = aw88166_dev_init(aw88166, aw88166->aw_cfg);
if (ret)
dev_err(aw88166->aw_pa->dev, "dev init failed\n");
mutex_unlock(&aw88166->lock);
scoped_guard(mutex, &aw88166->lock) {
/* aw device init */
ret = aw88166_dev_init(aw88166, aw88166->aw_cfg);
if (ret)
dev_err(aw88166->aw_pa->dev, "dev init failed\n");
}
return ret;
}
@@ -1639,7 +1636,7 @@ static int aw88166_playback_event(struct snd_soc_dapm_widget *w,
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct aw88166 *aw88166 = snd_soc_component_get_drvdata(component);
mutex_lock(&aw88166->lock);
guard(mutex)(&aw88166->lock);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
aw88166_start(aw88166, AW88166_ASYNC_START);
@@ -1650,7 +1647,6 @@ static int aw88166_playback_event(struct snd_soc_dapm_widget *w,
default:
break;
}
mutex_unlock(&aw88166->lock);
return 0;
}

View File

@@ -8,6 +8,7 @@
// Author: Weidong Wang <wangweidong.a@awinic.com>
//
#include <linux/cleanup.h>
#include <linux/i2c.h>
#include <linux/firmware.h>
#include <linux/bitops.h>
@@ -206,10 +207,10 @@ static int aw88261_dev_check_sysst(struct aw_device *aw_dev)
return ret;
check_val = reg_val & (~AW88261_BIT_SYSST_CHECK_MASK)
& AW88261_BIT_SYSST_CHECK;
if (check_val != AW88261_BIT_SYSST_CHECK) {
& AW88261_BIT_PLL_CHECK;
if (check_val != AW88261_BIT_PLL_CHECK) {
dev_dbg(aw_dev->dev, "check sysst fail, reg_val=0x%04x, check:0x%x",
reg_val, AW88261_BIT_SYSST_CHECK);
reg_val, AW88261_BIT_PLL_CHECK);
usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
} else {
return 0;
@@ -960,11 +961,10 @@ static int aw88261_profile_set(struct snd_kcontrol *kcontrol,
int ret;
/* pa stop or stopping just set profile */
mutex_lock(&aw88261->lock);
guard(mutex)(&aw88261->lock);
ret = aw88261_dev_set_profile_index(aw88261->aw_pa, ucontrol->value.integer.value[0]);
if (ret) {
dev_dbg(codec->dev, "profile index does not change");
mutex_unlock(&aw88261->lock);
return 0;
}
@@ -973,8 +973,6 @@ static int aw88261_profile_set(struct snd_kcontrol *kcontrol,
aw88261_start(aw88261);
}
mutex_unlock(&aw88261->lock);
return 1;
}
@@ -1038,7 +1036,7 @@ static int aw88261_playback_event(struct snd_soc_dapm_widget *w,
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct aw88261 *aw88261 = snd_soc_component_get_drvdata(component);
mutex_lock(&aw88261->lock);
guard(mutex)(&aw88261->lock);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
aw88261_start(aw88261);
@@ -1049,7 +1047,6 @@ static int aw88261_playback_event(struct snd_soc_dapm_widget *w,
default:
break;
}
mutex_unlock(&aw88261->lock);
return 0;
}
@@ -1188,12 +1185,12 @@ static int aw88261_request_firmware_file(struct aw88261 *aw88261)
return ret;
}
mutex_lock(&aw88261->lock);
/* aw device init */
ret = aw88261_dev_init(aw88261, aw88261->aw_cfg);
if (ret)
dev_err(aw88261->aw_pa->dev, "dev init failed");
mutex_unlock(&aw88261->lock);
scoped_guard(mutex, &aw88261->lock) {
/* aw device init */
ret = aw88261_dev_init(aw88261, aw88261->aw_cfg);
if (ret)
dev_err(aw88261->aw_pa->dev, "dev init failed");
}
return ret;
}

View File

@@ -194,12 +194,6 @@
AW88261_OTHS_OT_VALUE | \
AW88261_PLLS_LOCKED_VALUE))
#define AW88261_BIT_SYSST_CHECK \
(AW88261_BSTS_FINISHED_VALUE | \
AW88261_SWS_SWITCHING_VALUE | \
AW88261_CLKS_STABLE_VALUE | \
AW88261_PLLS_LOCKED_VALUE)
#define AW88261_ULS_HMUTE_START_BIT (14)
#define AW88261_ULS_HMUTE_BITS_LEN (1)
#define AW88261_ULS_HMUTE_MASK \

View File

@@ -8,6 +8,7 @@
// Author: Weidong Wang <wangweidong.a@awinic.com>
//
#include <linux/cleanup.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/firmware.h>
@@ -51,9 +52,8 @@ static void aw88395_startup_work(struct work_struct *work)
struct aw88395 *aw88395 =
container_of(work, struct aw88395, start_work.work);
mutex_lock(&aw88395->lock);
guard(mutex)(&aw88395->lock);
aw88395_start_pa(aw88395);
mutex_unlock(&aw88395->lock);
}
static void aw88395_start(struct aw88395 *aw88395, bool sync_start)
@@ -224,11 +224,10 @@ static int aw88395_profile_set(struct snd_kcontrol *kcontrol,
int ret;
/* pa stop or stopping just set profile */
mutex_lock(&aw88395->lock);
guard(mutex)(&aw88395->lock);
ret = aw88395_dev_set_profile_index(aw88395->aw_pa, ucontrol->value.integer.value[0]);
if (ret < 0) {
dev_dbg(codec->dev, "profile index does not change");
mutex_unlock(&aw88395->lock);
return 0;
}
@@ -237,8 +236,6 @@ static int aw88395_profile_set(struct snd_kcontrol *kcontrol,
aw88395_start(aw88395, AW88395_SYNC_START);
}
mutex_unlock(&aw88395->lock);
return 1;
}
@@ -366,7 +363,7 @@ static int aw88395_playback_event(struct snd_soc_dapm_widget *w,
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(component);
mutex_lock(&aw88395->lock);
guard(mutex)(&aw88395->lock);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
aw88395_start(aw88395, AW88395_ASYNC_START);
@@ -377,7 +374,6 @@ static int aw88395_playback_event(struct snd_soc_dapm_widget *w,
default:
break;
}
mutex_unlock(&aw88395->lock);
return 0;
}
@@ -495,12 +491,12 @@ static int aw88395_request_firmware_file(struct aw88395 *aw88395)
dev_dbg(aw88395->aw_pa->dev, "%s : bin load success\n", __func__);
mutex_lock(&aw88395->lock);
/* aw device init */
ret = aw88395_dev_init(aw88395->aw_pa, aw88395->aw_cfg);
if (ret < 0)
dev_err(aw88395->aw_pa->dev, "dev init failed");
mutex_unlock(&aw88395->lock);
scoped_guard(mutex, &aw88395->lock) {
/* aw device init */
ret = aw88395_dev_init(aw88395->aw_pa, aw88395->aw_cfg);
if (ret < 0)
dev_err(aw88395->aw_pa->dev, "dev init failed");
}
return ret;
}

View File

@@ -8,6 +8,7 @@
// Author: Ben Yi <yijiangtao@awinic.com>
//
#include <linux/cleanup.h>
#include <linux/crc32.h>
#include <linux/i2c.h>
#include <linux/minmax.h>
@@ -70,7 +71,7 @@ int aw_dev_dsp_write(struct aw_device *aw_dev,
u32 reg_value;
int ret;
mutex_lock(&aw_dev->dsp_lock);
guard(mutex)(&aw_dev->dsp_lock);
switch (data_type) {
case AW_DSP_16_DATA:
ret = aw_dev_dsp_write_16bit(aw_dev, dsp_addr, dsp_data);
@@ -93,7 +94,6 @@ int aw_dev_dsp_write(struct aw_device *aw_dev,
/* clear dsp chip select state*/
if (regmap_read(aw_dev->regmap, AW88395_ID_REG, &reg_value))
dev_err(aw_dev->dev, "%s fail to clear chip state. Err=%d\n", __func__, ret);
mutex_unlock(&aw_dev->dsp_lock);
return ret;
}
@@ -156,7 +156,7 @@ int aw_dev_dsp_read(struct aw_device *aw_dev,
u32 reg_value;
int ret;
mutex_lock(&aw_dev->dsp_lock);
guard(mutex)(&aw_dev->dsp_lock);
switch (data_type) {
case AW_DSP_16_DATA:
ret = aw_dev_dsp_read_16bit(aw_dev, dsp_addr, dsp_data);
@@ -179,7 +179,6 @@ int aw_dev_dsp_read(struct aw_device *aw_dev,
/* clear dsp chip select state*/
if (regmap_read(aw_dev->regmap, AW88395_ID_REG, &reg_value))
dev_err(aw_dev->dev, "%s fail to clear chip state. Err=%d\n", __func__, ret);
mutex_unlock(&aw_dev->dsp_lock);
return ret;
}
@@ -1110,42 +1109,36 @@ static int aw_dev_dsp_update_container(struct aw_device *aw_dev,
#ifdef AW88395_DSP_I2C_WRITES
u32 tmp_len;
mutex_lock(&aw_dev->dsp_lock);
guard(mutex)(&aw_dev->dsp_lock);
ret = regmap_write(aw_dev->regmap, AW88395_DSPMADD_REG, base);
if (ret)
goto error_operation;
return ret;
for (i = 0; i < len; i += AW88395_MAX_RAM_WRITE_BYTE_SIZE) {
tmp_len = min(len - i, AW88395_MAX_RAM_WRITE_BYTE_SIZE);
ret = regmap_raw_write(aw_dev->regmap, AW88395_DSPMDAT_REG,
&data[i], tmp_len);
if (ret)
goto error_operation;
return ret;
}
mutex_unlock(&aw_dev->dsp_lock);
#else
__be16 reg_val;
mutex_lock(&aw_dev->dsp_lock);
guard(mutex)(&aw_dev->dsp_lock);
/* i2c write */
ret = regmap_write(aw_dev->regmap, AW88395_DSPMADD_REG, base);
if (ret)
goto error_operation;
return ret;
for (i = 0; i < len; i += 2) {
reg_val = cpu_to_be16p((u16 *)(data + i));
ret = regmap_write(aw_dev->regmap, AW88395_DSPMDAT_REG,
(u16)reg_val);
if (ret)
goto error_operation;
return ret;
}
mutex_unlock(&aw_dev->dsp_lock);
#endif
return 0;
error_operation:
mutex_unlock(&aw_dev->dsp_lock);
return ret;
}
static int aw_dev_dsp_update_fw(struct aw_device *aw_dev,
@@ -1231,14 +1224,14 @@ static int aw_dev_check_sram(struct aw_device *aw_dev)
{
unsigned int reg_val;
mutex_lock(&aw_dev->dsp_lock);
guard(mutex)(&aw_dev->dsp_lock);
/* check the odd bits of reg 0x40 */
regmap_write(aw_dev->regmap, AW88395_DSPMADD_REG, AW88395_DSP_ODD_NUM_BIT_TEST);
regmap_read(aw_dev->regmap, AW88395_DSPMADD_REG, &reg_val);
if (reg_val != AW88395_DSP_ODD_NUM_BIT_TEST) {
dev_err(aw_dev->dev, "check reg 0x40 odd bit failed, read[0x%x] != write[0x%x]",
reg_val, AW88395_DSP_ODD_NUM_BIT_TEST);
goto error;
return -EPERM;
}
/* check the even bits of reg 0x40 */
@@ -1247,7 +1240,7 @@ static int aw_dev_check_sram(struct aw_device *aw_dev)
if (reg_val != AW88395_DSP_EVEN_NUM_BIT_TEST) {
dev_err(aw_dev->dev, "check reg 0x40 even bit failed, read[0x%x] != write[0x%x]",
reg_val, AW88395_DSP_EVEN_NUM_BIT_TEST);
goto error;
return -EPERM;
}
/* check dsp_fw_base_addr */
@@ -1256,7 +1249,7 @@ static int aw_dev_check_sram(struct aw_device *aw_dev)
if (reg_val != AW88395_DSP_EVEN_NUM_BIT_TEST) {
dev_err(aw_dev->dev, "check dsp fw addr failed, read[0x%x] != write[0x%x]",
reg_val, AW88395_DSP_EVEN_NUM_BIT_TEST);
goto error;
return -EPERM;
}
/* check dsp_cfg_base_addr */
@@ -1265,15 +1258,10 @@ static int aw_dev_check_sram(struct aw_device *aw_dev)
if (reg_val != AW88395_DSP_ODD_NUM_BIT_TEST) {
dev_err(aw_dev->dev, "check dsp cfg failed, read[0x%x] != write[0x%x]",
reg_val, AW88395_DSP_ODD_NUM_BIT_TEST);
goto error;
return -EPERM;
}
mutex_unlock(&aw_dev->dsp_lock);
return 0;
error:
mutex_unlock(&aw_dev->dsp_lock);
return -EPERM;
}
int aw88395_dev_fw_update(struct aw_device *aw_dev, bool up_dsp_fw_en, bool force_up_en)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -10,512 +10,10 @@
#ifndef __AW88399_H__
#define __AW88399_H__
/* registers list */
#define AW88399_ID_REG (0x00)
#define AW88399_SYSST_REG (0x01)
#define AW88399_SYSINT_REG (0x02)
#define AW88399_SYSINTM_REG (0x03)
#define AW88399_SYSCTRL_REG (0x04)
#define AW88399_SYSCTRL2_REG (0x05)
#define AW88399_I2SCTRL1_REG (0x06)
#define AW88399_I2SCTRL2_REG (0x07)
#define AW88399_I2SCTRL3_REG (0x08)
#define AW88399_DACCFG1_REG (0x09)
#define AW88399_DACCFG2_REG (0x0A)
#define AW88399_DACCFG3_REG (0x0B)
#define AW88399_DACCFG4_REG (0x0C)
#define AW88399_DACCFG5_REG (0x0D)
#define AW88399_DACCFG6_REG (0x0E)
#define AW88399_DACCFG7_REG (0x0F)
#define AW88399_MPDCFG1_REG (0x10)
#define AW88399_MPDCFG2_REG (0x11)
#define AW88399_MPDCFG3_REG (0x12)
#define AW88399_MPDCFG4_REG (0x13)
#define AW88399_PWMCTRL1_REG (0x14)
#define AW88399_PWMCTRL2_REG (0x15)
#define AW88399_PWMCTRL3_REG (0x16)
#define AW88399_I2SCFG1_REG (0x17)
#define AW88399_DBGCTRL_REG (0x18)
#define AW88399_HAGCST_REG (0x20)
#define AW88399_VBAT_REG (0x21)
#define AW88399_TEMP_REG (0x22)
#define AW88399_PVDD_REG (0x23)
#define AW88399_ISNDAT_REG (0x24)
#define AW88399_VSNDAT_REG (0x25)
#define AW88399_I2SINT_REG (0x26)
#define AW88399_I2SCAPCNT_REG (0x27)
#define AW88399_ANASTA1_REG (0x28)
#define AW88399_ANASTA2_REG (0x29)
#define AW88399_ANASTA3_REG (0x2A)
#define AW88399_TESTDET_REG (0x2B)
#define AW88399_DSMCFG1_REG (0x30)
#define AW88399_DSMCFG2_REG (0x31)
#define AW88399_DSMCFG3_REG (0x32)
#define AW88399_DSMCFG4_REG (0x33)
#define AW88399_DSMCFG5_REG (0x34)
#define AW88399_DSMCFG6_REG (0x35)
#define AW88399_DSMCFG7_REG (0x36)
#define AW88399_DSMCFG8_REG (0x37)
#define AW88399_TESTIN_REG (0x38)
#define AW88399_TESTOUT_REG (0x39)
#define AW88399_MEMTEST_REG (0x3A)
#define AW88399_VSNCTRL1_REG (0x3B)
#define AW88399_ISNCTRL1_REG (0x3C)
#define AW88399_ISNCTRL2_REG (0x3D)
#define AW88399_DSPMADD_REG (0x40)
#define AW88399_DSPMDAT_REG (0x41)
#define AW88399_WDT_REG (0x42)
#define AW88399_ACR1_REG (0x43)
#define AW88399_ACR2_REG (0x44)
#define AW88399_ASR1_REG (0x45)
#define AW88399_ASR2_REG (0x46)
#define AW88399_DSPCFG_REG (0x47)
#define AW88399_ASR3_REG (0x48)
#define AW88399_ASR4_REG (0x49)
#define AW88399_DSPVCALB_REG (0x4A)
#define AW88399_CRCCTRL_REG (0x4B)
#define AW88399_DSPDBG1_REG (0x4C)
#define AW88399_DSPDBG2_REG (0x4D)
#define AW88399_DSPDBG3_REG (0x4E)
#define AW88399_PLLCTRL1_REG (0x50)
#define AW88399_PLLCTRL2_REG (0x51)
#define AW88399_PLLCTRL3_REG (0x52)
#define AW88399_CDACTRL1_REG (0x53)
#define AW88399_CDACTRL2_REG (0x54)
#define AW88399_CDACTRL3_REG (0x55)
#define AW88399_SADCCTRL1_REG (0x56)
#define AW88399_SADCCTRL2_REG (0x57)
#define AW88399_BOPCTRL1_REG (0x58)
#define AW88399_BOPCTRL2_REG (0x5A)
#define AW88399_BOPCTRL3_REG (0x5B)
#define AW88399_BOPCTRL4_REG (0x5C)
#define AW88399_BOPCTRL5_REG (0x5D)
#define AW88399_BOPCTRL6_REG (0x5E)
#define AW88399_BOPCTRL7_REG (0x5F)
#define AW88399_BSTCTRL1_REG (0x60)
#define AW88399_BSTCTRL2_REG (0x61)
#define AW88399_BSTCTRL3_REG (0x62)
#define AW88399_BSTCTRL4_REG (0x63)
#define AW88399_BSTCTRL5_REG (0x64)
#define AW88399_BSTCTRL6_REG (0x65)
#define AW88399_BSTCTRL7_REG (0x66)
#define AW88399_BSTCTRL8_REG (0x67)
#define AW88399_BSTCTRL9_REG (0x68)
#define AW88399_BSTCTRL10_REG (0x69)
#define AW88399_CPCTRL_REG (0x6A)
#define AW88399_EFWH_REG (0x6C)
#define AW88399_EFWM2_REG (0x6D)
#define AW88399_EFWM1_REG (0x6E)
#define AW88399_EFWL_REG (0x6F)
#define AW88399_TESTCTRL1_REG (0x70)
#define AW88399_TESTCTRL2_REG (0x71)
#define AW88399_EFCTRL1_REG (0x72)
#define AW88399_EFCTRL2_REG (0x73)
#define AW88399_EFRH4_REG (0x74)
#define AW88399_EFRH3_REG (0x75)
#define AW88399_EFRH2_REG (0x76)
#define AW88399_EFRH1_REG (0x77)
#define AW88399_EFRL4_REG (0x78)
#define AW88399_EFRL3_REG (0x79)
#define AW88399_EFRL2_REG (0x7A)
#define AW88399_EFRL1_REG (0x7B)
#define AW88399_TM_REG (0x7C)
#define AW88399_TM2_REG (0x7D)
#define AW88399_REG_MAX (0x7E)
#define AW88399_MUTE_VOL (1023)
#define AW88399_DSP_CFG_ADDR (0x9B00)
#define AW88399_DSP_REG_CFG_ADPZ_RA (0x9B68)
#define AW88399_DSP_FW_ADDR (0x8980)
#define AW88399_DSP_ROM_CHECK_ADDR (0x1F40)
#define AW88399_DSP_ROM_CHECK_DATA (0x4638)
#define AW88399_CALI_RE_HBITS_MASK (~(0xFFFF0000))
#define AW88399_CALI_RE_HBITS_SHIFT (16)
#define AW88399_CALI_RE_LBITS_MASK (~(0xFFFF))
#define AW88399_CALI_RE_LBITS_SHIFT (0)
#define AW88399_I2STXEN_START_BIT (9)
#define AW88399_I2STXEN_BITS_LEN (1)
#define AW88399_I2STXEN_MASK \
(~(((1<<AW88399_I2STXEN_BITS_LEN)-1) << AW88399_I2STXEN_START_BIT))
#define AW88399_I2STXEN_DISABLE (0)
#define AW88399_I2STXEN_DISABLE_VALUE \
(AW88399_I2STXEN_DISABLE << AW88399_I2STXEN_START_BIT)
#define AW88399_I2STXEN_ENABLE (1)
#define AW88399_I2STXEN_ENABLE_VALUE \
(AW88399_I2STXEN_ENABLE << AW88399_I2STXEN_START_BIT)
#define AW88399_VOL_START_BIT (0)
#define AW88399_VOL_BITS_LEN (10)
#define AW88399_VOL_MASK \
(~(((1<<AW88399_VOL_BITS_LEN)-1) << AW88399_VOL_START_BIT))
#define AW88399_PWDN_START_BIT (0)
#define AW88399_PWDN_BITS_LEN (1)
#define AW88399_PWDN_MASK \
(~(((1<<AW88399_PWDN_BITS_LEN)-1) << AW88399_PWDN_START_BIT))
#define AW88399_PWDN_POWER_DOWN (1)
#define AW88399_PWDN_POWER_DOWN_VALUE \
(AW88399_PWDN_POWER_DOWN << AW88399_PWDN_START_BIT)
#define AW88399_PWDN_WORKING (0)
#define AW88399_PWDN_WORKING_VALUE \
(AW88399_PWDN_WORKING << AW88399_PWDN_START_BIT)
#define AW88399_DSPBY_START_BIT (2)
#define AW88399_DSPBY_BITS_LEN (1)
#define AW88399_DSPBY_MASK \
(~(((1<<AW88399_DSPBY_BITS_LEN)-1) << AW88399_DSPBY_START_BIT))
#define AW88399_DSPBY_WORKING (0)
#define AW88399_DSPBY_WORKING_VALUE \
(AW88399_DSPBY_WORKING << AW88399_DSPBY_START_BIT)
#define AW88399_DSPBY_BYPASS (1)
#define AW88399_DSPBY_BYPASS_VALUE \
(AW88399_DSPBY_BYPASS << AW88399_DSPBY_START_BIT)
#define AW88399_MEM_CLKSEL_START_BIT (3)
#define AW88399_MEM_CLKSEL_BITS_LEN (1)
#define AW88399_MEM_CLKSEL_MASK \
(~(((1<<AW88399_MEM_CLKSEL_BITS_LEN)-1) << AW88399_MEM_CLKSEL_START_BIT))
#define AW88399_MEM_CLKSEL_OSCCLK (0)
#define AW88399_MEM_CLKSEL_OSCCLK_VALUE \
(AW88399_MEM_CLKSEL_OSCCLK << AW88399_MEM_CLKSEL_START_BIT)
#define AW88399_MEM_CLKSEL_DAPHCLK (1)
#define AW88399_MEM_CLKSEL_DAPHCLK_VALUE \
(AW88399_MEM_CLKSEL_DAPHCLK << AW88399_MEM_CLKSEL_START_BIT)
#define AW88399_DITHER_EN_START_BIT (15)
#define AW88399_DITHER_EN_BITS_LEN (1)
#define AW88399_DITHER_EN_MASK \
(~(((1<<AW88399_DITHER_EN_BITS_LEN)-1) << AW88399_DITHER_EN_START_BIT))
#define AW88399_DITHER_EN_DISABLE (0)
#define AW88399_DITHER_EN_DISABLE_VALUE \
(AW88399_DITHER_EN_DISABLE << AW88399_DITHER_EN_START_BIT)
#define AW88399_DITHER_EN_ENABLE (1)
#define AW88399_DITHER_EN_ENABLE_VALUE \
(AW88399_DITHER_EN_ENABLE << AW88399_DITHER_EN_START_BIT)
#define AW88399_HMUTE_START_BIT (8)
#define AW88399_HMUTE_BITS_LEN (1)
#define AW88399_HMUTE_MASK \
(~(((1<<AW88399_HMUTE_BITS_LEN)-1) << AW88399_HMUTE_START_BIT))
#define AW88399_HMUTE_DISABLE (0)
#define AW88399_HMUTE_DISABLE_VALUE \
(AW88399_HMUTE_DISABLE << AW88399_HMUTE_START_BIT)
#define AW88399_HMUTE_ENABLE (1)
#define AW88399_HMUTE_ENABLE_VALUE \
(AW88399_HMUTE_ENABLE << AW88399_HMUTE_START_BIT)
#define AW88399_EF_DBMD_START_BIT (2)
#define AW88399_EF_DBMD_BITS_LEN (1)
#define AW88399_EF_DBMD_MASK \
(~(((1<<AW88399_EF_DBMD_BITS_LEN)-1) << AW88399_EF_DBMD_START_BIT))
#define AW88399_EF_DBMD_OR (1)
#define AW88399_EF_DBMD_OR_VALUE \
(AW88399_EF_DBMD_OR << AW88399_EF_DBMD_START_BIT)
#define AW88399_VDSEL_START_BIT (5)
#define AW88399_VDSEL_BITS_LEN (1)
#define AW88399_VDSEL_MASK \
(~(((1<<AW88399_VDSEL_BITS_LEN)-1) << AW88399_VDSEL_START_BIT))
#define AW88399_EF_ISN_GESLP_H_START_BIT (0)
#define AW88399_EF_ISN_GESLP_H_BITS_LEN (10)
#define AW88399_EF_ISN_GESLP_H_MASK \
(~(((1<<AW88399_EF_ISN_GESLP_H_BITS_LEN)-1) << AW88399_EF_ISN_GESLP_H_START_BIT))
/* EF_VSN_GESLP_H bit 9:0 (EFRH3 0x75) */
#define AW88399_EF_VSN_GESLP_H_START_BIT (0)
#define AW88399_EF_VSN_GESLP_H_BITS_LEN (10)
#define AW88399_EF_VSN_GESLP_H_MASK \
(~(((1<<AW88399_EF_VSN_GESLP_H_BITS_LEN)-1) << AW88399_EF_VSN_GESLP_H_START_BIT))
#define AW88399_EF_ISN_GESLP_L_START_BIT (0)
#define AW88399_EF_ISN_GESLP_L_BITS_LEN (10)
#define AW88399_EF_ISN_GESLP_L_MASK \
(~(((1<<AW88399_EF_ISN_GESLP_L_BITS_LEN)-1) << AW88399_EF_ISN_GESLP_L_START_BIT))
/* EF_VSN_GESLP_L bit 9:0 (EFRL3 0x79) */
#define AW88399_EF_VSN_GESLP_L_START_BIT (0)
#define AW88399_EF_VSN_GESLP_L_BITS_LEN (10)
#define AW88399_EF_VSN_GESLP_L_MASK \
(~(((1<<AW88399_EF_VSN_GESLP_L_BITS_LEN)-1) << AW88399_EF_VSN_GESLP_L_START_BIT))
#define AW88399_INTERNAL_VSN_TRIM_H_START_BIT (9)
#define AW88399_INTERNAL_VSN_TRIM_H_BITS_LEN (6)
#define AW88399_INTERNAL_VSN_TRIM_H_MASK \
(~(((1<<AW88399_INTERNAL_VSN_TRIM_H_BITS_LEN)-1) << AW88399_INTERNAL_VSN_TRIM_H_START_BIT))
#define AW88399_INTERNAL_VSN_TRIM_L_START_BIT (9)
#define AW88399_INTERNAL_VSN_TRIM_L_BITS_LEN (6)
#define AW88399_INTERNAL_VSN_TRIM_L_MASK \
(~(((1<<AW88399_INTERNAL_VSN_TRIM_L_BITS_LEN)-1) << AW88399_INTERNAL_VSN_TRIM_L_START_BIT))
#define AW88399_RCV_MODE_START_BIT (7)
#define AW88399_RCV_MODE_BITS_LEN (1)
#define AW88399_RCV_MODE_MASK \
(~(((1<<AW88399_RCV_MODE_BITS_LEN)-1) << AW88399_RCV_MODE_START_BIT))
#define AW88399_CLKI_START_BIT (4)
#define AW88399_NOCLKI_START_BIT (5)
#define AW88399_PLLI_START_BIT (0)
#define AW88399_PLLI_INT_VALUE (1)
#define AW88399_PLLI_INT_INTERRUPT \
(AW88399_PLLI_INT_VALUE << AW88399_PLLI_START_BIT)
#define AW88399_CLKI_INT_VALUE (1)
#define AW88399_CLKI_INT_INTERRUPT \
(AW88399_CLKI_INT_VALUE << AW88399_CLKI_START_BIT)
#define AW88399_NOCLKI_INT_VALUE (1)
#define AW88399_NOCLKI_INT_INTERRUPT \
(AW88399_NOCLKI_INT_VALUE << AW88399_NOCLKI_START_BIT)
#define AW88399_BIT_SYSINT_CHECK \
(AW88399_PLLI_INT_INTERRUPT | \
AW88399_CLKI_INT_INTERRUPT | \
AW88399_NOCLKI_INT_INTERRUPT)
#define AW88399_CRC_CHECK_START_BIT (12)
#define AW88399_CRC_CHECK_BITS_LEN (3)
#define AW88399_CRC_CHECK_BITS_MASK \
(~(((1<<AW88399_CRC_CHECK_BITS_LEN)-1) << AW88399_CRC_CHECK_START_BIT))
#define AW88399_RCV_MODE_RECEIVER (1)
#define AW88399_RCV_MODE_RECEIVER_VALUE \
(AW88399_RCV_MODE_RECEIVER << AW88399_RCV_MODE_START_BIT)
#define AW88399_AMPPD_START_BIT (1)
#define AW88399_AMPPD_BITS_LEN (1)
#define AW88399_AMPPD_MASK \
(~(((1<<AW88399_AMPPD_BITS_LEN)-1) << AW88399_AMPPD_START_BIT))
#define AW88399_AMPPD_WORKING (0)
#define AW88399_AMPPD_WORKING_VALUE \
(AW88399_AMPPD_WORKING << AW88399_AMPPD_START_BIT)
#define AW88399_AMPPD_POWER_DOWN (1)
#define AW88399_AMPPD_POWER_DOWN_VALUE \
(AW88399_AMPPD_POWER_DOWN << AW88399_AMPPD_START_BIT)
#define AW88399_RAM_CG_BYP_START_BIT (0)
#define AW88399_RAM_CG_BYP_BITS_LEN (1)
#define AW88399_RAM_CG_BYP_MASK \
(~(((1<<AW88399_RAM_CG_BYP_BITS_LEN)-1) << AW88399_RAM_CG_BYP_START_BIT))
#define AW88399_RAM_CG_BYP_WORK (0)
#define AW88399_RAM_CG_BYP_WORK_VALUE \
(AW88399_RAM_CG_BYP_WORK << AW88399_RAM_CG_BYP_START_BIT)
#define AW88399_RAM_CG_BYP_BYPASS (1)
#define AW88399_RAM_CG_BYP_BYPASS_VALUE \
(AW88399_RAM_CG_BYP_BYPASS << AW88399_RAM_CG_BYP_START_BIT)
#define AW88399_CRC_END_ADDR_START_BIT (0)
#define AW88399_CRC_END_ADDR_BITS_LEN (12)
#define AW88399_CRC_END_ADDR_MASK \
(~(((1<<AW88399_CRC_END_ADDR_BITS_LEN)-1) << AW88399_CRC_END_ADDR_START_BIT))
#define AW88399_CRC_CODE_EN_START_BIT (13)
#define AW88399_CRC_CODE_EN_BITS_LEN (1)
#define AW88399_CRC_CODE_EN_MASK \
(~(((1<<AW88399_CRC_CODE_EN_BITS_LEN)-1) << AW88399_CRC_CODE_EN_START_BIT))
#define AW88399_CRC_CODE_EN_DISABLE (0)
#define AW88399_CRC_CODE_EN_DISABLE_VALUE \
(AW88399_CRC_CODE_EN_DISABLE << AW88399_CRC_CODE_EN_START_BIT)
#define AW88399_CRC_CODE_EN_ENABLE (1)
#define AW88399_CRC_CODE_EN_ENABLE_VALUE \
(AW88399_CRC_CODE_EN_ENABLE << AW88399_CRC_CODE_EN_START_BIT)
#define AW88399_CRC_CFG_EN_START_BIT (12)
#define AW88399_CRC_CFG_EN_BITS_LEN (1)
#define AW88399_CRC_CFG_EN_MASK \
(~(((1<<AW88399_CRC_CFG_EN_BITS_LEN)-1) << AW88399_CRC_CFG_EN_START_BIT))
#define AW88399_CRC_CFG_EN_DISABLE (0)
#define AW88399_CRC_CFG_EN_DISABLE_VALUE \
(AW88399_CRC_CFG_EN_DISABLE << AW88399_CRC_CFG_EN_START_BIT)
#define AW88399_CRC_CFG_EN_ENABLE (1)
#define AW88399_CRC_CFG_EN_ENABLE_VALUE \
(AW88399_CRC_CFG_EN_ENABLE << AW88399_CRC_CFG_EN_START_BIT)
#define AW88399_OCDS_START_BIT (3)
#define AW88399_OCDS_OC (1)
#define AW88399_OCDS_OC_VALUE \
(AW88399_OCDS_OC << AW88399_OCDS_START_BIT)
#define AW88399_NOCLKS_START_BIT (5)
#define AW88399_NOCLKS_NO_CLOCK (1)
#define AW88399_NOCLKS_NO_CLOCK_VALUE \
(AW88399_NOCLKS_NO_CLOCK << AW88399_NOCLKS_START_BIT)
#define AW88399_SWS_START_BIT (8)
#define AW88399_SWS_SWITCHING (1)
#define AW88399_SWS_SWITCHING_VALUE \
(AW88399_SWS_SWITCHING << AW88399_SWS_START_BIT)
#define AW88399_BSTS_START_BIT (9)
#define AW88399_BSTS_FINISHED (1)
#define AW88399_BSTS_FINISHED_VALUE \
(AW88399_BSTS_FINISHED << AW88399_BSTS_START_BIT)
#define AW88399_UVLS_START_BIT (14)
#define AW88399_UVLS_NORMAL (0)
#define AW88399_UVLS_NORMAL_VALUE \
(AW88399_UVLS_NORMAL << AW88399_UVLS_START_BIT)
#define AW88399_BSTOCS_START_BIT (11)
#define AW88399_BSTOCS_OVER_CURRENT (1)
#define AW88399_BSTOCS_OVER_CURRENT_VALUE \
(AW88399_BSTOCS_OVER_CURRENT << AW88399_BSTOCS_START_BIT)
#define AW88399_OTHS_START_BIT (1)
#define AW88399_OTHS_OT (1)
#define AW88399_OTHS_OT_VALUE \
(AW88399_OTHS_OT << AW88399_OTHS_START_BIT)
#define AW88399_PLLS_START_BIT (0)
#define AW88399_PLLS_LOCKED (1)
#define AW88399_PLLS_LOCKED_VALUE \
(AW88399_PLLS_LOCKED << AW88399_PLLS_START_BIT)
#define AW88399_CLKS_START_BIT (4)
#define AW88399_CLKS_STABLE (1)
#define AW88399_CLKS_STABLE_VALUE \
(AW88399_CLKS_STABLE << AW88399_CLKS_START_BIT)
#define AW88399_BIT_PLL_CHECK \
(AW88399_CLKS_STABLE_VALUE | \
AW88399_PLLS_LOCKED_VALUE)
#define AW88399_BIT_SYSST_CHECK_MASK \
(~(AW88399_UVLS_NORMAL_VALUE | \
AW88399_BSTOCS_OVER_CURRENT_VALUE | \
AW88399_BSTS_FINISHED_VALUE | \
AW88399_SWS_SWITCHING_VALUE | \
AW88399_NOCLKS_NO_CLOCK_VALUE | \
AW88399_CLKS_STABLE_VALUE | \
AW88399_OCDS_OC_VALUE | \
AW88399_OTHS_OT_VALUE | \
AW88399_PLLS_LOCKED_VALUE))
#define AW88399_BIT_SYSST_NOSWS_CHECK \
(AW88399_BSTS_FINISHED_VALUE | \
AW88399_CLKS_STABLE_VALUE | \
AW88399_PLLS_LOCKED_VALUE)
#define AW88399_BIT_SYSST_SWS_CHECK \
(AW88399_BSTS_FINISHED_VALUE | \
AW88399_CLKS_STABLE_VALUE | \
AW88399_PLLS_LOCKED_VALUE | \
AW88399_SWS_SWITCHING_VALUE)
#define AW88399_CCO_MUX_START_BIT (14)
#define AW88399_CCO_MUX_BITS_LEN (1)
#define AW88399_CCO_MUX_MASK \
(~(((1<<AW88399_CCO_MUX_BITS_LEN)-1) << AW88399_CCO_MUX_START_BIT))
#define AW88399_CCO_MUX_DIVIDED (0)
#define AW88399_CCO_MUX_DIVIDED_VALUE \
(AW88399_CCO_MUX_DIVIDED << AW88399_CCO_MUX_START_BIT)
#define AW88399_CCO_MUX_BYPASS (1)
#define AW88399_CCO_MUX_BYPASS_VALUE \
(AW88399_CCO_MUX_BYPASS << AW88399_CCO_MUX_START_BIT)
#define AW88399_NOISE_GATE_EN_START_BIT (13)
#define AW88399_NOISE_GATE_EN_BITS_LEN (1)
#define AW88399_NOISE_GATE_EN_MASK \
(~(((1<<AW88399_NOISE_GATE_EN_BITS_LEN)-1) << AW88399_NOISE_GATE_EN_START_BIT))
#define AW88399_WDT_CNT_START_BIT (0)
#define AW88399_WDT_CNT_BITS_LEN (8)
#define AW88399_WDT_CNT_MASK \
(~(((1<<AW88399_WDT_CNT_BITS_LEN)-1) << AW88399_WDT_CNT_START_BIT))
#define AW88399_REABS_START_BIT (3)
#define AW88399_REABS_BITS_LEN (1)
#define AW88399_REABS_MASK \
(~(((1<<AW88399_REABS_BITS_LEN)-1) << AW88399_REABS_START_BIT))
#define AW88399_DSP_VOL_START_BIT (8)
#define AW88399_DSP_VOL_BITS_LEN (8)
#define AW88399_DSP_VOL_MASK \
(~(((1<<AW88399_DSP_VOL_BITS_LEN)-1) << AW88399_DSP_VOL_START_BIT))
#define AW883XX_DSP_NG_EN_START (13)
#define AW883XX_DSP_NG_EN_LEN (1)
#define AW883XX_DSP_NG_EN_MASK \
(~(((1 << AW883XX_DSP_NG_EN_LEN) - 1) << AW883XX_DSP_NG_EN_START))
#define AW883XX_DSP_NG_EN_DISABLE (0)
#define AW883XX_DSP_NG_EN_DISABLE_VALUE \
(AW883XX_DSP_NG_EN_DISABLE << AW883XX_DSP_NG_EN_START)
#define AW88399_VOLUME_STEP_DB (64)
#define AW88399_VOL_DEFAULT_VALUE (0)
#define AW88399_DSP_ODD_NUM_BIT_TEST (0x5555)
#define AW88399_EF_ISN_GESLP_SIGN_MASK (~(1 << 9))
#define AW88399_EF_ISN_GESLP_SIGN_NEG (0xfe00)
#define AW88399_EF_VSN_GESLP_SIGN_MASK (~(1 << 9))
#define AW88399_EF_VSN_GESLP_SIGN_NEG (0xfe00)
#define AW88399_TEM4_SIGN_MASK (~(1 << 5))
#define AW88399_TEM4_SIGN_NEG (0xffc0)
#define AW88399_ICABLK_FACTOR (1)
#define AW88399_VCABLK_FACTOR (1)
#define AW88399_VCABLK_DAC_FACTOR (2)
#define AW88399_VCALB_ADJ_FACTOR (12)
#define AW88399_VCALB_ACCURACY (1 << 12)
#define AW88399_ISCAL_FACTOR (3125)
#define AW88399_VSCAL_FACTOR (18875)
#define AW88399_ISCAL_DAC_FACTOR (3125)
#define AW88399_VSCAL_DAC_FACTOR (12600)
#define AW88399_CABL_BASE_VALUE (1000)
#define AW88399_DEV_DEFAULT_CH (0)
#define AW88399_DEV_DSP_CHECK_MAX (5)
#define AW88399_MAX_RAM_WRITE_BYTE_SIZE (128)
#define AW88399_DSP_RE_SHIFT (12)
#define AW88399_CALI_RE_MAX (15000)
#define AW88399_CALI_RE_MIN (4000)
#define AW_FW_ADDR_LEN (4)
#define AW88399_DSP_RE_TO_SHOW_RE(re, shift) (((re) * (1000)) >> (shift))
#define AW88399_SHOW_RE_TO_DSP_RE(re, shift) (((re) << shift) / (1000))
#define AW88399_CRC_CHECK_PASS_VAL (0x4)
#define AW88399_CRC_CFG_BASE_ADDR (0xD80)
#define AW88399_CRC_FW_BASE_ADDR (0x4C0)
#define AW88399_ACF_FILE "aw88399_acf.bin"
#define AW88399_DEV_SYSST_CHECK_MAX (10)
#define AW88399_CHIP_ID 0x2183
#include <sound/aw88399.h>
#define AW88399_I2C_NAME "aw88399"
#define AW88399_START_RETRIES (5)
#define AW88399_START_WORK_DELAY_MS (0)
#define AW88399_RATES (SNDRV_PCM_RATE_8000_48000 | \
SNDRV_PCM_RATE_96000)
#define AW88399_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
@@ -550,80 +48,4 @@
.put = profile_set, \
}
enum {
AW_EF_AND_CHECK = 0,
AW_EF_OR_CHECK,
};
enum {
AW88399_DEV_VDSEL_DAC = 0,
AW88399_DEV_VDSEL_VSENSE = 32,
};
enum {
AW88399_DSP_CRC_NA = 0,
AW88399_DSP_CRC_OK = 1,
};
enum {
AW88399_DSP_FW_UPDATE_OFF = 0,
AW88399_DSP_FW_UPDATE_ON = 1,
};
enum {
AW88399_FORCE_UPDATE_OFF = 0,
AW88399_FORCE_UPDATE_ON = 1,
};
enum {
AW88399_1000_US = 1000,
AW88399_2000_US = 2000,
AW88399_3000_US = 3000,
AW88399_4000_US = 4000,
};
enum AW88399_DEV_STATUS {
AW88399_DEV_PW_OFF = 0,
AW88399_DEV_PW_ON,
};
enum AW88399_DEV_FW_STATUS {
AW88399_DEV_FW_FAILED = 0,
AW88399_DEV_FW_OK,
};
enum AW88399_DEV_MEMCLK {
AW88399_DEV_MEMCLK_OSC = 0,
AW88399_DEV_MEMCLK_PLL = 1,
};
enum AW88399_DEV_DSP_CFG {
AW88399_DEV_DSP_WORK = 0,
AW88399_DEV_DSP_BYPASS = 1,
};
enum {
AW88399_NOT_RCV_MODE = 0,
AW88399_RCV_MODE = 1,
};
enum {
AW88399_SYNC_START = 0,
AW88399_ASYNC_START,
};
struct aw88399 {
struct aw_device *aw_pa;
struct mutex lock;
struct gpio_desc *reset_gpio;
struct delayed_work start_work;
struct regmap *regmap;
struct aw_container *aw_cfg;
unsigned int check_val;
unsigned int crc_init_val;
unsigned int vcalb_init_val;
unsigned int dither_st;
};
#endif
#endif /* __AW88399_H__ */

View File

@@ -85,13 +85,9 @@ static int bt_sco_probe(struct platform_device *pdev)
}
static const struct platform_device_id bt_sco_driver_ids[] = {
{
.name = "dfbmcs320",
},
{
.name = "bt-sco",
},
{},
{ .name = "dfbmcs320" },
{ .name = "bt-sco" },
{ }
};
MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids);

View File

@@ -12,6 +12,7 @@
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/cleanup.h>
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
@@ -608,10 +609,10 @@ static void wov_copy_work(struct work_struct *w)
container_of(w, struct cros_ec_codec_priv, wov_copy_work.work);
int ret;
mutex_lock(&priv->wov_dma_lock);
guard(mutex)(&priv->wov_dma_lock);
if (!priv->wov_substream) {
dev_warn(priv->dev, "no pcm substream\n");
goto leave;
return;
}
if (ec_codec_capable(priv, EC_CODEC_CAP_WOV_AUDIO_SHM))
@@ -624,8 +625,6 @@ static void wov_copy_work(struct work_struct *w)
msecs_to_jiffies(10));
else if (ret)
dev_err(priv->dev, "failed to read audio data\n");
leave:
mutex_unlock(&priv->wov_dma_lock);
}
static int wov_enable_get(struct snd_kcontrol *kcontrol,
@@ -895,12 +894,11 @@ static int wov_pcm_hw_params(struct snd_soc_component *component,
struct cros_ec_codec_priv *priv =
snd_soc_component_get_drvdata(component);
mutex_lock(&priv->wov_dma_lock);
guard(mutex)(&priv->wov_dma_lock);
priv->wov_substream = substream;
priv->wov_rp = priv->wov_wp = 0;
priv->wov_dma_offset = 0;
priv->wov_burst_read = true;
mutex_unlock(&priv->wov_dma_lock);
return 0;
}
@@ -911,10 +909,10 @@ static int wov_pcm_hw_free(struct snd_soc_component *component,
struct cros_ec_codec_priv *priv =
snd_soc_component_get_drvdata(component);
mutex_lock(&priv->wov_dma_lock);
wov_queue_dequeue(priv, wov_queue_size(priv));
priv->wov_substream = NULL;
mutex_unlock(&priv->wov_dma_lock);
scoped_guard(mutex, &priv->wov_dma_lock) {
wov_queue_dequeue(priv, wov_queue_size(priv));
priv->wov_substream = NULL;
}
cancel_delayed_work_sync(&priv->wov_copy_work);

View File

@@ -7,6 +7,7 @@
#include <asm/byteorder.h>
#include <kunit/static_stub.h>
#include <linux/cleanup.h>
#include <linux/debugfs.h>
#include <linux/dev_printk.h>
#include <linux/efi.h>
@@ -83,10 +84,12 @@ static int cs_amp_write_cal_coeff(struct cs_dsp *dsp,
KUNIT_STATIC_STUB_REDIRECT(cs_amp_write_cal_coeff, dsp, controls, ctl_name, val);
if (IS_REACHABLE(CONFIG_FW_CS_DSP)) {
mutex_lock(&dsp->pwr_lock);
cs_ctl = cs_dsp_get_ctl(dsp, ctl_name, controls->mem_region, controls->alg_id);
ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, &beval, sizeof(beval));
mutex_unlock(&dsp->pwr_lock);
scoped_guard(mutex, &dsp->pwr_lock) {
cs_ctl = cs_dsp_get_ctl(dsp, ctl_name,
controls->mem_region,
controls->alg_id);
ret = cs_dsp_coeff_write_ctrl(cs_ctl, 0, &beval, sizeof(beval));
}
if (ret < 0) {
dev_err(dsp->dev, "Failed to write to '%s': %d\n", ctl_name, ret);

View File

@@ -538,7 +538,15 @@ static int cs35l32_runtime_resume(struct device *dev)
gpiod_set_value_cansleep(cs35l32->reset_gpio, 1);
regcache_cache_only(cs35l32->regmap, false);
regcache_sync(cs35l32->regmap);
ret = regcache_sync(cs35l32->regmap);
if (ret) {
regcache_cache_only(cs35l32->regmap, true);
regcache_mark_dirty(cs35l32->regmap);
gpiod_set_value_cansleep(cs35l32->reset_gpio, 0);
regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies),
cs35l32->supplies);
return ret;
}
return 0;
}

View File

@@ -40,6 +40,7 @@ struct cs35l33_private {
struct regmap *regmap;
struct gpio_desc *reset_gpio;
bool amp_cal;
bool irq_requested;
int mclk_int;
struct regulator_bulk_data core_supplies[2];
int num_core_supplies;
@@ -881,6 +882,9 @@ static int cs35l33_runtime_resume(struct device *dev)
goto err;
}
if (cs35l33->irq_requested)
enable_irq(to_i2c_client(dev)->irq);
return 0;
err:
@@ -900,6 +904,10 @@ static int cs35l33_runtime_suspend(struct device *dev)
/* redo the calibration in next power up */
cs35l33->amp_cal = false;
/* Drain and block the threaded IRQ before cache_only/power-off. */
if (cs35l33->irq_requested)
disable_irq(to_i2c_client(dev)->irq);
regcache_cache_only(cs35l33->regmap, true);
regcache_mark_dirty(cs35l33->regmap);
regulator_bulk_disable(cs35l33->num_core_supplies,
@@ -1154,10 +1162,12 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client)
}
ret = devm_request_threaded_irq(&i2c_client->dev, i2c_client->irq, NULL,
cs35l33_irq_thread, IRQF_ONESHOT | IRQF_TRIGGER_LOW,
"cs35l33", cs35l33);
cs35l33_irq_thread, IRQF_ONESHOT | IRQF_TRIGGER_LOW,
"cs35l33", cs35l33);
if (ret != 0)
dev_warn(&i2c_client->dev, "Failed to request IRQ: %d\n", ret);
else
cs35l33->irq_requested = true;
/* We could issue !RST or skip it based on AMP topology */
cs35l33->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,

View File

@@ -45,6 +45,7 @@ struct cs35l34_private {
int num_core_supplies;
int mclk_int;
bool tdm_mode;
bool irq_requested;
struct gpio_desc *reset_gpio; /* Active-low reset GPIO */
};
@@ -1032,10 +1033,12 @@ static int cs35l34_i2c_probe(struct i2c_client *i2c_client)
}
ret = devm_request_threaded_irq(&i2c_client->dev, i2c_client->irq, NULL,
cs35l34_irq_thread, IRQF_ONESHOT | IRQF_TRIGGER_LOW,
"cs35l34", cs35l34);
cs35l34_irq_thread, IRQF_ONESHOT | IRQF_TRIGGER_LOW,
"cs35l34", cs35l34);
if (ret != 0)
dev_err(&i2c_client->dev, "Failed to request IRQ: %d\n", ret);
else
cs35l34->irq_requested = true;
cs35l34->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
"reset", GPIOD_OUT_LOW);
@@ -1140,6 +1143,9 @@ static int cs35l34_runtime_resume(struct device *dev)
dev_err(dev, "Failed to restore register cache\n");
goto err;
}
if (cs35l34->irq_requested)
enable_irq(to_i2c_client(dev)->irq);
return 0;
err:
regcache_cache_only(cs35l34->regmap, true);
@@ -1153,6 +1159,10 @@ static int cs35l34_runtime_suspend(struct device *dev)
{
struct cs35l34_private *cs35l34 = dev_get_drvdata(dev);
/* Drain and block the threaded IRQ before cache_only/power-off. */
if (cs35l34->irq_requested)
disable_irq(to_i2c_client(dev)->irq);
regcache_cache_only(cs35l34->regmap, true);
regcache_mark_dirty(cs35l34->regmap);

View File

@@ -457,6 +457,7 @@ static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_devi
regmap_config = &cs35l56_regmap_sdw;
break;
case 0x3563:
case 0x3562:
regmap_config = &cs35l63_regmap_sdw;
break;
default:
@@ -509,6 +510,7 @@ static const struct dev_pm_ops cs35l56_sdw_pm = {
static const struct sdw_device_id cs35l56_sdw_id[] = {
SDW_SLAVE_ENTRY(0x01FA, 0x3556, 0x3556),
SDW_SLAVE_ENTRY(0x01FA, 0x3557, 0x3557),
SDW_SLAVE_ENTRY(0x01FA, 0x3562, 0x3562),
SDW_SLAVE_ENTRY(0x01FA, 0x3563, 0x3563),
{},
};

View File

@@ -96,6 +96,7 @@ int cs35l56_set_patch(struct cs35l56_base *cs35l56_base)
ARRAY_SIZE(cs35l56_patch_fw));
break;
case 0x63:
case 0x62:
ret = regmap_register_patch(cs35l56_base->regmap, cs35l63_patch_fw,
ARRAY_SIZE(cs35l63_patch_fw));
break;
@@ -389,6 +390,7 @@ static void cs35l56_set_fw_reg_table(struct cs35l56_base *cs35l56_base)
}
break;
case 0x63:
case 0x62:
cs35l56_base->fw_reg = &cs35l63_fw_reg;
break;
}
@@ -595,6 +597,7 @@ void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire)
}
break;
case 0x63:
case 0x62:
regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
cs35l63_system_reset_seq,
ARRAY_SIZE(cs35l63_system_reset_seq));
@@ -640,23 +643,22 @@ irqreturn_t cs35l56_irq(int irq, void *data)
unsigned int val;
int rv;
irqreturn_t ret = IRQ_NONE;
if (!cs35l56_base->init_done)
return IRQ_NONE;
mutex_lock(&cs35l56_base->irq_lock);
guard(mutex)(&cs35l56_base->irq_lock);
rv = pm_runtime_resume_and_get(cs35l56_base->dev);
PM_RUNTIME_ACQUIRE_IF_ENABLED(cs35l56_base->dev, pm);
rv = PM_RUNTIME_ACQUIRE_ERR(&pm);
if (rv < 0) {
dev_err(cs35l56_base->dev, "irq: failed to get pm_runtime: %d\n", rv);
goto err_unlock;
return IRQ_NONE;
}
regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_STATUS, &val);
if ((val & CS35L56_IRQ1_STS_MASK) == 0) {
dev_dbg(cs35l56_base->dev, "Spurious IRQ: no pending interrupt\n");
goto err;
return IRQ_NONE;
}
/* Ack interrupts */
@@ -680,7 +682,7 @@ irqreturn_t cs35l56_irq(int irq, void *data)
/* Check to see if unmasked bits are active */
if (!status1 && !status8 && !status20)
goto err;
return IRQ_NONE;
if (status1 & CS35L56_AMP_SHORT_ERR_EINT1_MASK)
dev_crit(cs35l56_base->dev, "Amp short error\n");
@@ -688,14 +690,7 @@ irqreturn_t cs35l56_irq(int irq, void *data)
if (status8 & CS35L56_TEMP_ERR_EINT1_MASK)
dev_crit(cs35l56_base->dev, "Overtemp error\n");
ret = IRQ_HANDLED;
err:
pm_runtime_put(cs35l56_base->dev);
err_unlock:
mutex_unlock(&cs35l56_base->irq_lock);
return ret;
return IRQ_HANDLED;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_irq, "SND_SOC_CS35L56_SHARED");
@@ -816,14 +811,10 @@ int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_sou
if (!cs35l56_base->init_done)
return 0;
if (!cs35l56_base->can_hibernate)
goto out_sync;
/* Must be done before releasing cache-only */
if (!is_soundwire)
/* Hibernate wake must be done before releasing cache-only */
if (cs35l56_base->can_hibernate && !is_soundwire)
cs35l56_issue_wake_event(cs35l56_base);
out_sync:
ret = cs35l56_wait_for_firmware_boot(cs35l56_base);
if (ret) {
dev_err(cs35l56_base->dev, "Hibernate wake failed: %d\n", ret);
@@ -1470,6 +1461,7 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
cs35l56_base->calibration_controls = &cs35l56_calibration_controls;
break;
case 0x35A630:
case 0x35A620:
cs35l56_base->calibration_controls = &cs35l63_calibration_controls;
devid = devid >> 4;
break;

View File

@@ -1402,6 +1402,7 @@ static int _cs35l56_component_probe(struct snd_soc_component *component)
ARRAY_SIZE(cs35l56_controls));
break;
case 0x63:
case 0x62:
ret = snd_soc_add_component_controls(component, cs35l63_controls,
ARRAY_SIZE(cs35l63_controls));
break;

View File

@@ -288,8 +288,8 @@ static int cs40l50_codec_driver_probe(struct platform_device *pdev)
}
static const struct platform_device_id cs40l50_id[] = {
{ "cs40l50-codec", },
{}
{ .name = "cs40l50-codec" },
{ }
};
MODULE_DEVICE_TABLE(platform, cs40l50_id);

View File

@@ -481,10 +481,20 @@ static int cs42l42_sdw_runtime_resume(struct device *dev)
regcache_cache_only(cs42l42->regmap, false);
/* Sync LATCH_TO_VP first so the VP domain registers sync correctly */
regcache_sync_region(cs42l42->regmap, CS42L42_MIC_DET_CTL1, CS42L42_MIC_DET_CTL1);
regcache_sync(cs42l42->regmap);
ret = regcache_sync_region(cs42l42->regmap, CS42L42_MIC_DET_CTL1, CS42L42_MIC_DET_CTL1);
if (ret)
goto err_sync;
ret = regcache_sync(cs42l42->regmap);
if (ret)
goto err_sync;
return 0;
err_sync:
regcache_cache_only(cs42l42->regmap, true);
regcache_mark_dirty(cs42l42->regmap);
return ret;
}
static int cs42l42_sdw_resume(struct device *dev)

View File

@@ -9,6 +9,7 @@
* Author: Michael White <michael.white@cirrus.com>
*/
#include <linux/cleanup.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
@@ -565,7 +566,7 @@ static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_
struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
/* Prevent race with interrupt handler */
mutex_lock(&cs42l42->irq_lock);
guard(mutex)(&cs42l42->irq_lock);
cs42l42->jack = jk;
if (jk) {
@@ -581,7 +582,6 @@ static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_
break;
}
}
mutex_unlock(&cs42l42->irq_lock);
return 0;
}
@@ -1668,13 +1668,10 @@ irqreturn_t cs42l42_irq_thread(int irq, void *data)
unsigned int current_button_status;
unsigned int i;
pm_runtime_get_sync(cs42l42->dev);
mutex_lock(&cs42l42->irq_lock);
if (cs42l42->suspended || !cs42l42->init_done) {
mutex_unlock(&cs42l42->irq_lock);
pm_runtime_put_autosuspend(cs42l42->dev);
guard(pm_runtime_active_auto)(cs42l42->dev);
guard(mutex)(&cs42l42->irq_lock);
if (cs42l42->suspended || !cs42l42->init_done)
return IRQ_NONE;
}
/* Read sticky registers to clear interurpt */
for (i = 0; i < ARRAY_SIZE(stickies); i++) {
@@ -1774,9 +1771,6 @@ irqreturn_t cs42l42_irq_thread(int irq, void *data)
}
}
mutex_unlock(&cs42l42->irq_lock);
pm_runtime_put_autosuspend(cs42l42->dev);
return IRQ_HANDLED;
}
EXPORT_SYMBOL_NS_GPL(cs42l42_irq_thread, "SND_SOC_CS42L42_CORE");
@@ -2163,23 +2157,23 @@ int cs42l42_suspend(struct device *dev)
* future interrupts. This ensures a safe disable if the interrupt
* is shared.
*/
mutex_lock(&cs42l42->irq_lock);
cs42l42->suspended = true;
scoped_guard(mutex, &cs42l42->irq_lock) {
cs42l42->suspended = true;
/* Save register values that will be overwritten by shutdown sequence */
for (i = 0; i < ARRAY_SIZE(cs42l42_shutdown_seq); ++i) {
regmap_read(cs42l42->regmap, cs42l42_shutdown_seq[i].reg, &reg);
save_regs[i] = (u8)reg;
/* Save register values that will be overwritten by shutdown sequence */
for (i = 0; i < ARRAY_SIZE(cs42l42_shutdown_seq); ++i) {
regmap_read(cs42l42->regmap, cs42l42_shutdown_seq[i].reg, &reg);
save_regs[i] = (u8)reg;
}
/* Shutdown codec */
regmap_multi_reg_write(cs42l42->regmap,
cs42l42_shutdown_seq,
ARRAY_SIZE(cs42l42_shutdown_seq));
/* All interrupt sources are now disabled */
}
/* Shutdown codec */
regmap_multi_reg_write(cs42l42->regmap,
cs42l42_shutdown_seq,
ARRAY_SIZE(cs42l42_shutdown_seq));
/* All interrupt sources are now disabled */
mutex_unlock(&cs42l42->irq_lock);
/* Wait for power-down complete */
msleep(CS42L42_PDN_DONE_TIME_MS);
ret = regmap_read_poll_timeout(cs42l42->regmap,
@@ -2250,13 +2244,13 @@ void cs42l42_resume_restore(struct device *dev)
regcache_cache_only(cs42l42->regmap, false);
regcache_mark_dirty(cs42l42->regmap);
mutex_lock(&cs42l42->irq_lock);
/* Sync LATCH_TO_VP first so the VP domain registers sync correctly */
regcache_sync_region(cs42l42->regmap, CS42L42_MIC_DET_CTL1, CS42L42_MIC_DET_CTL1);
regcache_sync(cs42l42->regmap);
scoped_guard(mutex, &cs42l42->irq_lock) {
/* Sync LATCH_TO_VP first so the VP domain registers sync correctly */
regcache_sync_region(cs42l42->regmap, CS42L42_MIC_DET_CTL1, CS42L42_MIC_DET_CTL1);
regcache_sync(cs42l42->regmap);
cs42l42->suspended = false;
mutex_unlock(&cs42l42->irq_lock);
cs42l42->suspended = false;
}
dev_dbg(dev, "System resumed\n");
}

View File

@@ -6,6 +6,7 @@
// Cirrus Logic International Semiconductor Ltd.
#include <linux/build_bug.h>
#include <linux/cleanup.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/errno.h>
@@ -67,6 +68,21 @@ static int cs42l43_find_index(struct cs42l43_codec *priv, const char * const pro
return -EINVAL;
}
static void cs42l43_apply_accdet_config(struct cs42l43_codec *priv,
unsigned int autocontrol,
unsigned int pdncntl)
{
struct cs42l43 *cs42l43 = priv->core;
regmap_update_bits(cs42l43->regmap, CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
CS42L43_JACKDET_MODE_MASK | CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK |
CS42L43_HSBIAS_SENSE_TRIP_MASK, autocontrol);
regmap_update_bits(cs42l43->regmap, CS42L43_PDNCNTL,
CS42L43_RING_SENSE_EN_MASK, pdncntl);
dev_dbg(priv->dev, "Successfully configured accessory detect\n");
}
int cs42l43_set_jack(struct snd_soc_component *component,
struct snd_soc_jack *jack, void *d)
{
@@ -80,31 +96,34 @@ int cs42l43_set_jack(struct snd_soc_component *component,
dev_dbg(priv->dev, "Configure accessory detect\n");
ret = pm_runtime_resume_and_get(priv->dev);
PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(priv->dev, pm);
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
if (ret) {
dev_err(priv->dev, "Failed to resume for jack config: %d\n", ret);
return ret;
}
mutex_lock(&priv->jack_lock);
guard(mutex)(&priv->jack_lock);
priv->jack_hp = jack;
if (!jack)
goto done;
if (!jack) {
cs42l43_apply_accdet_config(priv, autocontrol, pdncntl);
return 0;
}
ret = device_property_count_u32(cs42l43->dev, "cirrus,buttons-ohms");
if (ret != -EINVAL) {
if (ret < 0) {
dev_err(priv->dev, "Property cirrus,buttons-ohms malformed: %d\n",
ret);
goto error;
return ret;
}
if (ret > CS42L43_N_BUTTONS) {
ret = -EINVAL;
dev_err(priv->dev, "Property cirrus,buttons-ohms too many entries\n");
goto error;
return ret;
}
ret = device_property_read_u32_array(cs42l43->dev, "cirrus,buttons-ohms",
@@ -112,7 +131,7 @@ int cs42l43_set_jack(struct snd_soc_component *component,
if (ret < 0) {
dev_err(priv->dev, "Property cirrus,button-ohms malformed: %d\n",
ret);
goto error;
return ret;
}
} else {
priv->buttons[0] = 70;
@@ -124,7 +143,7 @@ int cs42l43_set_jack(struct snd_soc_component *component,
ret = cs42l43_find_index(priv, "cirrus,detect-us", 50000, &priv->detect_us,
cs42l43_accdet_us, ARRAY_SIZE(cs42l43_accdet_us));
if (ret < 0)
goto error;
return ret;
hs2 |= ret << CS42L43_AUTO_HSDET_TIME_SHIFT;
@@ -134,7 +153,7 @@ int cs42l43_set_jack(struct snd_soc_component *component,
&priv->bias_ramp_ms, cs42l43_accdet_ramp_ms,
ARRAY_SIZE(cs42l43_accdet_ramp_ms));
if (ret < 0)
goto error;
return ret;
hs2 |= ret << CS42L43_HSBIAS_RAMP_SHIFT;
@@ -142,7 +161,7 @@ int cs42l43_set_jack(struct snd_soc_component *component,
&priv->bias_sense_ua, cs42l43_accdet_bias_sense,
ARRAY_SIZE(cs42l43_accdet_bias_sense));
if (ret < 0)
goto error;
return ret;
if (priv->bias_sense_ua)
autocontrol |= ret << CS42L43_HSBIAS_SENSE_TRIP_SHIFT;
@@ -154,7 +173,7 @@ int cs42l43_set_jack(struct snd_soc_component *component,
&priv->tip_debounce_ms);
if (ret < 0 && ret != -EINVAL) {
dev_err(priv->dev, "Property cirrus,tip-debounce-ms malformed: %d\n", ret);
goto error;
return ret;
}
/* This tip sense invert is set normally, as TIPSENSE_INV already inverted */
@@ -170,7 +189,7 @@ int cs42l43_set_jack(struct snd_soc_component *component,
&priv->tip_fall_db_ms, cs42l43_accdet_db_ms,
ARRAY_SIZE(cs42l43_accdet_db_ms));
if (ret < 0)
goto error;
return ret;
tip_deb |= ret << CS42L43_TIPSENSE_FALLING_DB_TIME_SHIFT;
@@ -178,7 +197,7 @@ int cs42l43_set_jack(struct snd_soc_component *component,
&priv->tip_rise_db_ms, cs42l43_accdet_db_ms,
ARRAY_SIZE(cs42l43_accdet_db_ms));
if (ret < 0)
goto error;
return ret;
tip_deb |= ret << CS42L43_TIPSENSE_RISING_DB_TIME_SHIFT;
@@ -199,7 +218,7 @@ int cs42l43_set_jack(struct snd_soc_component *component,
NULL, cs42l43_accdet_db_ms,
ARRAY_SIZE(cs42l43_accdet_db_ms));
if (ret < 0)
goto error;
return ret;
ring_deb |= ret << CS42L43_RINGSENSE_FALLING_DB_TIME_SHIFT;
@@ -207,7 +226,7 @@ int cs42l43_set_jack(struct snd_soc_component *component,
NULL, cs42l43_accdet_db_ms,
ARRAY_SIZE(cs42l43_accdet_db_ms));
if (ret < 0)
goto error;
return ret;
ring_deb |= ret << CS42L43_RINGSENSE_RISING_DB_TIME_SHIFT;
pdncntl |= CS42L43_RING_SENSE_EN_MASK;
@@ -228,23 +247,9 @@ int cs42l43_set_jack(struct snd_soc_component *component,
CS42L43_HSBIAS_RAMP_MASK | CS42L43_HSDET_MODE_MASK |
CS42L43_AUTO_HSDET_TIME_MASK, hs2);
done:
ret = 0;
cs42l43_apply_accdet_config(priv, autocontrol, pdncntl);
regmap_update_bits(cs42l43->regmap, CS42L43_HS_BIAS_SENSE_AND_CLAMP_AUTOCONTROL,
CS42L43_JACKDET_MODE_MASK | CS42L43_S0_AUTO_ADCMUTE_DISABLE_MASK |
CS42L43_HSBIAS_SENSE_TRIP_MASK, autocontrol);
regmap_update_bits(cs42l43->regmap, CS42L43_PDNCNTL,
CS42L43_RING_SENSE_EN_MASK, pdncntl);
dev_dbg(priv->dev, "Successfully configured accessory detect\n");
error:
mutex_unlock(&priv->jack_lock);
pm_runtime_put_autosuspend(priv->dev);
return ret;
return 0;
}
static void cs42l43_start_hs_bias(struct cs42l43_codec *priv, bool type_detect)
@@ -370,22 +375,22 @@ irqreturn_t cs42l43_button_press(int irq, void *data)
{
struct cs42l43_codec *priv = data;
struct cs42l43 *cs42l43 = priv->core;
irqreturn_t iret = IRQ_NONE;
unsigned int buttons = 0;
unsigned int val = 0;
int i, ret;
ret = pm_runtime_resume_and_get(priv->dev);
PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(priv->dev, pm);
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
if (ret) {
dev_err(priv->dev, "Failed to resume for button press: %d\n", ret);
return iret;
return IRQ_NONE;
}
mutex_lock(&priv->jack_lock);
guard(mutex)(&priv->jack_lock);
if (!priv->button_detect_running) {
dev_dbg(priv->dev, "Spurious button press IRQ\n");
goto error;
return IRQ_NONE;
}
// Wait for 2 full cycles of comb filter to ensure good reading
@@ -396,12 +401,12 @@ irqreturn_t cs42l43_button_press(int irq, void *data)
/* Bail if jack removed, the button is irrelevant and likely invalid */
if (!cs42l43_jack_present(priv)) {
dev_dbg(priv->dev, "Button ignored due to removal\n");
goto error;
return IRQ_NONE;
}
if (val & CS42L43_HSBIAS_CLAMP_STS_MASK) {
dev_dbg(priv->dev, "Button ignored due to bias sense\n");
goto error;
return IRQ_NONE;
}
val = (val & CS42L43_HSDET_DC_STS_MASK) >> CS42L43_HSDET_DC_STS_SHIFT;
@@ -424,45 +429,32 @@ irqreturn_t cs42l43_button_press(int irq, void *data)
snd_soc_jack_report(priv->jack_hp, buttons, CS42L43_JACK_BUTTONS);
iret = IRQ_HANDLED;
error:
mutex_unlock(&priv->jack_lock);
pm_runtime_put_autosuspend(priv->dev);
return iret;
return IRQ_HANDLED;
}
irqreturn_t cs42l43_button_release(int irq, void *data)
{
struct cs42l43_codec *priv = data;
irqreturn_t iret = IRQ_NONE;
int ret;
ret = pm_runtime_resume_and_get(priv->dev);
PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(priv->dev, pm);
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
if (ret) {
dev_err(priv->dev, "Failed to resume for button release: %d\n", ret);
return iret;
return IRQ_NONE;
}
mutex_lock(&priv->jack_lock);
guard(mutex)(&priv->jack_lock);
if (priv->button_detect_running) {
dev_dbg(priv->dev, "Button release IRQ\n");
snd_soc_jack_report(priv->jack_hp, 0, CS42L43_JACK_BUTTONS);
iret = IRQ_HANDLED;
} else {
if (!priv->button_detect_running) {
dev_dbg(priv->dev, "Spurious button release IRQ\n");
return IRQ_NONE;
}
mutex_unlock(&priv->jack_lock);
dev_dbg(priv->dev, "Button release IRQ\n");
snd_soc_jack_report(priv->jack_hp, 0, CS42L43_JACK_BUTTONS);
pm_runtime_put_autosuspend(priv->dev);
return iret;
return IRQ_HANDLED;
}
void cs42l43_bias_sense_timeout(struct work_struct *work)
@@ -472,13 +464,14 @@ void cs42l43_bias_sense_timeout(struct work_struct *work)
struct cs42l43 *cs42l43 = priv->core;
int ret;
ret = pm_runtime_resume_and_get(priv->dev);
PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(priv->dev, pm);
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
if (ret) {
dev_err(priv->dev, "Failed to resume for bias sense: %d\n", ret);
return;
}
mutex_lock(&priv->jack_lock);
guard(mutex)(&priv->jack_lock);
if (cs42l43_jack_present(priv) && priv->button_detect_running) {
dev_dbg(priv->dev, "Bias sense timeout out, restore bias\n");
@@ -491,10 +484,6 @@ void cs42l43_bias_sense_timeout(struct work_struct *work)
CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK,
CS42L43_AUTO_HSBIAS_CLAMP_EN_MASK);
}
mutex_unlock(&priv->jack_lock);
pm_runtime_put_autosuspend(priv->dev);
}
static const struct reg_sequence cs42l43_3pole_patch[] = {
@@ -896,9 +885,8 @@ int cs42l43_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
mutex_lock(&priv->jack_lock);
guard(mutex)(&priv->jack_lock);
ucontrol->value.integer.value[0] = priv->jack_override;
mutex_unlock(&priv->jack_lock);
return 0;
}
@@ -914,17 +902,13 @@ int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u
if (override >= e->items)
return -EINVAL;
mutex_lock(&priv->jack_lock);
guard(mutex)(&priv->jack_lock);
if (!cs42l43_jack_present(priv)) {
mutex_unlock(&priv->jack_lock);
if (!cs42l43_jack_present(priv))
return -EBUSY;
}
if (override == priv->jack_override) {
mutex_unlock(&priv->jack_lock);
if (override == priv->jack_override)
return 0;
}
priv->jack_override = override;
@@ -984,7 +968,5 @@ int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u
cs42l43_jack_override_modes[override].report);
}
mutex_unlock(&priv->jack_lock);
return 1;
}

View File

@@ -8,6 +8,7 @@
#include <linux/bitops.h>
#include <linux/bits.h>
#include <linux/build_bug.h>
#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -1207,14 +1208,12 @@ static void cs42l43_spk_vu_sync(struct cs42l43_codec *priv)
{
struct cs42l43 *cs42l43 = priv->core;
mutex_lock(&priv->spk_vu_lock);
guard(mutex)(&priv->spk_vu_lock);
regmap_update_bits(cs42l43->regmap, CS42L43_INTP_VOLUME_CTRL1,
CS42L43_AMP1_2_VU_MASK, CS42L43_AMP1_2_VU_MASK);
regmap_update_bits(cs42l43->regmap, CS42L43_INTP_VOLUME_CTRL1,
CS42L43_AMP1_2_VU_MASK, 0);
mutex_unlock(&priv->spk_vu_lock);
}
static int cs42l43_shutter_get(struct cs42l43_codec *priv, unsigned int shift)
@@ -1601,7 +1600,7 @@ static int cs42l43_pll_ev(struct snd_soc_dapm_widget *w,
struct cs42l43 *cs42l43 = priv->core;
int ret;
mutex_lock(&cs42l43->pll_lock);
guard(mutex)(&cs42l43->pll_lock);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -1626,8 +1625,6 @@ static int cs42l43_pll_ev(struct snd_soc_dapm_widget *w,
break;
}
mutex_unlock(&cs42l43->pll_lock);
return ret;
}
@@ -2565,13 +2562,10 @@ static int cs42l43_set_sysclk(struct snd_soc_component *component, int clk_id,
{
struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
struct cs42l43 *cs42l43 = priv->core;
int ret;
mutex_lock(&cs42l43->pll_lock);
ret = cs42l43_set_pll(priv, src, freq);
mutex_unlock(&cs42l43->pll_lock);
guard(mutex)(&cs42l43->pll_lock);
return ret;
return cs42l43_set_pll(priv, src, freq);
}
static int cs42l43_component_probe(struct snd_soc_component *component)
@@ -2941,8 +2935,8 @@ static const struct dev_pm_ops cs42l43_codec_pm_ops = {
};
static const struct platform_device_id cs42l43_codec_id_table[] = {
{ "cs42l43-codec", },
{}
{ .name = "cs42l43-codec" },
{ }
};
MODULE_DEVICE_TABLE(platform, cs42l43_codec_id_table);

View File

@@ -10,6 +10,7 @@
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/cleanup.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -281,10 +282,9 @@ static int cs42l84_set_jack(struct snd_soc_component *component, struct snd_soc_
struct cs42l84_private *cs42l84 = snd_soc_component_get_drvdata(component);
/* Prevent race with interrupt handler */
mutex_lock(&cs42l84->irq_lock);
guard(mutex)(&cs42l84->irq_lock);
cs42l84->jack = jk;
snd_soc_jack_report(jk, cs42l84->hs_type, SND_JACK_HEADSET);
mutex_unlock(&cs42l84->irq_lock);
return 0;
}
@@ -831,7 +831,7 @@ static irqreturn_t cs42l84_irq_thread(int irq, void *data)
u8 current_ring_state;
int i;
mutex_lock(&cs42l84->irq_lock);
guard(mutex)(&cs42l84->irq_lock);
/* Read sticky registers to clear interrupt */
for (i = 0; i < ARRAY_SIZE(stickies); i++) {
regmap_read(cs42l84->regmap, irq_params_table[i].status_addr,
@@ -902,8 +902,6 @@ static irqreturn_t cs42l84_irq_thread(int irq, void *data)
break;
}
mutex_unlock(&cs42l84->irq_lock);
return IRQ_HANDLED;
}
@@ -919,8 +917,6 @@ static irqreturn_t cs42l84_irq_thread(int irq, void *data)
}
}
mutex_unlock(&cs42l84->irq_lock);
return IRQ_HANDLED;
}

View File

@@ -6,6 +6,7 @@
*
* Authors: Li Xu <li.xu@cirrus.com>
*/
#include <linux/cleanup.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -818,26 +819,26 @@ static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream,
unsigned int required_clk;
u8 dsd_speed;
mutex_lock(&cs43130->clk_mutex);
if (!cs43130->clk_req) {
/* no DAI is currently using clk */
if (!(CS43130_MCLK_22M % params_rate(params)))
required_clk = CS43130_MCLK_22M;
else
required_clk = CS43130_MCLK_24M;
scoped_guard(mutex, &cs43130->clk_mutex) {
if (!cs43130->clk_req) {
/* no DAI is currently using clk */
if (!(CS43130_MCLK_22M % params_rate(params)))
required_clk = CS43130_MCLK_22M;
else
required_clk = CS43130_MCLK_24M;
cs43130_set_pll(component, 0, 0, cs43130->mclk, required_clk);
if (cs43130->pll_bypass)
cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);
else
cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);
cs43130_set_pll(component, 0, 0, cs43130->mclk, required_clk);
if (cs43130->pll_bypass)
cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);
else
cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);
}
cs43130->clk_req++;
if (cs43130->clk_req == 2)
cs43130_pcm_dsd_mix(true, cs43130->regmap);
}
cs43130->clk_req++;
if (cs43130->clk_req == 2)
cs43130_pcm_dsd_mix(true, cs43130->regmap);
mutex_unlock(&cs43130->clk_mutex);
switch (params_rate(params)) {
case 176400:
dsd_speed = 0;
@@ -881,26 +882,26 @@ static int cs43130_hw_params(struct snd_pcm_substream *substream,
unsigned int required_clk;
u8 dsd_speed;
mutex_lock(&cs43130->clk_mutex);
if (!cs43130->clk_req) {
/* no DAI is currently using clk */
if (!(CS43130_MCLK_22M % params_rate(params)))
required_clk = CS43130_MCLK_22M;
else
required_clk = CS43130_MCLK_24M;
scoped_guard(mutex, &cs43130->clk_mutex) {
if (!cs43130->clk_req) {
/* no DAI is currently using clk */
if (!(CS43130_MCLK_22M % params_rate(params)))
required_clk = CS43130_MCLK_22M;
else
required_clk = CS43130_MCLK_24M;
cs43130_set_pll(component, 0, 0, cs43130->mclk, required_clk);
if (cs43130->pll_bypass)
cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);
else
cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);
cs43130_set_pll(component, 0, 0, cs43130->mclk, required_clk);
if (cs43130->pll_bypass)
cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);
else
cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);
}
cs43130->clk_req++;
if (cs43130->clk_req == 2)
cs43130_pcm_dsd_mix(true, cs43130->regmap);
}
cs43130->clk_req++;
if (cs43130->clk_req == 2)
cs43130_pcm_dsd_mix(true, cs43130->regmap);
mutex_unlock(&cs43130->clk_mutex);
switch (dai->id) {
case CS43130_ASP_DOP_DAI:
case CS43130_XSP_DOP_DAI:
@@ -988,14 +989,13 @@ static int cs43130_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component;
struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);
mutex_lock(&cs43130->clk_mutex);
guard(mutex)(&cs43130->clk_mutex);
cs43130->clk_req--;
if (!cs43130->clk_req) {
/* no DAI is currently using clk */
cs43130_change_clksrc(component, CS43130_MCLK_SRC_RCO);
cs43130_pcm_dsd_mix(false, cs43130->regmap);
}
mutex_unlock(&cs43130->clk_mutex);
return 0;
}

View File

@@ -340,7 +340,13 @@ static int cs4349_runtime_resume(struct device *dev)
gpiod_set_value_cansleep(cs4349->reset_gpio, 1);
regcache_cache_only(cs4349->regmap, false);
regcache_sync(cs4349->regmap);
ret = regcache_sync(cs4349->regmap);
if (ret) {
regcache_cache_only(cs4349->regmap, true);
regcache_mark_dirty(cs4349->regmap);
gpiod_set_value_cansleep(cs4349->reset_gpio, 0);
return ret;
}
return 0;
}

View File

@@ -6,6 +6,7 @@
// Cirrus Logic International Semiconductor Ltd.
//
#include <linux/cleanup.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
@@ -1285,9 +1286,8 @@ static int cs47l15_component_probe(struct snd_soc_component *component)
snd_soc_component_init_regmap(component, madera->regmap);
mutex_lock(&madera->dapm_ptr_lock);
madera->dapm = snd_soc_component_to_dapm(component);
mutex_unlock(&madera->dapm_ptr_lock);
scoped_guard(mutex, &madera->dapm_ptr_lock)
madera->dapm = snd_soc_component_to_dapm(component);
ret = madera_init_inputs(component);
if (ret)
@@ -1317,9 +1317,8 @@ static void cs47l15_component_remove(struct snd_soc_component *component)
struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
struct madera *madera = cs47l15->core.madera;
mutex_lock(&madera->dapm_ptr_lock);
madera->dapm = NULL;
mutex_unlock(&madera->dapm_ptr_lock);
scoped_guard(mutex, &madera->dapm_ptr_lock)
madera->dapm = NULL;
wm_adsp2_component_remove(&cs47l15->core.adsp[0], component);
}

View File

@@ -6,6 +6,7 @@
// Cirrus Logic International Semiconductor Ltd.
//
#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/init.h>
@@ -1566,9 +1567,8 @@ static int cs47l35_component_probe(struct snd_soc_component *component)
snd_soc_component_init_regmap(component, madera->regmap);
mutex_lock(&madera->dapm_ptr_lock);
madera->dapm = snd_soc_component_to_dapm(component);
mutex_unlock(&madera->dapm_ptr_lock);
scoped_guard(mutex, &madera->dapm_ptr_lock)
madera->dapm = snd_soc_component_to_dapm(component);
ret = madera_init_inputs(component);
if (ret)
@@ -1600,9 +1600,8 @@ static void cs47l35_component_remove(struct snd_soc_component *component)
struct madera *madera = cs47l35->core.madera;
int i;
mutex_lock(&madera->dapm_ptr_lock);
madera->dapm = NULL;
mutex_unlock(&madera->dapm_ptr_lock);
scoped_guard(mutex, &madera->dapm_ptr_lock)
madera->dapm = NULL;
for (i = 0; i < CS47L35_NUM_ADSP; i++)
wm_adsp2_component_remove(&cs47l35->core.adsp[i], component);

View File

@@ -6,6 +6,7 @@
// Cirrus Logic International Semiconductor Ltd.
//
#include <linux/cleanup.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
@@ -2504,9 +2505,8 @@ static int cs47l85_component_probe(struct snd_soc_component *component)
snd_soc_component_init_regmap(component, madera->regmap);
mutex_lock(&madera->dapm_ptr_lock);
madera->dapm = snd_soc_component_to_dapm(component);
mutex_unlock(&madera->dapm_ptr_lock);
scoped_guard(mutex, &madera->dapm_ptr_lock)
madera->dapm = snd_soc_component_to_dapm(component);
ret = madera_init_inputs(component);
if (ret)
@@ -2537,9 +2537,8 @@ static void cs47l85_component_remove(struct snd_soc_component *component)
struct madera *madera = cs47l85->core.madera;
int i;
mutex_lock(&madera->dapm_ptr_lock);
madera->dapm = NULL;
mutex_unlock(&madera->dapm_ptr_lock);
scoped_guard(mutex, &madera->dapm_ptr_lock)
madera->dapm = NULL;
for (i = 0; i < CS47L85_NUM_ADSP; i++)
wm_adsp2_component_remove(&cs47l85->core.adsp[i], component);

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