mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-27 22:13:55 -04:00
Merge remote-tracking branch 'asoc/for-7.3' into asoc-next
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
240
Documentation/devicetree/bindings/sound/cirrus,cs35l36.yaml
Normal file
240
Documentation/devicetree/bindings/sound/cirrus,cs35l36.yaml
Normal 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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -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>;
|
||||
};
|
||||
};
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
@@ -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>;
|
||||
};
|
||||
@@ -66,6 +66,10 @@ properties:
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
@@ -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>;
|
||||
};
|
||||
@@ -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";
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
93
Documentation/devicetree/bindings/sound/qcom,wsa8855.yaml
Normal file
93
Documentation/devicetree/bindings/sound/qcom,wsa8855.yaml
Normal 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";
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
58
Documentation/devicetree/bindings/sound/ti,omap4-dmic.yaml
Normal file
58
Documentation/devicetree/bindings/sound/ti,omap4-dmic.yaml
Normal 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";
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
621
include/sound/aw88399.h
Normal 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 */
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
/** @}*/
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -42,7 +42,7 @@ static const struct platform_device_id db1200_pids[] = {
|
||||
.name = "db1550-i2s",
|
||||
.driver_data = 5,
|
||||
},
|
||||
{},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, db1200_pids);
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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, ®_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, ®_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, ®_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)
|
||||
|
||||
1411
sound/soc/codecs/aw88399-lib.c
Normal file
1411
sound/soc/codecs/aw88399-lib.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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__ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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),
|
||||
{},
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, ®);
|
||||
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, ®);
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user