Merge remote-tracking branch 'asoc/for-5.8' into asoc-linus

This commit is contained in:
Mark Brown 2020-06-01 13:01:15 +01:00
commit 358c7c61fd
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
317 changed files with 15037 additions and 3929 deletions

View File

@ -17,6 +17,8 @@ properties:
compatible:
enum:
- fsl,imx8qxp-dsp
- fsl,imx8qm-dsp
- fsl,imx8mp-dsp
reg:
description: Should contain register location and length

View File

@ -1,9 +1,9 @@
Dialog Semiconductor DA7213 Audio Codec bindings
Dialog Semiconductor DA7212/DA7213 Audio Codec bindings
======
Required properties:
- compatible : Should be "dlg,da7213"
- compatible : Should be "dlg,da7212" or "dlg,da7213"
- reg: Specifies the I2C slave address
Optional properties:
@ -21,6 +21,10 @@ Optional properties:
- dlg,dmic-clkrate : DMIC clock frequency (Hz).
[<1500000>, <3000000>]
- VDDA-supply : Regulator phandle for Analogue power supply
- VDDMIC-supply : Regulator phandle for Mic Bias
- VDDIO-supply : Regulator phandle for I/O power supply
======
Example:

View File

@ -51,6 +51,10 @@ Optional properties:
will be in use as default. Otherwise, the big endian
mode will be in use for all the device registers.
- fsl,asrc-format : Defines a mutual sample format used by DPCM Back
Ends, which can replace the fsl,asrc-width.
The value is 2 (S16_LE), or 6 (S24_LE).
Example:
asrc: asrc@2034000 {

View File

@ -0,0 +1,101 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/fsl,easrc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP Asynchronous Sample Rate Converter (ASRC) Controller
maintainers:
- Shengjiu Wang <shengjiu.wang@nxp.com>
properties:
$nodename:
pattern: "^easrc@.*"
compatible:
const: fsl,imx8mn-easrc
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
items:
- description: Peripheral clock
clock-names:
items:
- const: mem
dmas:
maxItems: 8
dma-names:
items:
- const: ctx0_rx
- const: ctx0_tx
- const: ctx1_rx
- const: ctx1_tx
- const: ctx2_rx
- const: ctx2_tx
- const: ctx3_rx
- const: ctx3_tx
firmware-name:
allOf:
- $ref: /schemas/types.yaml#/definitions/string
- const: imx/easrc/easrc-imx8mn.bin
description: The coefficient table for the filters
fsl,asrc-rate:
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32
- minimum: 8000
- maximum: 192000
description: Defines a mutual sample rate used by DPCM Back Ends
fsl,asrc-format:
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32
- enum: [2, 6, 10, 32, 36]
default: 2
description:
Defines a mutual sample format used by DPCM Back Ends
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- dmas
- dma-names
- firmware-name
- fsl,asrc-rate
- fsl,asrc-format
examples:
- |
#include <dt-bindings/clock/imx8mn-clock.h>
easrc: easrc@300c0000 {
compatible = "fsl,imx8mn-easrc";
reg = <0x0 0x300c0000 0x0 0x10000>;
interrupts = <0x0 122 0x4>;
clocks = <&clk IMX8MN_CLK_ASRC_ROOT>;
clock-names = "mem";
dmas = <&sdma2 16 23 0> , <&sdma2 17 23 0>,
<&sdma2 18 23 0> , <&sdma2 19 23 0>,
<&sdma2 20 23 0> , <&sdma2 21 23 0>,
<&sdma2 22 23 0> , <&sdma2 23 23 0>;
dma-names = "ctx0_rx", "ctx0_tx",
"ctx1_rx", "ctx1_tx",
"ctx2_rx", "ctx2_tx",
"ctx3_rx", "ctx3_tx";
firmware-name = "imx/easrc/easrc-imx8mn.bin";
fsl,asrc-rate = <8000>;
fsl,asrc-format = <2>;
};

View File

@ -12,6 +12,7 @@ Required properties:
"fsl,imx35-esai",
"fsl,vf610-esai",
"fsl,imx6ull-esai",
"fsl,imx8qm-esai",
- reg : Offset and length of the register set for the device.

View File

@ -0,0 +1,122 @@
# SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/marvell,mmp-sspa.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Marvel SSPA Digital Audio Interface Bindings
maintainers:
- Lubomir Rintel <lkundrak@v3.sk>
properties:
$nodename:
pattern: "^audio-controller(@.*)?$"
compatible:
const: marvell,mmp-sspa
reg:
items:
- description: RX block
- description: TX block
interrupts:
maxItems: 1
clocks:
items:
- description: Clock for the Audio block
- description: I2S bit clock
clock-names:
items:
- const: audio
- const: bitclk
power-domains:
maxItems: 1
'#sound-dai-cells':
const: 0
dmas:
items:
- description: TX DMA Channel
- description: RX DMA Channel
dma-names:
items:
- const: tx
- const: rx
port:
type: object
properties:
endpoint:
type: object
properties:
remote-endpoint: true
frame-master:
type: boolean
description: SoC generates the frame clock
bitclock-master:
type: boolean
description: SoC generates the bit clock
dai-format:
$ref: /schemas/types.yaml#/definitions/string
description: The digital audio format
const: i2s
required:
- remote-endpoint
required:
- endpoint
additionalProperties: false
required:
- "#sound-dai-cells"
- compatible
- reg
- interrupts
- clocks
- clock-names
- dmas
- dma-names
- port
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/marvell,mmp2.h>
audio-controller@d42a0c00 {
compatible = "marvell,mmp-sspa";
reg = <0xd42a0c00 0x30>,
<0xd42a0c80 0x30>;
interrupts = <2>;
clock-names = "audio", "bitclk";
clocks = <&soc_clocks 127>,
<&audio_clk 1>;
#sound-dai-cells = <0>;
dmas = <&adma0 0>, <&adma0 1>;
dma-names = "tx", "rx";
port {
endpoint {
remote-endpoint = <&rt5631_0>;
frame-master;
bitclock-master;
dai-format = "i2s";
};
};
};
...

View File

@ -1,10 +1,11 @@
NAU8810 audio CODEC
NAU8810/NAU8812/NAU8814 audio CODEC
This device supports I2C only.
Required properties:
- compatible : "nuvoton,nau8810"
- compatible : One of "nuvoton,nau8810" or "nuvoton,nau8812" or
"nuvoton,nau8814"
- reg : the I2C address of the device.

View File

@ -29,6 +29,7 @@ Optional properties:
- nvidia,hp-det-gpios : The GPIO that detect headphones are plugged in
- nvidia,int-mic-en-gpios : The GPIO that enables the internal microphone
- nvidia,ext-mic-en-gpios : The GPIO that enables the external microphone
- nvidia,headset : The Mic Jack represents state of the headset microphone pin
Example:

View File

@ -30,6 +30,8 @@ Required properties:
- reg : Must contain an address for each entry in reg-names.
- reg-names : A list which must include the following entries:
* "lpass-lpaif"
- #address-cells : Must be 1
- #size-cells : Must be 0
@ -37,6 +39,20 @@ Optional properties:
- qcom,adsp : Phandle for the audio DSP node
By default, the driver uses up to 4 MI2S SD lines, for a total of 8 channels.
The SD lines to use can be configured by adding subnodes for each of the DAIs.
Required properties for each DAI (represented by a subnode):
- reg : Must be one of the DAI IDs
(usually part of dt-bindings header)
- qcom,playback-sd-lines: List of serial data lines to use for playback
Each SD line should be represented by a number from 0-3.
- qcom,capture-sd-lines : List of serial data lines to use for capture
Each SD line should be represented by a number from 0-3.
Note that adding a subnode changes the default to "no lines configured",
so both playback and capture lines should be configured when a subnode is added.
Example:
lpass@28100000 {
@ -51,4 +67,13 @@ lpass@28100000 {
reg = <0x28100000 0x10000>;
reg-names = "lpass-lpaif";
qcom,adsp = <&adsp>;
#address-cells = <1>;
#size-cells = <0>;
/* Optional to set different MI2S SD lines */
dai@3 {
reg = <MI2S_QUATERNARY>;
qcom,playback-sd-lines = <0 1>;
};
};

View File

@ -29,7 +29,7 @@ used by the apr service device.
Definition: Must be 0
= EXAMPLE
q6adm@8 {
apr-service@8 {
compatible = "qcom,q6adm";
reg = <APR_SVC_ADM>;
q6routing: routing {

View File

@ -100,7 +100,7 @@ configuration of each dai. Must contain the following properties.
= EXAMPLE
q6afe@4 {
apr-service@4 {
compatible = "qcom,q6afe";
reg = <APR_SVC_AFE>;
@ -110,12 +110,12 @@ q6afe@4 {
#address-cells = <1>;
#size-cells = <0>;
hdmi@1 {
reg = <1>;
dai@1 {
reg = <HDMI_RX>;
};
tdm@24 {
reg = <24>;
dai@24 {
reg = <PRIMARY_TDM_RX_0>;
qcom,tdm-sync-mode = <1>:
qcom,tdm-sync-src = <1>;
qcom,tdm-data-out = <0>;
@ -125,8 +125,8 @@ q6afe@4 {
};
tdm@25 {
reg = <25>;
dai@25 {
reg = <PRIMARY_TDM_TX_0>;
qcom,tdm-sync-mode = <1>:
qcom,tdm-sync-src = <1>;
qcom,tdm-data-out = <0>;
@ -135,43 +135,43 @@ q6afe@4 {
qcom,tdm-data-align = <0>;
};
prim-mi2s-rx@16 {
reg = <16>;
dai@16 {
reg = <PRIMARY_MI2S_RX>;
qcom,sd-lines = <0 2>;
};
prim-mi2s-tx@17 {
reg = <17>;
dai@17 {
reg = <PRIMARY_MI2S_TX>;
qcom,sd-lines = <1>;
};
sec-mi2s-rx@18 {
reg = <18>;
dai@18 {
reg = <SECONDARY_MI2S_RX>;
qcom,sd-lines = <0 3>;
};
sec-mi2s-tx@19 {
reg = <19>;
dai@19 {
reg = <SECONDARY_MI2S_TX>;
qcom,sd-lines = <1>;
};
tert-mi2s-rx@20 {
reg = <20>;
dai@20 {
reg = <TERTIARY_MI2S_RX>;
qcom,sd-lines = <1 3>;
};
tert-mi2s-tx@21 {
reg = <21>;
dai@21 {
reg = <TERTIARY_MI2S_TX>;
qcom,sd-lines = <0>;
};
quat-mi2s-rx@22 {
reg = <22>;
dai@22 {
reg = <QUATERNARY_MI2S_RX>;
qcom,sd-lines = <0>;
};
quat-mi2s-tx@23 {
reg = <23>;
dai@23 {
reg = <QUATERNARY_MI2S_TX>;
qcom,sd-lines = <1>;
};
};

View File

@ -51,13 +51,16 @@ configuration of each dai. Must contain the following properties.
= EXAMPLE
q6asm@7 {
apr-service@7 {
compatible = "qcom,q6asm";
reg = <APR_SVC_ASM>;
q6asmdai: dais {
compatible = "qcom,q6asm-dais";
#address-cells = <1>;
#size-cells = <0>;
#sound-dai-cells = <1>;
mm@0 {
dai@0 {
reg = <0>;
direction = <2>;
is-compress-dai;

View File

@ -15,7 +15,7 @@ used by the apr service device.
example "qcom,q6core-v2.0"
= EXAMPLE
q6core@3 {
apr-service@3 {
compatible = "qcom,q6core";
reg = <APR_SVC_ADSP_CORE>;
};

View File

@ -263,6 +263,7 @@ Required properties:
"renesas,rcar_sound-gen2" if generation2 (or RZ/G1)
"renesas,rcar_sound-gen3" if generation3 (or RZ/G2)
Examples with soctypes are:
- "renesas,rcar_sound-r8a7742" (RZ/G1H)
- "renesas,rcar_sound-r8a7743" (RZ/G1M)
- "renesas,rcar_sound-r8a7744" (RZ/G1N)
- "renesas,rcar_sound-r8a7745" (RZ/G1E)

View File

@ -24,6 +24,7 @@ properties:
- rockchip,rk3188-i2s
- rockchip,rk3228-i2s
- rockchip,rk3288-i2s
- rockchip,rk3308-i2s
- rockchip,rk3328-i2s
- rockchip,rk3366-i2s
- rockchip,rk3368-i2s
@ -47,14 +48,15 @@ properties:
- const: i2s_hclk
dmas:
items:
- description: TX DMA Channel
- description: RX DMA Channel
minItems: 1
maxItems: 2
dma-names:
items:
- const: tx
oneOf:
- const: rx
- items:
- const: tx
- const: rx
power-domains:
maxItems: 1

View File

@ -0,0 +1,17 @@
RT1016 Stereo Class D Audio Amplifier
This device supports I2C only.
Required properties:
- compatible : "realtek,rt1016".
- reg : The I2C address of the device.
Example:
rt1016: codec@1a {
compatible = "realtek,rt1016";
reg = <0x1a>;
};

View File

@ -1,351 +0,0 @@
Simple-Card:
Simple-Card specifies audio DAI connections of SoC <-> codec.
Required properties:
- compatible : "simple-audio-card"
Optional properties:
- simple-audio-card,name : User specified audio sound card name, one string
property.
- simple-audio-card,widgets : Please refer to widgets.txt.
- simple-audio-card,routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the
connection's sink, the second being the connection's
source.
- simple-audio-card,mclk-fs : Multiplication factor between stream rate and codec
mclk. When defined, mclk-fs property defined in
dai-link sub nodes are ignored.
- simple-audio-card,hp-det-gpio : Reference to GPIO that signals when
headphones are attached.
- simple-audio-card,mic-det-gpio : Reference to GPIO that signals when
a microphone is attached.
- simple-audio-card,aux-devs : List of phandles pointing to auxiliary devices, such
as amplifiers, to be added to the sound card.
- simple-audio-card,pin-switches : List of strings containing the widget names for
which pin switches must be created.
Optional subnodes:
- simple-audio-card,dai-link : Container for dai-link level
properties and the CPU and CODEC
sub-nodes. This container may be
omitted when the card has only one
DAI link. See the examples and the
section below.
Dai-link subnode properties and subnodes:
If dai-link subnode is omitted and the subnode properties are directly
under "sound"-node the subnode property and subnode names have to be
prefixed with "simple-audio-card,"-prefix.
Required dai-link subnodes:
- cpu : CPU sub-node
- codec : CODEC sub-node
Optional dai-link subnode properties:
- format : CPU/CODEC common audio format.
"i2s", "right_j", "left_j" , "dsp_a"
"dsp_b", "ac97", "pdm", "msb", "lsb"
- frame-master : Indicates dai-link frame master.
phandle to a cpu or codec subnode.
- bitclock-master : Indicates dai-link bit clock master.
phandle to a cpu or codec subnode.
- bitclock-inversion : bool property. Add this if the
dai-link uses bit clock inversion.
- frame-inversion : bool property. Add this if the
dai-link uses frame clock inversion.
- mclk-fs : Multiplication factor between stream
rate and codec mclk, applied only for
the dai-link.
For backward compatibility the frame-master and bitclock-master
properties can be used as booleans in codec subnode to indicate if the
codec is the dai-link frame or bit clock master. In this case there
should be no dai-link node, the same properties should not be present
at sound-node level, and the bitclock-inversion and frame-inversion
properties should also be placed in the codec node if needed.
Required CPU/CODEC subnodes properties:
- sound-dai : phandle and port of CPU/CODEC
Optional CPU/CODEC subnodes properties:
- dai-tdm-slot-num : Please refer to tdm-slot.txt.
- dai-tdm-slot-width : Please refer to tdm-slot.txt.
- clocks / system-clock-frequency : specify subnode's clock if needed.
it can be specified via "clocks" if system has
clock node (= common clock), or "system-clock-frequency"
(if system doens't support common clock)
If a clock is specified, it is
enabled with clk_prepare_enable()
in dai startup() and disabled with
clk_disable_unprepare() in dai
shutdown().
If a clock is specified and a
multiplication factor is given with
mclk-fs, the clock will be set to the
calculated mclk frequency when the
stream starts.
- system-clock-direction-out : specifies clock direction as 'out' on
initialization. It is useful for some aCPUs with
fixed clocks.
-------------------------------------------
Example 1 - single DAI link:
-------------------------------------------
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "VF610-Tower-Sound-Card";
simple-audio-card,format = "left_j";
simple-audio-card,bitclock-master = <&dailink0_master>;
simple-audio-card,frame-master = <&dailink0_master>;
simple-audio-card,widgets =
"Microphone", "Microphone Jack",
"Headphone", "Headphone Jack",
"Speaker", "External Speaker";
simple-audio-card,routing =
"MIC_IN", "Microphone Jack",
"Headphone Jack", "HP_OUT",
"External Speaker", "LINE_OUT";
simple-audio-card,cpu {
sound-dai = <&sh_fsi2 0>;
};
dailink0_master: simple-audio-card,codec {
sound-dai = <&ak4648>;
clocks = <&osc>;
};
};
&i2c0 {
ak4648: ak4648@12 {
#sound-dai-cells = <0>;
compatible = "asahi-kasei,ak4648";
reg = <0x12>;
};
};
sh_fsi2: sh_fsi2@ec230000 {
#sound-dai-cells = <1>;
compatible = "renesas,sh_fsi2";
reg = <0xec230000 0x400>;
interrupt-parent = <&gic>;
interrupts = <0 146 0x4>;
};
-------------------------------------------
Example 2 - many DAI links:
-------------------------------------------
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "Cubox Audio";
simple-audio-card,dai-link@0 { /* I2S - HDMI */
reg = <0>;
format = "i2s";
cpu {
sound-dai = <&audio1 0>;
};
codec {
sound-dai = <&tda998x 0>;
};
};
simple-audio-card,dai-link@1 { /* S/PDIF - HDMI */
reg = <1>;
cpu {
sound-dai = <&audio1 1>;
};
codec {
sound-dai = <&tda998x 1>;
};
};
simple-audio-card,dai-link@2 { /* S/PDIF - S/PDIF */
reg = <2>;
cpu {
sound-dai = <&audio1 1>;
};
codec {
sound-dai = <&spdif_codec>;
};
};
};
-------------------------------------------
Example 3 - route audio from IMX6 SSI2 through TLV320DAC3100 codec
through TPA6130A2 amplifier to headphones:
-------------------------------------------
&i2c0 {
codec: tlv320dac3100@18 {
compatible = "ti,tlv320dac3100";
...
}
amp: tpa6130a2@60 {
compatible = "ti,tpa6130a2";
...
}
}
sound {
compatible = "simple-audio-card";
...
simple-audio-card,widgets =
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"Headphone Jack", "HPLEFT",
"Headphone Jack", "HPRIGHT",
"LEFTIN", "HPL",
"RIGHTIN", "HPR";
simple-audio-card,aux-devs = <&amp>;
simple-audio-card,cpu {
sound-dai = <&ssi2>;
};
simple-audio-card,codec {
sound-dai = <&codec>;
clocks = ...
};
};
-------------------------------------------
Example 4. Sampling Rate Conversion
-------------------------------------------
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "rsnd-ak4643";
simple-audio-card,format = "left_j";
simple-audio-card,bitclock-master = <&sndcodec>;
simple-audio-card,frame-master = <&sndcodec>;
simple-audio-card,convert-rate = <48000>;
simple-audio-card,prefix = "ak4642";
simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
"DAI0 Capture", "ak4642 Capture";
sndcpu: simple-audio-card,cpu {
sound-dai = <&rcar_sound>;
};
sndcodec: simple-audio-card,codec {
sound-dai = <&ak4643>;
system-clock-frequency = <11289600>;
};
};
-------------------------------------------
Example 5. 2 CPU 1 Codec (Mixing)
-------------------------------------------
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "rsnd-ak4643";
simple-audio-card,format = "left_j";
simple-audio-card,bitclock-master = <&dpcmcpu>;
simple-audio-card,frame-master = <&dpcmcpu>;
simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
"ak4642 Playback", "DAI1 Playback";
dpcmcpu: cpu@0 {
sound-dai = <&rcar_sound 0>;
};
cpu@1 {
sound-dai = <&rcar_sound 1>;
};
codec {
prefix = "ak4642";
sound-dai = <&ak4643>;
clocks = <&audio_clock>;
};
};
-------------------------------------------
Example 6 - many DAI links with DPCM:
-------------------------------------------
CPU0 ------ ak4613
CPU1 ------ PCM3168A-p /* DPCM 1ch/2ch */
CPU2 --/ /* DPCM 3ch/4ch */
CPU3 --/ /* DPCM 5ch/6ch */
CPU4 --/ /* DPCM 7ch/8ch */
CPU5 ------ PCM3168A-c
sound {
compatible = "simple-audio-card";
simple-audio-card,routing =
"pcm3168a Playback", "DAI1 Playback",
"pcm3168a Playback", "DAI2 Playback",
"pcm3168a Playback", "DAI3 Playback",
"pcm3168a Playback", "DAI4 Playback";
simple-audio-card,dai-link@0 {
format = "left_j";
bitclock-master = <&sndcpu0>;
frame-master = <&sndcpu0>;
sndcpu0: cpu {
sound-dai = <&rcar_sound 0>;
};
codec {
sound-dai = <&ak4613>;
};
};
simple-audio-card,dai-link@1 {
format = "i2s";
bitclock-master = <&sndcpu1>;
frame-master = <&sndcpu1>;
convert-channels = <8>; /* TDM Split */
sndcpu1: cpu@0 {
sound-dai = <&rcar_sound 1>;
};
cpu@1 {
sound-dai = <&rcar_sound 2>;
};
cpu@2 {
sound-dai = <&rcar_sound 3>;
};
cpu@3 {
sound-dai = <&rcar_sound 4>;
};
codec {
mclk-fs = <512>;
prefix = "pcm3168a";
dai-tdm-slot-num = <8>;
sound-dai = <&pcm3168a 0>;
};
};
simple-audio-card,dai-link@2 {
format = "i2s";
bitclock-master = <&sndcpu2>;
frame-master = <&sndcpu2>;
sndcpu2: cpu {
sound-dai = <&rcar_sound 5>;
};
codec {
mclk-fs = <512>;
prefix = "pcm3168a";
sound-dai = <&pcm3168a 1>;
};
};
};

View File

@ -0,0 +1,484 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/simple-card.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Simple Audio Card Driver Device Tree Bindings
maintainers:
- Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
definitions:
frame-master:
description: Indicates dai-link frame master.
allOf:
- $ref: /schemas/types.yaml#/definitions/phandle-array
- maxItems: 1
bitclock-master:
description: Indicates dai-link bit clock master
allOf:
- $ref: /schemas/types.yaml#/definitions/phandle-array
- maxItems: 1
frame-inversion:
description: dai-link uses frame clock inversion
$ref: /schemas/types.yaml#/definitions/flag
bitclock-inversion:
description: dai-link uses bit clock inversion
$ref: /schemas/types.yaml#/definitions/flag
dai-tdm-slot-num:
description: see tdm-slot.txt.
$ref: /schemas/types.yaml#/definitions/uint32
dai-tdm-slot-width:
description: see tdm-slot.txt.
$ref: /schemas/types.yaml#/definitions/uint32
system-clock-frequency:
description: |
If a clock is specified and a multiplication factor is given with
mclk-fs, the clock will be set to the calculated mclk frequency
when the stream starts.
$ref: /schemas/types.yaml#/definitions/uint32
system-clock-direction-out:
description: |
specifies clock direction as 'out' on initialization.
It is useful for some aCPUs with fixed clocks.
$ref: /schemas/types.yaml#/definitions/flag
mclk-fs:
description: |
Multiplication factor between stream rate and codec mclk.
When defined, mclk-fs property defined in dai-link sub nodes are ignored.
$ref: /schemas/types.yaml#/definitions/uint32
aux-devs:
description: |
List of phandles pointing to auxiliary devices, such
as amplifiers, to be added to the sound card.
$ref: /schemas/types.yaml#/definitions/phandle-array
convert-rate:
description: CPU to Codec rate convert.
$ref: /schemas/types.yaml#/definitions/uint32
convert-channels:
description: CPU to Codec rate channels.
$ref: /schemas/types.yaml#/definitions/uint32
prefix:
description: "device name prefix"
$ref: /schemas/types.yaml#/definitions/string
label:
maxItems: 1
routing:
description: |
A list of the connections between audio components.
Each entry is a pair of strings, the first being the
connection's sink, the second being the connection's source.
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
widgets:
description: User specified audio sound widgets.
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
pin-switches:
description: the widget names for which pin switches must be created.
$ref: /schemas/types.yaml#/definitions/string-array
format:
description: audio format.
items:
enum:
- i2s
- right_j
- left_j
- dsp_a
- dsp_b
- ac97
- pdm
- msb
- lsb
dai:
type: object
properties:
sound-dai:
maxItems: 1
# common properties
mclk-fs:
$ref: "#/definitions/mclk-fs"
prefix:
$ref: "#/definitions/prefix"
frame-inversion:
$ref: "#/definitions/frame-inversion"
bitclock-inversion:
$ref: "#/definitions/bitclock-inversion"
frame-master:
$ref: /schemas/types.yaml#/definitions/flag
bitclock-master:
$ref: /schemas/types.yaml#/definitions/flag
dai-tdm-slot-num:
$ref: "#/definitions/dai-tdm-slot-num"
dai-tdm-slot-width:
$ref: "#/definitions/dai-tdm-slot-width"
clocks:
maxItems: 1
system-clock-frequency:
$ref: "#/definitions/system-clock-frequency"
system-clock-direction-out:
$ref: "#/definitions/system-clock-direction-out"
required:
- sound-dai
properties:
compatible:
contains:
enum:
- simple-audio-card
- simple-scu-audio-card
"#address-cells":
const: 1
"#size-cells":
const: 0
label:
$ref: "#/definitions/label"
simple-audio-card,name:
description: User specified audio sound card name.
$ref: /schemas/types.yaml#/definitions/string
# use patternProperties to avoid naming "xxx,yyy" issue
patternProperties:
"^simple-audio-card,widgets$":
$ref: "#/definitions/widgets"
"^simple-audio-card,routing$":
$ref: "#/definitions/routing"
"^simple-audio-card,cpu(@[0-9a-f]+)?":
$ref: "#/definitions/dai"
"^simple-audio-card,codec(@[0-9a-f]+)?":
$ref: "#/definitions/dai"
# common properties
"^simple-audio-card,frame-master$":
$ref: "#/definitions/frame-master"
"^simple-audio-card,bitclock-master$":
$ref: "#/definitions/bitclock-master"
"^simple-audio-card,frame-inversion$":
$ref: "#/definitions/frame-inversion"
"^simple-audio-card,bitclock-inversion$":
$ref: "#/definitions/bitclock-inversion"
"^simple-audio-card,format$":
$ref: "#/definitions/format"
"^simple-audio-card,mclk-fs$":
$ref: "#/definitions/mclk-fs"
"^simple-audio-card,aux-devs$":
$ref: "#/definitions/aux-devs"
"^simple-audio-card,convert-rate$":
$ref: "#/definitions/convert-rate"
"^simple-audio-card,convert-channels$":
$ref: "#/definitions/convert-channels"
"^simple-audio-card,prefix$":
$ref: "#/definitions/prefix"
"^simple-audio-card,pin-switches$":
$ref: "#/definitions/pin-switches"
"^simple-audio-card,hp-det-gpio$":
maxItems: 1
"^simple-audio-card,mic-det-gpio$":
maxItems: 1
"^simple-audio-card,dai-link(@[0-9a-f]+)?$":
description: |
Container for dai-link level properties and the CPU and CODEC sub-nodes.
This container may be omitted when the card has only one DAI link.
type: object
properties:
reg:
maxItems: 1
# common properties
frame-master:
$ref: "#/definitions/frame-master"
bitclock-master:
$ref: "#/definitions/bitclock-master"
frame-inversion:
$ref: "#/definitions/frame-inversion"
bitclock-inversion:
$ref: "#/definitions/bitclock-inversion"
format:
$ref: "#/definitions/format"
mclk-fs:
$ref: "#/definitions/mclk-fs"
aux-devs:
$ref: "#/definitions/aux-devs"
convert-rate:
$ref: "#/definitions/convert-rate"
convert-channels:
$ref: "#/definitions/convert-channels"
prefix:
$ref: "#/definitions/prefix"
pin-switches:
$ref: "#/definitions/pin-switches"
hp-det-gpio:
maxItems: 1
mic-det-gpio:
maxItems: 1
patternProperties:
"^cpu(@[0-9a-f]+)?":
$ref: "#/definitions/dai"
"^codec(@[0-9a-f]+)?":
$ref: "#/definitions/dai"
additionalProperties: false
required:
- compatible
additionalProperties: false
examples:
#--------------------
# single DAI link
#--------------------
- |
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "VF610-Tower-Sound-Card";
simple-audio-card,format = "left_j";
simple-audio-card,bitclock-master = <&dailink0_master>;
simple-audio-card,frame-master = <&dailink0_master>;
simple-audio-card,widgets =
"Microphone", "Microphone Jack",
"Headphone", "Headphone Jack",
"Speaker", "External Speaker";
simple-audio-card,routing =
"MIC_IN", "Microphone Jack",
"Headphone Jack", "HP_OUT",
"External Speaker", "LINE_OUT";
simple-audio-card,cpu {
sound-dai = <&sh_fsi2 0>;
};
dailink0_master: simple-audio-card,codec {
sound-dai = <&ak4648>;
clocks = <&osc>;
};
};
#--------------------
# Multi DAI links
#--------------------
- |
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "Cubox Audio";
#address-cells = <1>;
#size-cells = <0>;
simple-audio-card,dai-link@0 { /* I2S - HDMI */
reg = <0>;
format = "i2s";
cpu {
sound-dai = <&audio0>;
};
codec {
sound-dai = <&tda998x0>;
};
};
simple-audio-card,dai-link@1 { /* S/PDIF - HDMI */
reg = <1>;
cpu {
sound-dai = <&audio1>;
};
codec {
sound-dai = <&tda998x1>;
};
};
simple-audio-card,dai-link@2 { /* S/PDIF - S/PDIF */
reg = <2>;
cpu {
sound-dai = <&audio2>;
};
codec {
sound-dai = <&spdif_codec>;
};
};
};
#--------------------
# route audio from IMX6 SSI2 through TLV320DAC3100 codec
# through TPA6130A2 amplifier to headphones:
#--------------------
- |
sound {
compatible = "simple-audio-card";
simple-audio-card,widgets =
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"Headphone Jack", "HPLEFT",
"Headphone Jack", "HPRIGHT",
"LEFTIN", "HPL",
"RIGHTIN", "HPR";
simple-audio-card,aux-devs = <&amp>;
simple-audio-card,cpu {
sound-dai = <&ssi2>;
};
simple-audio-card,codec {
sound-dai = <&codec>;
clocks = <&clocks>;
};
};
#--------------------
# Sampling Rate Conversion
#--------------------
- |
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "rsnd-ak4643";
simple-audio-card,format = "left_j";
simple-audio-card,bitclock-master = <&sndcodec>;
simple-audio-card,frame-master = <&sndcodec>;
simple-audio-card,convert-rate = <48000>;
simple-audio-card,prefix = "ak4642";
simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
"DAI0 Capture", "ak4642 Capture";
sndcpu: simple-audio-card,cpu {
sound-dai = <&rcar_sound>;
};
sndcodec: simple-audio-card,codec {
sound-dai = <&ak4643>;
system-clock-frequency = <11289600>;
};
};
#--------------------
# 2 CPU 1 Codec (Mixing)
#--------------------
- |
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "rsnd-ak4643";
simple-audio-card,format = "left_j";
simple-audio-card,bitclock-master = <&dpcmcpu>;
simple-audio-card,frame-master = <&dpcmcpu>;
simple-audio-card,convert-rate = <48000>;
simple-audio-card,convert-channels = <2>;
simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
"ak4642 Playback", "DAI1 Playback";
dpcmcpu: simple-audio-card,cpu@0 {
sound-dai = <&rcar_sound 0>;
};
simple-audio-card,cpu@1 {
sound-dai = <&rcar_sound 1>;
};
simple-audio-card,codec {
prefix = "ak4642";
sound-dai = <&ak4643>;
clocks = <&audio_clock>;
};
};
#--------------------
# Multi DAI links with DPCM:
#
# CPU0 ------ ak4613
# CPU1 ------ PCM3168A-p /* DPCM 1ch/2ch */
# CPU2 --/ /* DPCM 3ch/4ch */
# CPU3 --/ /* DPCM 5ch/6ch */
# CPU4 --/ /* DPCM 7ch/8ch */
# CPU5 ------ PCM3168A-c
#--------------------
- |
sound {
compatible = "simple-audio-card";
simple-audio-card,routing =
"pcm3168a Playback", "DAI1 Playback",
"pcm3168a Playback", "DAI2 Playback",
"pcm3168a Playback", "DAI3 Playback",
"pcm3168a Playback", "DAI4 Playback";
simple-audio-card,dai-link@0 {
format = "left_j";
bitclock-master = <&sndcpu0>;
frame-master = <&sndcpu0>;
sndcpu0: cpu {
sound-dai = <&rcar_sound 0>;
};
codec {
sound-dai = <&ak4613>;
};
};
simple-audio-card,dai-link@1 {
format = "i2s";
bitclock-master = <&sndcpu1>;
frame-master = <&sndcpu1>;
convert-channels = <8>; /* TDM Split */
sndcpu1: cpu@0 {
sound-dai = <&rcar_sound 1>;
};
cpu@1 {
sound-dai = <&rcar_sound 2>;
};
cpu@2 {
sound-dai = <&rcar_sound 3>;
};
cpu@3 {
sound-dai = <&rcar_sound 4>;
};
codec {
mclk-fs = <512>;
prefix = "pcm3168a";
dai-tdm-slot-num = <8>;
sound-dai = <&pcm3168a 0>;
};
};
simple-audio-card,dai-link@2 {
format = "i2s";
bitclock-master = <&sndcpu2>;
frame-master = <&sndcpu2>;
sndcpu2: cpu {
sound-dai = <&rcar_sound 5>;
};
codec {
mclk-fs = <512>;
prefix = "pcm3168a";
sound-dai = <&pcm3168a 1>;
};
};
};

View File

@ -63,6 +63,55 @@ properties:
- $ref: /schemas/types.yaml#/definitions/uint32
- enum: [0, 1, 2]
ti,pdm-edge-select:
description: |
Defines the PDMCLK sampling edge configuration for the PDM inputs. This
array is defined as <PDMIN1 PDMIN2 PDMIN3 PDMIN4>.
0 - (default) Odd channel is latched on the negative edge and even
channel is latched on the the positive edge.
1 - Odd channel is latched on the positive edge and even channel is
latched on the the negative edge.
PDMIN1 - PDMCLK latching edge used for channel 1 and 2 data
PDMIN2 - PDMCLK latching edge used for channel 3 and 4 data
PDMIN3 - PDMCLK latching edge used for channel 5 and 6 data
PDMIN4 - PDMCLK latching edge used for channel 7 and 8 data
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32-array
- minItems: 1
maxItems: 4
items:
maximum: 1
default: [0, 0, 0, 0]
ti,gpi-config:
description: |
Defines the configuration for the general purpose input pins (GPI).
The array is defined as <GPI1 GPI2 GPI3 GPI4>.
0 - (default) disabled
1 - GPIX is configured as a general-purpose input (GPI)
2 - GPIX is configured as a master clock input (MCLK)
3 - GPIX is configured as an ASI input for daisy-chain (SDIN)
4 - GPIX is configured as a PDM data input for channel 1 and channel
(PDMDIN1)
5 - GPIX is configured as a PDM data input for channel 3 and channel
(PDMDIN2)
6 - GPIX is configured as a PDM data input for channel 5 and channel
(PDMDIN3)
7 - GPIX is configured as a PDM data input for channel 7 and channel
(PDMDIN4)
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32-array
- minItems: 1
maxItems: 4
items:
maximum: 7
default: [0, 0, 0, 0]
required:
- compatible
- reg
@ -77,6 +126,8 @@ examples:
compatible = "ti,tlv320adc5140";
reg = <0x4c>;
ti,mic-bias-source = <6>;
ti,pdm-edge-select = <0 1 0 1>;
ti,gpi-config = <4 5 6 7>;
reset-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
};
};

View File

@ -14,9 +14,15 @@ Required properties:
- #gpio-cells : Must be 2. The first cell is the pin number and the
second cell is used to specify optional parameters (currently unused).
- AVDD2-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply,
SPKVDD1-supply, SPKVDD2-supply : power supplies for the device, as covered
in Documentation/devicetree/bindings/regulator/regulator.txt
- power supplies for the device, as covered in
Documentation/devicetree/bindings/regulator/regulator.txt, depending
on compatible:
- for wlf,wm1811 and wlf,wm8958:
AVDD1-supply, AVDD2-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply,
DCVDD-supply, CPVDD-supply, SPKVDD1-supply, SPKVDD2-supply
- for wlf,wm8994:
AVDD1-supply, AVDD2-supply, DBVDD-supply, DCVDD-supply, CPVDD-supply,
SPKVDD1-supply, SPKVDD2-supply
Optional properties:
@ -73,11 +79,11 @@ wm8994: codec@1a {
lineout1-se;
AVDD1-supply = <&regulator>;
AVDD2-supply = <&regulator>;
CPVDD-supply = <&regulator>;
DBVDD1-supply = <&regulator>;
DBVDD2-supply = <&regulator>;
DBVDD3-supply = <&regulator>;
DBVDD-supply = <&regulator>;
DCVDD-supply = <&regulator>;
SPKVDD1-supply = <&regulator>;
SPKVDD2-supply = <&regulator>;
};

View File

@ -0,0 +1,69 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/zl38060.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ZL38060 Connected Home Audio Processor from Microsemi.
description: |
The ZL38060 is a "Connected Home Audio Processor" from Microsemi,
which consists of a Digital Signal Processor (DSP), several Digital
Audio Interfaces (DAIs), analog outputs, and a block of 14 GPIOs.
maintainers:
- Jaroslav Kysela <perex@perex.cz>
- Takashi Iwai <tiwai@suse.com>
properties:
compatible:
const: mscc,zl38060
reg:
description:
SPI device address.
maxItems: 1
spi-max-frequency:
maximum: 24000000
reset-gpios:
description:
A GPIO line handling reset of the chip. As the line is active low,
it should be marked GPIO_ACTIVE_LOW (see ../gpio/gpio.txt)
maxItems: 1
'#gpio-cells':
const: 2
gpio-controller: true
'#sound-dai-cells':
const: 0
required:
- compatible
- reg
- '#gpio-cells'
- gpio-controller
- '#sound-dai-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi0 {
#address-cells = <1>;
#size-cells = <0>;
codec: zl38060@0 {
gpio-controller;
#gpio-cells = <2>;
#sound-dai-cells = <0>;
compatible = "mscc,zl38060";
reg = <0>;
spi-max-frequency = <12000000>;
reset-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
};
};

View File

@ -669,11 +669,11 @@ static int sdw_stream_setup(struct snd_pcm_substream *substream,
/* Set stream pointer on all CODEC DAIs */
for (i = 0; i < rtd->num_codecs; i++) {
ret = snd_soc_dai_set_sdw_stream(rtd->codec_dais[i], sdw_stream,
ret = snd_soc_dai_set_sdw_stream(asoc_rtd_to_codec(rtd, i), sdw_stream,
substream->stream);
if (ret < 0) {
dev_err(dai->dev, "failed to set stream pointer on codec dai %s",
rtd->codec_dais[i]->name);
asoc_rtd_to_codec(rtd, i)->name);
goto release_stream;
}
}

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0
/* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (C) 2013-15, Intel Corporation. All rights reserved.
*/

69
include/sound/soc-card.h Normal file
View File

@ -0,0 +1,69 @@
/* SPDX-License-Identifier: GPL-2.0
*
* soc-card.h
*
* Copyright (C) 2019 Renesas Electronics Corp.
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
*/
#ifndef __SOC_CARD_H
#define __SOC_CARD_H
enum snd_soc_card_subclass {
SND_SOC_CARD_CLASS_INIT = 0,
SND_SOC_CARD_CLASS_RUNTIME = 1,
};
struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
const char *name);
int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
struct snd_soc_jack *jack,
struct snd_soc_jack_pin *pins, unsigned int num_pins);
int snd_soc_card_suspend_pre(struct snd_soc_card *card);
int snd_soc_card_suspend_post(struct snd_soc_card *card);
int snd_soc_card_resume_pre(struct snd_soc_card *card);
int snd_soc_card_resume_post(struct snd_soc_card *card);
int snd_soc_card_probe(struct snd_soc_card *card);
int snd_soc_card_late_probe(struct snd_soc_card *card);
int snd_soc_card_remove(struct snd_soc_card *card);
int snd_soc_card_set_bias_level(struct snd_soc_card *card,
struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level);
int snd_soc_card_set_bias_level_post(struct snd_soc_card *card,
struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level);
int snd_soc_card_add_dai_link(struct snd_soc_card *card,
struct snd_soc_dai_link *dai_link);
void snd_soc_card_remove_dai_link(struct snd_soc_card *card,
struct snd_soc_dai_link *dai_link);
/* device driver data */
static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
void *data)
{
card->drvdata = data;
}
static inline void *snd_soc_card_get_drvdata(struct snd_soc_card *card)
{
return card->drvdata;
}
static inline
struct snd_soc_dai *snd_soc_card_get_codec_dai(struct snd_soc_card *card,
const char *dai_name)
{
struct snd_soc_pcm_runtime *rtd;
for_each_card_rtds(card, rtd) {
if (!strcmp(asoc_rtd_to_codec(rtd, 0)->name, dai_name))
return asoc_rtd_to_codec(rtd, 0);
}
return NULL;
}
#endif /* __SOC_CARD_H */

View File

@ -25,6 +25,44 @@
order++)
/* component interface */
struct snd_compress_ops {
int (*open)(struct snd_soc_component *component,
struct snd_compr_stream *stream);
int (*free)(struct snd_soc_component *component,
struct snd_compr_stream *stream);
int (*set_params)(struct snd_soc_component *component,
struct snd_compr_stream *stream,
struct snd_compr_params *params);
int (*get_params)(struct snd_soc_component *component,
struct snd_compr_stream *stream,
struct snd_codec *params);
int (*set_metadata)(struct snd_soc_component *component,
struct snd_compr_stream *stream,
struct snd_compr_metadata *metadata);
int (*get_metadata)(struct snd_soc_component *component,
struct snd_compr_stream *stream,
struct snd_compr_metadata *metadata);
int (*trigger)(struct snd_soc_component *component,
struct snd_compr_stream *stream, int cmd);
int (*pointer)(struct snd_soc_component *component,
struct snd_compr_stream *stream,
struct snd_compr_tstamp *tstamp);
int (*copy)(struct snd_soc_component *component,
struct snd_compr_stream *stream, char __user *buf,
size_t count);
int (*mmap)(struct snd_soc_component *component,
struct snd_compr_stream *stream,
struct vm_area_struct *vma);
int (*ack)(struct snd_soc_component *component,
struct snd_compr_stream *stream, size_t bytes);
int (*get_caps)(struct snd_soc_component *component,
struct snd_compr_stream *stream,
struct snd_compr_caps *caps);
int (*get_codec_caps)(struct snd_soc_component *component,
struct snd_compr_stream *stream,
struct snd_compr_codec_caps *codec);
};
struct snd_soc_component_driver {
const char *name;
@ -108,7 +146,7 @@ struct snd_soc_component_driver {
struct snd_pcm_substream *substream,
struct vm_area_struct *vma);
const struct snd_compr_ops *compr_ops;
const struct snd_compress_ops *compress_ops;
/* probe ordering - for components with runtime dependencies */
int probe_order;
@ -351,10 +389,10 @@ static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
return dev_get_drvdata(c->dev);
}
static inline bool snd_soc_component_is_active(
struct snd_soc_component *component)
static inline unsigned int
snd_soc_component_active(struct snd_soc_component *component)
{
return component->active != 0;
return component->active;
}
/* component pin */

View File

@ -154,21 +154,59 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
int snd_soc_dai_prepare(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
int snd_soc_dai_trigger(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream, int cmd);
int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream, int cmd);
snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
void snd_soc_dai_suspend(struct snd_soc_dai *dai);
void snd_soc_dai_resume(struct snd_soc_dai *dai);
int snd_soc_dai_probe(struct snd_soc_dai *dai);
int snd_soc_dai_remove(struct snd_soc_dai *dai);
int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
struct snd_soc_pcm_runtime *rtd, int num);
bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream);
void snd_soc_dai_action(struct snd_soc_dai *dai,
int stream, int action);
static inline void snd_soc_dai_activate(struct snd_soc_dai *dai,
int stream)
{
snd_soc_dai_action(dai, stream, 1);
}
static inline void snd_soc_dai_deactivate(struct snd_soc_dai *dai,
int stream)
{
snd_soc_dai_action(dai, stream, -1);
}
int snd_soc_dai_active(struct snd_soc_dai *dai);
int snd_soc_pcm_dai_probe(struct snd_soc_pcm_runtime *rtd, int order);
int snd_soc_pcm_dai_remove(struct snd_soc_pcm_runtime *rtd, int order);
int snd_soc_pcm_dai_new(struct snd_soc_pcm_runtime *rtd);
int snd_soc_pcm_dai_prepare(struct snd_pcm_substream *substream);
int snd_soc_pcm_dai_trigger(struct snd_pcm_substream *substream, int cmd);
int snd_soc_pcm_dai_bespoke_trigger(struct snd_pcm_substream *substream,
int cmd);
int snd_soc_dai_compr_startup(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream);
void snd_soc_dai_compr_shutdown(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream);
int snd_soc_dai_compr_trigger(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream, int cmd);
int snd_soc_dai_compr_set_params(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_params *params);
int snd_soc_dai_compr_get_params(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_codec *params);
int snd_soc_dai_compr_ack(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
size_t bytes);
int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_tstamp *tstamp);
int snd_soc_dai_compr_set_metadata(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_metadata *metadata);
int snd_soc_dai_compr_get_metadata(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_metadata *metadata);
struct snd_soc_dai_ops {
/*
@ -326,8 +364,6 @@ struct snd_soc_dai {
/* DAI runtime info */
unsigned int stream_active[SNDRV_PCM_STREAM_LAST + 1]; /* usage count */
unsigned int active;
struct snd_soc_dapm_widget *playback_widget;
struct snd_soc_dapm_widget *capture_widget;
@ -443,4 +479,10 @@ static inline void *snd_soc_dai_get_sdw_stream(struct snd_soc_dai *dai,
return ERR_PTR(-ENOTSUPP);
}
static inline unsigned int
snd_soc_dai_stream_active(struct snd_soc_dai *dai, int stream)
{
return dai->stream_active[stream];
}
#endif

View File

@ -689,7 +689,7 @@ struct snd_soc_dapm_context {
/* A list of widgets associated with an object, typically a snd_kcontrol */
struct snd_soc_dapm_widget_list {
int num_widgets;
struct snd_soc_dapm_widget *widgets[0];
struct snd_soc_dapm_widget *widgets[];
};
#define for_each_dapm_widgets(list, i, widget) \

27
include/sound/soc-link.h Normal file
View File

@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0
*
* soc-link.h
*
* Copyright (C) 2019 Renesas Electronics Corp.
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
*/
#ifndef __SOC_LINK_H
#define __SOC_LINK_H
int snd_soc_link_init(struct snd_soc_pcm_runtime *rtd);
int snd_soc_link_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params);
int snd_soc_link_startup(struct snd_pcm_substream *substream);
void snd_soc_link_shutdown(struct snd_pcm_substream *substream);
int snd_soc_link_prepare(struct snd_pcm_substream *substream);
int snd_soc_link_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params);
void snd_soc_link_hw_free(struct snd_pcm_substream *substream);
int snd_soc_link_trigger(struct snd_pcm_substream *substream, int cmd);
int snd_soc_link_compr_startup(struct snd_compr_stream *cstream);
void snd_soc_link_compr_shutdown(struct snd_compr_stream *cstream);
int snd_soc_link_compr_set_params(struct snd_compr_stream *cstream);
#endif /* __SOC_LINK_H */

View File

@ -414,11 +414,6 @@ enum snd_soc_pcm_subclass {
SND_SOC_PCM_CLASS_BE = 1,
};
enum snd_soc_card_subclass {
SND_SOC_CARD_CLASS_INIT = 0,
SND_SOC_CARD_CLASS_RUNTIME = 1,
};
int snd_soc_register_card(struct snd_soc_card *card);
int snd_soc_unregister_card(struct snd_soc_card *card);
int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card);
@ -468,8 +463,19 @@ struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card,
struct snd_soc_dai_link *dai_link);
bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd);
void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream);
void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream);
void snd_soc_runtime_action(struct snd_soc_pcm_runtime *rtd,
int stream, int action);
static inline void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd,
int stream)
{
snd_soc_runtime_action(rtd, stream, 1);
}
static inline void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd,
int stream)
{
snd_soc_runtime_action(rtd, stream, -1);
}
int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hardware *hw, int stream);
@ -498,10 +504,6 @@ int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
const struct snd_pcm_hardware *hw);
/* Jack reporting */
int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins,
unsigned int num_pins);
void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask);
int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
struct snd_soc_jack_pin *pins);
@ -571,8 +573,6 @@ static inline int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
void *data, const char *long_name,
const char *prefix);
struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
const char *name);
int snd_soc_add_component_controls(struct snd_soc_component *component,
const struct snd_kcontrol_new *controls, unsigned int num_controls);
int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
@ -806,7 +806,7 @@ struct snd_soc_dai_link {
const struct snd_soc_compr_ops *compr_ops;
/* Mark this pcm with non atomic ops */
bool nonatomic;
unsigned int nonatomic:1;
/* For unidirectional dai links */
unsigned int playback_only:1;
@ -1002,9 +1002,6 @@ struct snd_soc_card {
spinlock_t dpcm_lock;
bool instantiated;
bool topology_shortname_created;
int (*probe)(struct snd_soc_card *card);
int (*late_probe)(struct snd_soc_card *card);
int (*remove)(struct snd_soc_card *card);
@ -1065,8 +1062,6 @@ struct snd_soc_card {
int num_of_dapm_widgets;
const struct snd_soc_dapm_route *of_dapm_routes;
int num_of_dapm_routes;
bool fully_routed;
bool disable_route_checks;
/* lists of probed devices belonging to this card */
struct list_head component_dev_list;
@ -1093,6 +1088,13 @@ struct snd_soc_card {
#endif
u32 pop_time;
/* bit field */
unsigned int instantiated:1;
unsigned int topology_shortname_created:1;
unsigned int fully_routed:1;
unsigned int disable_route_checks:1;
unsigned int probed:1;
void *drvdata;
};
#define for_each_card_prelinks(card, i, link) \
@ -1143,14 +1145,16 @@ struct snd_soc_pcm_runtime {
/* runtime devices */
struct snd_pcm *pcm;
struct snd_compr *compr;
struct snd_soc_dai *codec_dai;
struct snd_soc_dai *cpu_dai;
/*
* dais = cpu_dai + codec_dai
* see
* soc_new_pcm_runtime()
* asoc_rtd_to_cpu()
* asoc_rtd_to_codec()
*/
struct snd_soc_dai **dais;
struct snd_soc_dai **codec_dais;
unsigned int num_codecs;
struct snd_soc_dai **cpu_dais;
unsigned int num_cpus;
struct snd_soc_dapm_widget *playback_widget;
@ -1170,28 +1174,28 @@ struct snd_soc_pcm_runtime {
unsigned int fe_compr:1; /* for Dynamic PCM */
int num_components;
struct snd_soc_component *components[0]; /* CPU/Codec/Platform */
struct snd_soc_component *components[]; /* CPU/Codec/Platform */
};
/* see soc_new_pcm_runtime() */
#define asoc_rtd_to_cpu(rtd, n) (rtd)->dais[n]
#define asoc_rtd_to_codec(rtd, n) (rtd)->dais[n + (rtd)->num_cpus]
#define for_each_rtd_components(rtd, i, component) \
for ((i) = 0; \
for ((i) = 0, component = NULL; \
((i) < rtd->num_components) && ((component) = rtd->components[i]);\
(i)++)
#define for_each_rtd_cpu_dais(rtd, i, dai) \
for ((i) = 0; \
((i) < rtd->num_cpus) && ((dai) = rtd->cpu_dais[i]); \
((i) < rtd->num_cpus) && ((dai) = asoc_rtd_to_cpu(rtd, i)); \
(i)++)
#define for_each_rtd_cpu_dais_rollback(rtd, i, dai) \
for (; (--(i) >= 0) && ((dai) = rtd->cpu_dais[i]);)
for (; (--(i) >= 0) && ((dai) = asoc_rtd_to_cpu(rtd, i));)
#define for_each_rtd_codec_dais(rtd, i, dai) \
for ((i) = 0; \
((i) < rtd->num_codecs) && ((dai) = rtd->codec_dais[i]); \
((i) < rtd->num_codecs) && ((dai) = asoc_rtd_to_codec(rtd, i)); \
(i)++)
#define for_each_rtd_codec_dais_rollback(rtd, i, dai) \
for (; (--(i) >= 0) && ((dai) = rtd->codec_dais[i]);)
for (; (--(i) >= 0) && ((dai) = asoc_rtd_to_codec(rtd, i));)
#define for_each_rtd_dais(rtd, i, dai) \
for ((i) = 0; \
((i) < (rtd)->num_cpus + (rtd)->num_codecs) && \
@ -1252,29 +1256,16 @@ struct soc_enum {
#endif
};
/* device driver data */
static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
void *data)
{
card->drvdata = data;
}
static inline void *snd_soc_card_get_drvdata(struct snd_soc_card *card)
{
return card->drvdata;
}
static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
{
if (mc->reg == mc->rreg && mc->shift == mc->rshift)
return 0;
return false;
/*
* mc->reg == mc->rreg && mc->shift != mc->rshift, or
* mc->reg != mc->rreg means that the control is
* stereo (bits in one register or in two registers)
*/
return 1;
return true;
}
static inline unsigned int snd_soc_enum_val_to_item(struct soc_enum *e,
@ -1377,20 +1368,6 @@ struct snd_soc_dai *snd_soc_find_dai(
#include <sound/soc-dai.h>
static inline
struct snd_soc_dai *snd_soc_card_get_codec_dai(struct snd_soc_card *card,
const char *dai_name)
{
struct snd_soc_pcm_runtime *rtd;
list_for_each_entry(rtd, &card->rtd_list, list) {
if (!strcmp(rtd->codec_dai->name, dai_name))
return rtd->codec_dai;
}
return NULL;
}
static inline
int snd_soc_fixup_dai_links_platform_name(struct snd_soc_card *card,
const char *platform_name)
@ -1436,5 +1413,6 @@ static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm)
}
#include <sound/soc-component.h>
#include <sound/soc-card.h>
#endif

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@ -27,6 +27,9 @@ struct snd_sof_pdata {
struct device *dev;
/* indicate how many first bytes shouldn't be loaded into DSP memory. */
size_t fw_offset;
/*
* notification callback used if the hardware initialization
* can take time or is handled in a workqueue. This callback

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* Copyright 2019 NXP
*

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@ -49,6 +49,9 @@
/* bclk idle */
#define SOF_DAI_INTEL_SSP_CLKCTRL_BCLK_IDLE_HIGH BIT(5)
/* DMIC max. four controllers for eight microphone channels */
#define SOF_DAI_INTEL_DMIC_NUM_CTRL 4
/* SSP Configuration Request - SOF_IPC_DAI_SSP_CONFIG */
struct sof_ipc_dai_ssp_params {
struct sof_ipc_hdr hdr;
@ -85,15 +88,19 @@ struct sof_ipc_dai_ssp_params {
struct sof_ipc_dai_hda_params {
struct sof_ipc_hdr hdr;
uint32_t link_dma_ch;
uint32_t rate;
uint32_t channels;
} __packed;
/* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */
struct sof_ipc_dai_alh_params {
struct sof_ipc_hdr hdr;
uint32_t stream_id;
uint32_t rate;
uint32_t channels;
/* reserved for future use */
uint32_t reserved[15];
uint32_t reserved[13];
} __packed;
/* DMIC Configuration Request - SOF_IPC_DAI_DMIC_CONFIG */
@ -135,7 +142,7 @@ struct sof_ipc_dai_dmic_pdm_ctrl {
* version number used in configuration data is checked vs. version used by
* device driver src/drivers/dmic.c need to match. It is incremented from
* initial value 1 if updates done for the to driver would alter the operation
* of the microhone.
* of the microphone.
*
* Note: The microphone clock (pdmclk_min, pdmclk_max, duty_min, duty_max)
* parameters need to be set as defined in microphone data sheet. E.g. clock
@ -170,12 +177,13 @@ struct sof_ipc_dai_dmic_params {
uint32_t fifo_fs; /**< FIFO sample rate in Hz (8000..96000) */
uint32_t reserved_1; /**< Reserved */
uint16_t fifo_bits; /**< FIFO word length (16 or 32) */
uint16_t reserved_2; /**< Reserved */
uint16_t fifo_bits_b; /**< Deprecated since firmware ABI 3.0.1 */
uint16_t duty_min; /**< Min. mic clock duty cycle in % (20..80) */
uint16_t duty_max; /**< Max. mic clock duty cycle in % (min..80) */
uint32_t num_pdm_active; /**< Number of active pdm controllers */
uint32_t num_pdm_active; /**< Number of active pdm controllers. */
/**< Range is 1..SOF_DAI_INTEL_DMIC_NUM_CTRL */
uint32_t wake_up_time; /**< Time from clock start to data (us) */
uint32_t min_clock_on_time; /**< Min. time that clk is kept on (us) */
@ -184,8 +192,8 @@ struct sof_ipc_dai_dmic_params {
/* reserved for future use */
uint32_t reserved[5];
/**< variable number of pdm controller config */
struct sof_ipc_dai_dmic_pdm_ctrl pdm[0];
/**< PDM controllers configuration */
struct sof_ipc_dai_dmic_pdm_ctrl pdm[SOF_DAI_INTEL_DMIC_NUM_CTRL];
} __packed;
#endif

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.

View File

@ -0,0 +1,95 @@
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* Copyright(c) 2020 Intel Corporation. All rights reserved.
*/
/*
* Extended manifest is a place to store metadata about firmware, known during
* compilation time - for example firmware version or used compiler.
* Given information are read on host side before firmware startup.
* This part of output binary is not signed.
*/
#ifndef __SOF_FIRMWARE_EXT_MANIFEST_H__
#define __SOF_FIRMWARE_EXT_MANIFEST_H__
#include <linux/bits.h>
#include <linux/compiler.h>
#include <linux/types.h>
#include <sound/sof/info.h>
/* In ASCII `XMan` */
#define SOF_EXT_MAN_MAGIC_NUMBER 0x6e614d58
/* Build u32 number in format MMmmmppp */
#define SOF_EXT_MAN_BUILD_VERSION(MAJOR, MINOR, PATH) ((uint32_t)( \
((MAJOR) << 24) | \
((MINOR) << 12) | \
(PATH)))
/* check extended manifest version consistency */
#define SOF_EXT_MAN_VERSION_INCOMPATIBLE(host_ver, cli_ver) ( \
((host_ver) & GENMASK(31, 24)) != \
((cli_ver) & GENMASK(31, 24)))
/* used extended manifest header version */
#define SOF_EXT_MAN_VERSION SOF_EXT_MAN_BUILD_VERSION(1, 0, 0)
/* extended manifest header, deleting any field breaks backward compatibility */
struct sof_ext_man_header {
uint32_t magic; /*< identification number, */
/*< EXT_MAN_MAGIC_NUMBER */
uint32_t full_size; /*< [bytes] full size of ext_man, */
/*< (header + content + padding) */
uint32_t header_size; /*< [bytes] makes header extensionable, */
/*< after append new field to ext_man header */
/*< then backward compatible won't be lost */
uint32_t header_version; /*< value of EXT_MAN_VERSION */
/*< not related with following content */
/* just after this header should be list of ext_man_elem_* elements */
} __packed;
/* Now define extended manifest elements */
/* Extended manifest elements types */
enum sof_ext_man_elem_type {
SOF_EXT_MAN_ELEM_FW_VERSION = 0,
SOF_EXT_MAN_ELEM_WINDOW = SOF_IPC_EXT_WINDOW,
SOF_EXT_MAN_ELEM_CC_VERSION = SOF_IPC_EXT_CC_INFO,
};
/* extended manifest element header */
struct sof_ext_man_elem_header {
uint32_t type; /*< SOF_EXT_MAN_ELEM_ */
uint32_t size; /*< in bytes, including header size */
/* just after this header should be type dependent content */
} __packed;
/* FW version */
struct sof_ext_man_fw_version {
struct sof_ext_man_elem_header hdr;
/* use sof_ipc struct because of code re-use */
struct sof_ipc_fw_version version;
uint32_t flags;
} __packed;
/* extended data memory windows for IPC, trace and debug */
struct sof_ext_man_window {
struct sof_ext_man_elem_header hdr;
/* use sof_ipc struct because of code re-use */
struct sof_ipc_window ipc_window;
} __packed;
/* Used C compiler description */
struct sof_ext_man_cc_version {
struct sof_ext_man_elem_header hdr;
/* use sof_ipc struct because of code re-use */
struct sof_ipc_cc_version cc_version;
} __packed;
#endif /* __SOF_FIRMWARE_EXT_MANIFEST_H__ */

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@ -31,6 +31,8 @@ enum sof_ipc_ext_data {
SOF_IPC_EXT_UNUSED = 0,
SOF_IPC_EXT_WINDOW = 1,
SOF_IPC_EXT_CC_INFO = 2,
SOF_IPC_EXT_PROBE_INFO = 3,
SOF_IPC_EXT_USER_ABI_INFO = 4,
};
/* FW version - SOF_IPC_GLB_VERSION */
@ -109,9 +111,27 @@ struct sof_ipc_cc_version {
/* reserved for future use */
uint32_t reserved[4];
char name[16]; /* null terminated compiler name */
char optim[4]; /* null terminated compiler -O flag value */
char desc[]; /* null terminated compiler description */
uint8_t name[16]; /* null terminated compiler name */
uint8_t optim[4]; /* null terminated compiler -O flag value */
uint8_t desc[32]; /* null terminated compiler description */
} __packed;
/* extended data: Probe setup */
struct sof_ipc_probe_support {
struct sof_ipc_ext_data_hdr ext_hdr;
uint32_t probe_points_max;
uint32_t injection_dmas_max;
/* reserved for future use */
uint32_t reserved[2];
} __packed;
/* extended data: user abi version(s) */
struct sof_ipc_user_abi_version {
struct sof_ipc_ext_data_hdr ext_hdr;
uint32_t abi_dbg_version;
} __packed;
#endif

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@ -37,6 +37,8 @@ enum sof_comp_type {
SOF_COMP_SELECTOR, /**< channel selector component */
SOF_COMP_DEMUX,
SOF_COMP_ASRC, /**< Asynchronous sample rate converter */
SOF_COMP_DCBLOCK,
SOF_COMP_SMART_AMP, /**< smart amplifier component */
/* keep FILEREAD/FILEWRITE as the last ones */
SOF_COMP_FILEREAD = 10000, /**< host test based file IO */
SOF_COMP_FILEWRITE = 10001, /**< host test based file IO */
@ -75,11 +77,23 @@ struct sof_ipc_comp {
#define SOF_MEM_CAPS_CACHE (1 << 6) /**< cacheable */
#define SOF_MEM_CAPS_EXEC (1 << 7) /**< executable */
/*
* overrun will cause ring buffer overwrite, instead of XRUN.
*/
#define SOF_BUF_OVERRUN_PERMITTED BIT(0)
/*
* underrun will cause readback of 0s, instead of XRUN.
*/
#define SOF_BUF_UNDERRUN_PERMITTED BIT(1)
/* create new component buffer - SOF_IPC_TPLG_BUFFER_NEW */
struct sof_ipc_buffer {
struct sof_ipc_comp comp;
uint32_t size; /**< buffer size in bytes */
uint32_t caps; /**< SOF_MEM_CAPS_ */
uint32_t flags; /**< SOF_BUF_ flags defined above */
uint32_t reserved; /**< reserved for future use */
} __packed;
/* generic component config data - must always be after struct sof_ipc_comp */
@ -206,6 +220,8 @@ enum sof_ipc_process_type {
SOF_PROCESS_CHAN_SELECTOR, /**< Channel Selector */
SOF_PROCESS_MUX,
SOF_PROCESS_DEMUX,
SOF_PROCESS_DCBLOCK,
SOF_PROCESS_SMART_AMP, /**< Smart Amplifier */
};
/* generic "effect", "codec" or proprietary processing component */
@ -218,7 +234,7 @@ struct sof_ipc_comp_process {
/* reserved for future use */
uint32_t reserved[7];
unsigned char data[0];
uint8_t data[0];
} __packed;
/* frees components, buffers and pipelines

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@ -72,7 +72,7 @@ struct sof_ipc_dma_trace_posn {
struct sof_ipc_panic_info {
struct sof_ipc_hdr hdr;
uint32_t code; /* SOF_IPC_PANIC_ */
char filename[SOF_TRACE_FILENAME_SIZE];
uint8_t filename[SOF_TRACE_FILENAME_SIZE];
uint32_t linenum;
} __packed;

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.

View File

@ -18,6 +18,8 @@
*/
#define SKL_CONTROL_TYPE_BYTE_TLV 0x100
#define SKL_CONTROL_TYPE_MIC_SELECT 0x102
#define SKL_CONTROL_TYPE_MULTI_IO_SELECT 0x103
#define SKL_CONTROL_TYPE_MULTI_IO_SELECT_DMIC 0x104
#define HDA_SST_CFG_MAX 900 /* size of copier cfg*/
#define MAX_IN_QUEUE 8

View File

@ -26,7 +26,7 @@
/* SOF ABI version major, minor and patch numbers */
#define SOF_ABI_MAJOR 3
#define SOF_ABI_MINOR 13
#define SOF_ABI_MINOR 16
#define SOF_ABI_PATCH 0
/* SOF ABI version number. Format within 32bit word is MMmmmppp */

View File

@ -126,4 +126,12 @@
#define SOF_TKN_MUTE_LED_USE 1300
#define SOF_TKN_MUTE_LED_DIRECTION 1301
/* ALH */
#define SOF_TKN_INTEL_ALH_RATE 1400
#define SOF_TKN_INTEL_ALH_CH 1401
/* HDA */
#define SOF_TKN_INTEL_HDA_RATE 1500
#define SOF_TKN_INTEL_HDA_CH 1501
#endif

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0
// SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2015-2019 Intel Corporation
#include <linux/acpi.h>

View File

@ -4169,6 +4169,7 @@ HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi),
HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI", patch_i915_icl_hdmi),
HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi),
HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi),
HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI", patch_i915_icl_hdmi),
HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi),
HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),

View File

@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-utils.o soc-dai.o soc-component.o
snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o
snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o soc-link.o soc-card.o
snd-soc-core-$(CONFIG_SND_SOC_COMPRESS) += soc-compress.o
ifneq ($(CONFIG_SND_SOC_TOPOLOGY),)

View File

@ -29,10 +29,23 @@ config SND_SOC_AMD_ACP3x
config SND_SOC_AMD_RV_RT5682_MACH
tristate "AMD RV support for RT5682"
select SND_SOC_RT5682
select SND_SOC_RT5682_I2C
select SND_SOC_MAX98357A
select SND_SOC_CROS_EC_CODEC
select I2C_CROS_EC_TUNNEL
depends on SND_SOC_AMD_ACP3x && I2C && CROS_EC
help
This option enables machine driver for RT5682 and MAX9835.
config SND_SOC_AMD_RENOIR
tristate "AMD Audio Coprocessor - Renoir support"
depends on X86 && PCI
help
This option enables ACP support for Renoir platform
config SND_SOC_AMD_RENOIR_MACH
tristate "AMD Renoir support for DMIC"
select SND_SOC_DMIC
depends on SND_SOC_AMD_RENOIR
help
This option enables machine driver for DMIC

View File

@ -9,3 +9,4 @@ obj-$(CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH) += snd-soc-acp-da7219mx98357-mac
obj-$(CONFIG_SND_SOC_AMD_CZ_RT5645_MACH) += snd-soc-acp-rt5645-mach.o
obj-$(CONFIG_SND_SOC_AMD_ACP3x) += raven/
obj-$(CONFIG_SND_SOC_AMD_RV_RT5682_MACH) += snd-soc-acp-rt5682-mach.o
obj-$(CONFIG_SND_SOC_AMD_RENOIR) += renoir/

View File

@ -15,7 +15,7 @@
#include "acp3x.h"
#define DRV_NAME "acp3x-i2s"
#define DRV_NAME "acp3x_i2s_playcap"
static int acp3x_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt)
@ -269,7 +269,7 @@ static struct snd_soc_dai_ops acp3x_i2s_dai_ops = {
};
static const struct snd_soc_component_driver acp3x_dai_component = {
.name = "acp3x-i2s",
.name = DRV_NAME,
};
static struct snd_soc_dai_driver acp3x_i2s_dai = {
@ -348,4 +348,4 @@ module_platform_driver(acp3x_dai_driver);
MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com");
MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);
MODULE_ALIAS("platform:"DRV_NAME);

View File

@ -15,7 +15,7 @@
#include "acp3x.h"
#define DRV_NAME "acp3x-i2s-audio"
#define DRV_NAME "acp3x_rv_i2s_dma"
static const struct snd_pcm_hardware acp3x_pcm_hardware_playback = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
@ -303,7 +303,6 @@ static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_soc_component *component,
{
struct snd_soc_pcm_runtime *prtd;
struct snd_soc_card *card;
struct acp3x_platform_info *pinfo;
struct i2s_stream_instance *rtd;
u32 pos;
u32 buffersize;
@ -312,13 +311,6 @@ static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_soc_component *component,
prtd = substream->private_data;
card = prtd->card;
rtd = substream->runtime->private_data;
pinfo = snd_soc_card_get_drvdata(card);
if (pinfo) {
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
rtd->i2s_instance = pinfo->play_i2s_instance;
else
rtd->i2s_instance = pinfo->cap_i2s_instance;
}
buffersize = frames_to_bytes(substream->runtime,
substream->runtime->buffer_size);
@ -542,4 +534,4 @@ MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com");
MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);
MODULE_ALIAS("platform:"DRV_NAME);

View File

@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+
# Renoir platform Support
snd-rn-pci-acp3x-objs := rn-pci-acp3x.o
snd-acp3x-pdm-dma-objs := acp3x-pdm-dma.o
obj-$(CONFIG_SND_SOC_AMD_RENOIR) += snd-rn-pci-acp3x.o
obj-$(CONFIG_SND_SOC_AMD_RENOIR) += snd-acp3x-pdm-dma.o
obj-$(CONFIG_SND_SOC_AMD_RENOIR_MACH) += acp3x-rn.o

View File

@ -0,0 +1,524 @@
// SPDX-License-Identifier: GPL-2.0+
//
// AMD ALSA SoC PDM Driver
//
//Copyright 2020 Advanced Micro Devices, Inc.
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>
#include "rn_acp3x.h"
#define DRV_NAME "acp_rn_pdm_dma"
static const struct snd_pcm_hardware acp_pdm_hardware_capture = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
.formats = SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 2,
.rates = SNDRV_PCM_RATE_48000,
.rate_min = 48000,
.rate_max = 48000,
.buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
.period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
.period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
.periods_min = CAPTURE_MIN_NUM_PERIODS,
.periods_max = CAPTURE_MAX_NUM_PERIODS,
};
static irqreturn_t pdm_irq_handler(int irq, void *dev_id)
{
struct pdm_dev_data *rn_pdm_data;
u16 cap_flag;
u32 val;
rn_pdm_data = dev_id;
if (!rn_pdm_data)
return IRQ_NONE;
cap_flag = 0;
val = rn_readl(rn_pdm_data->acp_base + ACP_EXTERNAL_INTR_STAT);
if ((val & BIT(PDM_DMA_STAT)) && rn_pdm_data->capture_stream) {
rn_writel(BIT(PDM_DMA_STAT), rn_pdm_data->acp_base +
ACP_EXTERNAL_INTR_STAT);
snd_pcm_period_elapsed(rn_pdm_data->capture_stream);
cap_flag = 1;
}
if (cap_flag)
return IRQ_HANDLED;
else
return IRQ_NONE;
}
static void init_pdm_ring_buffer(u32 physical_addr,
u32 buffer_size,
u32 watermark_size,
void __iomem *acp_base)
{
rn_writel(physical_addr, acp_base + ACP_WOV_RX_RINGBUFADDR);
rn_writel(buffer_size, acp_base + ACP_WOV_RX_RINGBUFSIZE);
rn_writel(watermark_size, acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
rn_writel(0x01, acp_base + ACPAXI2AXI_ATU_CTRL);
}
static void enable_pdm_clock(void __iomem *acp_base)
{
u32 pdm_clk_enable, pdm_ctrl;
pdm_clk_enable = ACP_PDM_CLK_FREQ_MASK;
pdm_ctrl = 0x00;
rn_writel(pdm_clk_enable, acp_base + ACP_WOV_CLK_CTRL);
pdm_ctrl = rn_readl(acp_base + ACP_WOV_MISC_CTRL);
pdm_ctrl |= ACP_WOV_MISC_CTRL_MASK;
rn_writel(pdm_ctrl, acp_base + ACP_WOV_MISC_CTRL);
}
static void enable_pdm_interrupts(void __iomem *acp_base)
{
u32 ext_int_ctrl;
ext_int_ctrl = rn_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
ext_int_ctrl |= PDM_DMA_INTR_MASK;
rn_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
}
static void disable_pdm_interrupts(void __iomem *acp_base)
{
u32 ext_int_ctrl;
ext_int_ctrl = rn_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
ext_int_ctrl |= ~PDM_DMA_INTR_MASK;
rn_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
}
static bool check_pdm_dma_status(void __iomem *acp_base)
{
bool pdm_dma_status;
u32 pdm_enable, pdm_dma_enable;
pdm_dma_status = false;
pdm_enable = rn_readl(acp_base + ACP_WOV_PDM_ENABLE);
pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
if ((pdm_enable & ACP_PDM_ENABLE) && (pdm_dma_enable &
ACP_PDM_DMA_EN_STATUS))
pdm_dma_status = true;
return pdm_dma_status;
}
static int start_pdm_dma(void __iomem *acp_base)
{
u32 pdm_enable;
u32 pdm_dma_enable;
int timeout;
pdm_enable = 0x01;
pdm_dma_enable = 0x01;
enable_pdm_clock(acp_base);
rn_writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
rn_writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
pdm_dma_enable = 0x00;
timeout = 0;
while (++timeout < ACP_COUNTER) {
pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
if ((pdm_dma_enable & 0x02) == ACP_PDM_DMA_EN_STATUS)
return 0;
udelay(DELAY_US);
}
return -ETIMEDOUT;
}
static int stop_pdm_dma(void __iomem *acp_base)
{
u32 pdm_enable, pdm_dma_enable;
int timeout;
pdm_enable = 0x00;
pdm_dma_enable = 0x00;
pdm_enable = rn_readl(acp_base + ACP_WOV_PDM_ENABLE);
pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
if (pdm_dma_enable & 0x01) {
pdm_dma_enable = 0x02;
rn_writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
pdm_dma_enable = 0x00;
timeout = 0;
while (++timeout < ACP_COUNTER) {
pdm_dma_enable = rn_readl(acp_base +
ACP_WOV_PDM_DMA_ENABLE);
if ((pdm_dma_enable & 0x02) == 0x00)
break;
udelay(DELAY_US);
}
if (timeout == ACP_COUNTER)
return -ETIMEDOUT;
}
if (pdm_enable == ACP_PDM_ENABLE) {
pdm_enable = ACP_PDM_DISABLE;
rn_writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
}
rn_writel(0x01, acp_base + ACP_WOV_PDM_FIFO_FLUSH);
return 0;
}
static void config_acp_dma(struct pdm_stream_instance *rtd, int direction)
{
u16 page_idx;
u32 low, high, val;
dma_addr_t addr;
addr = rtd->dma_addr;
val = 0;
/* Group Enable */
rn_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp_base +
ACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
rn_writel(PAGE_SIZE_4K_ENABLE, rtd->acp_base +
ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
/* Load the low address of page int ACP SRAM through SRBM */
low = lower_32_bits(addr);
high = upper_32_bits(addr);
rn_writel(low, rtd->acp_base + ACP_SCRATCH_REG_0 + val);
high |= BIT(31);
rn_writel(high, rtd->acp_base + ACP_SCRATCH_REG_0 + val + 4);
val += 8;
addr += PAGE_SIZE;
}
}
static int acp_pdm_dma_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime;
struct pdm_dev_data *adata;
struct pdm_stream_instance *pdm_data;
int ret;
runtime = substream->runtime;
adata = dev_get_drvdata(component->dev);
pdm_data = kzalloc(sizeof(*pdm_data), GFP_KERNEL);
if (!pdm_data)
return -EINVAL;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
runtime->hw = acp_pdm_hardware_capture;
ret = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
if (ret < 0) {
dev_err(component->dev, "set integer constraint failed\n");
kfree(pdm_data);
return ret;
}
enable_pdm_interrupts(adata->acp_base);
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
adata->capture_stream = substream;
pdm_data->acp_base = adata->acp_base;
runtime->private_data = pdm_data;
return ret;
}
static int acp_pdm_dma_hw_params(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct pdm_stream_instance *rtd;
size_t size, period_bytes;
rtd = substream->runtime->private_data;
if (!rtd)
return -EINVAL;
size = params_buffer_bytes(params);
period_bytes = params_period_bytes(params);
rtd->dma_addr = substream->dma_buffer.addr;
rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
config_acp_dma(rtd, substream->stream);
init_pdm_ring_buffer(MEM_WINDOW_START, size, period_bytes,
rtd->acp_base);
return 0;
}
static u64 acp_pdm_get_byte_count(struct pdm_stream_instance *rtd,
int direction)
{
union acp_pdm_dma_count byte_count;
byte_count.bcount.high =
rn_readl(rtd->acp_base +
ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH);
byte_count.bcount.low =
rn_readl(rtd->acp_base +
ACP_WOV_RX_LINEARPOSITIONCNTR_LOW);
return byte_count.bytescount;
}
static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_soc_component *comp,
struct snd_pcm_substream *stream)
{
struct pdm_stream_instance *rtd;
u32 pos, buffersize;
u64 bytescount;
rtd = stream->runtime->private_data;
buffersize = frames_to_bytes(stream->runtime,
stream->runtime->buffer_size);
bytescount = acp_pdm_get_byte_count(rtd, stream->stream);
if (bytescount > rtd->bytescount)
bytescount -= rtd->bytescount;
pos = do_div(bytescount, buffersize);
return bytes_to_frames(stream->runtime, pos);
}
static int acp_pdm_dma_new(struct snd_soc_component *component,
struct snd_soc_pcm_runtime *rtd)
{
struct device *parent = component->dev->parent;
snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
parent, MIN_BUFFER, MAX_BUFFER);
return 0;
}
static int acp_pdm_dma_mmap(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
struct vm_area_struct *vma)
{
return snd_pcm_lib_default_mmap(substream, vma);
}
static int acp_pdm_dma_close(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct pdm_dev_data *adata = dev_get_drvdata(component->dev);
disable_pdm_interrupts(adata->acp_base);
adata->capture_stream = NULL;
return 0;
}
static int acp_pdm_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct pdm_stream_instance *rtd;
unsigned int ch_mask;
rtd = substream->runtime->private_data;
switch (params_channels(params)) {
case TWO_CH:
ch_mask = 0x00;
break;
default:
return -EINVAL;
}
rn_writel(ch_mask, rtd->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS);
rn_writel(PDM_DECIMATION_FACTOR, rtd->acp_base +
ACP_WOV_PDM_DECIMATION_FACTOR);
return 0;
}
static int acp_pdm_dai_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct pdm_stream_instance *rtd;
int ret;
bool pdm_status;
rtd = substream->runtime->private_data;
ret = 0;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
rtd->bytescount = acp_pdm_get_byte_count(rtd,
substream->stream);
pdm_status = check_pdm_dma_status(rtd->acp_base);
if (!pdm_status)
ret = start_pdm_dma(rtd->acp_base);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
pdm_status = check_pdm_dma_status(rtd->acp_base);
if (pdm_status)
ret = stop_pdm_dma(rtd->acp_base);
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
static struct snd_soc_dai_ops acp_pdm_dai_ops = {
.hw_params = acp_pdm_dai_hw_params,
.trigger = acp_pdm_dai_trigger,
};
static struct snd_soc_dai_driver acp_pdm_dai_driver = {
.capture = {
.rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 2,
.channels_max = 2,
.rate_min = 48000,
.rate_max = 48000,
},
.ops = &acp_pdm_dai_ops,
};
static const struct snd_soc_component_driver acp_pdm_component = {
.name = DRV_NAME,
.open = acp_pdm_dma_open,
.close = acp_pdm_dma_close,
.hw_params = acp_pdm_dma_hw_params,
.pointer = acp_pdm_dma_pointer,
.mmap = acp_pdm_dma_mmap,
.pcm_construct = acp_pdm_dma_new,
};
static int acp_pdm_audio_probe(struct platform_device *pdev)
{
struct resource *res;
struct pdm_dev_data *adata;
unsigned int irqflags;
int status;
if (!pdev->dev.platform_data) {
dev_err(&pdev->dev, "platform_data not retrieved\n");
return -ENODEV;
}
irqflags = *((unsigned int *)(pdev->dev.platform_data));
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
return -ENODEV;
}
adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
if (!adata)
return -ENOMEM;
adata->acp_base = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!adata->acp_base)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
return -ENODEV;
}
adata->pdm_irq = res->start;
adata->capture_stream = NULL;
dev_set_drvdata(&pdev->dev, adata);
status = devm_snd_soc_register_component(&pdev->dev,
&acp_pdm_component,
&acp_pdm_dai_driver, 1);
if (status) {
dev_err(&pdev->dev, "Fail to register acp pdm dai\n");
return -ENODEV;
}
status = devm_request_irq(&pdev->dev, adata->pdm_irq, pdm_irq_handler,
irqflags, "ACP_PDM_IRQ", adata);
if (status) {
dev_err(&pdev->dev, "ACP PDM IRQ request failed\n");
return -ENODEV;
}
pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev);
pm_runtime_allow(&pdev->dev);
return 0;
}
static int acp_pdm_audio_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
return 0;
}
static int acp_pdm_resume(struct device *dev)
{
struct pdm_dev_data *adata;
struct snd_pcm_runtime *runtime;
struct pdm_stream_instance *rtd;
u32 period_bytes, buffer_len;
adata = dev_get_drvdata(dev);
if (adata->capture_stream && adata->capture_stream->runtime) {
runtime = adata->capture_stream->runtime;
rtd = runtime->private_data;
period_bytes = frames_to_bytes(runtime, runtime->period_size);
buffer_len = frames_to_bytes(runtime, runtime->buffer_size);
config_acp_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
init_pdm_ring_buffer(MEM_WINDOW_START, buffer_len, period_bytes,
adata->acp_base);
}
enable_pdm_interrupts(adata->acp_base);
return 0;
}
static int acp_pdm_runtime_suspend(struct device *dev)
{
struct pdm_dev_data *adata;
adata = dev_get_drvdata(dev);
disable_pdm_interrupts(adata->acp_base);
return 0;
}
static int acp_pdm_runtime_resume(struct device *dev)
{
struct pdm_dev_data *adata;
adata = dev_get_drvdata(dev);
enable_pdm_interrupts(adata->acp_base);
return 0;
}
static const struct dev_pm_ops acp_pdm_pm_ops = {
.runtime_suspend = acp_pdm_runtime_suspend,
.runtime_resume = acp_pdm_runtime_resume,
.resume = acp_pdm_resume,
};
static struct platform_driver acp_pdm_dma_driver = {
.probe = acp_pdm_audio_probe,
.remove = acp_pdm_audio_remove,
.driver = {
.name = "acp_rn_pdm_dma",
.pm = &acp_pdm_pm_ops,
},
};
module_platform_driver(acp_pdm_dma_driver);
MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
MODULE_DESCRIPTION("AMD ACP3x Renior PDM Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);

View File

@ -0,0 +1,77 @@
// SPDX-License-Identifier: GPL-2.0+
//
// Machine driver for AMD Renoir platform using DMIC
//
//Copyright 2020 Advanced Micro Devices, Inc.
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <linux/module.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <linux/io.h>
#include "rn_acp3x.h"
#define DRV_NAME "acp_pdm_mach"
SND_SOC_DAILINK_DEF(acp_pdm,
DAILINK_COMP_ARRAY(COMP_CPU("acp_rn_pdm_dma.0")));
SND_SOC_DAILINK_DEF(dmic_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec.0",
"dmic-hifi")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_rn_pdm_dma.0")));
static struct snd_soc_dai_link acp_dai_pdm[] = {
{
.name = "acp3x-dmic-capture",
.stream_name = "DMIC capture",
.capture_only = 1,
SND_SOC_DAILINK_REG(acp_pdm, dmic_codec, platform),
},
};
static struct snd_soc_card acp_card = {
.name = "acp",
.owner = THIS_MODULE,
.dai_link = acp_dai_pdm,
.num_links = 1,
};
static int acp_probe(struct platform_device *pdev)
{
int ret;
struct acp_pdm *machine = NULL;
struct snd_soc_card *card;
card = &acp_card;
acp_card.dev = &pdev->dev;
platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, machine);
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) {
dev_err(&pdev->dev,
"snd_soc_register_card(%s) failed: %d\n",
acp_card.name, ret);
return ret;
}
return 0;
}
static struct platform_driver acp_mach_driver = {
.driver = {
.name = "acp_pdm_mach",
.pm = &snd_soc_pm_ops,
},
.probe = acp_probe,
};
module_platform_driver(acp_mach_driver);
MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME);

View File

@ -0,0 +1,344 @@
// SPDX-License-Identifier: GPL-2.0+
//
// AMD Renoir ACP PCI Driver
//
//Copyright 2020 Advanced Micro Devices, Inc.
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
#include "rn_acp3x.h"
static int acp_power_gating;
module_param(acp_power_gating, int, 0644);
MODULE_PARM_DESC(acp_power_gating, "Enable acp power gating");
struct acp_dev_data {
void __iomem *acp_base;
struct resource *res;
struct platform_device *pdev[ACP_DEVS];
};
static int rn_acp_power_on(void __iomem *acp_base)
{
u32 val;
int timeout;
val = rn_readl(acp_base + ACP_PGFSM_STATUS);
if (val == 0)
return val;
if ((val & ACP_PGFSM_STATUS_MASK) !=
ACP_POWER_ON_IN_PROGRESS)
rn_writel(ACP_PGFSM_CNTL_POWER_ON_MASK,
acp_base + ACP_PGFSM_CONTROL);
timeout = 0;
while (++timeout < 500) {
val = rn_readl(acp_base + ACP_PGFSM_STATUS);
if (!val)
return 0;
udelay(1);
}
return -ETIMEDOUT;
}
static int rn_acp_power_off(void __iomem *acp_base)
{
u32 val;
int timeout;
rn_writel(ACP_PGFSM_CNTL_POWER_OFF_MASK,
acp_base + ACP_PGFSM_CONTROL);
timeout = 0;
while (++timeout < 500) {
val = rn_readl(acp_base + ACP_PGFSM_STATUS);
if ((val & ACP_PGFSM_STATUS_MASK) == ACP_POWERED_OFF)
return 0;
udelay(1);
}
return -ETIMEDOUT;
}
static int rn_acp_reset(void __iomem *acp_base)
{
u32 val;
int timeout;
rn_writel(1, acp_base + ACP_SOFT_RESET);
timeout = 0;
while (++timeout < 500) {
val = rn_readl(acp_base + ACP_SOFT_RESET);
if (val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK)
break;
cpu_relax();
}
rn_writel(0, acp_base + ACP_SOFT_RESET);
timeout = 0;
while (++timeout < 500) {
val = rn_readl(acp_base + ACP_SOFT_RESET);
if (!val)
return 0;
cpu_relax();
}
return -ETIMEDOUT;
}
static void rn_acp_enable_interrupts(void __iomem *acp_base)
{
u32 ext_intr_ctrl;
rn_writel(0x01, acp_base + ACP_EXTERNAL_INTR_ENB);
ext_intr_ctrl = rn_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
ext_intr_ctrl |= ACP_ERROR_MASK;
rn_writel(ext_intr_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
}
static void rn_acp_disable_interrupts(void __iomem *acp_base)
{
rn_writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base +
ACP_EXTERNAL_INTR_STAT);
rn_writel(0x00, acp_base + ACP_EXTERNAL_INTR_ENB);
}
static int rn_acp_init(void __iomem *acp_base)
{
int ret;
/* power on */
ret = rn_acp_power_on(acp_base);
if (ret) {
pr_err("ACP power on failed\n");
return ret;
}
rn_writel(0x01, acp_base + ACP_CONTROL);
/* Reset */
ret = rn_acp_reset(acp_base);
if (ret) {
pr_err("ACP reset failed\n");
return ret;
}
rn_writel(0x03, acp_base + ACP_CLKMUX_SEL);
rn_acp_enable_interrupts(acp_base);
return 0;
}
static int rn_acp_deinit(void __iomem *acp_base)
{
int ret;
rn_acp_disable_interrupts(acp_base);
/* Reset */
ret = rn_acp_reset(acp_base);
if (ret) {
pr_err("ACP reset failed\n");
return ret;
}
rn_writel(0x00, acp_base + ACP_CLKMUX_SEL);
rn_writel(0x00, acp_base + ACP_CONTROL);
/* power off */
if (acp_power_gating) {
ret = rn_acp_power_off(acp_base);
if (ret) {
pr_err("ACP power off failed\n");
return ret;
}
}
return 0;
}
static int snd_rn_acp_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
struct acp_dev_data *adata;
struct platform_device_info pdevinfo[ACP_DEVS];
unsigned int irqflags;
int ret, index;
u32 addr;
if (pci_enable_device(pci)) {
dev_err(&pci->dev, "pci_enable_device failed\n");
return -ENODEV;
}
ret = pci_request_regions(pci, "AMD ACP3x audio");
if (ret < 0) {
dev_err(&pci->dev, "pci_request_regions failed\n");
goto disable_pci;
}
adata = devm_kzalloc(&pci->dev, sizeof(struct acp_dev_data),
GFP_KERNEL);
if (!adata) {
ret = -ENOMEM;
goto release_regions;
}
/* check for msi interrupt support */
ret = pci_enable_msi(pci);
if (ret)
/* msi is not enabled */
irqflags = IRQF_SHARED;
else
/* msi is enabled */
irqflags = 0;
addr = pci_resource_start(pci, 0);
adata->acp_base = devm_ioremap(&pci->dev, addr,
pci_resource_len(pci, 0));
if (!adata->acp_base) {
ret = -ENOMEM;
goto disable_msi;
}
pci_set_master(pci);
pci_set_drvdata(pci, adata);
ret = rn_acp_init(adata->acp_base);
if (ret)
goto disable_msi;
adata->res = devm_kzalloc(&pci->dev,
sizeof(struct resource) * 2,
GFP_KERNEL);
if (!adata->res) {
ret = -ENOMEM;
goto de_init;
}
adata->res[0].name = "acp_pdm_iomem";
adata->res[0].flags = IORESOURCE_MEM;
adata->res[0].start = addr;
adata->res[0].end = addr + (ACP_REG_END - ACP_REG_START);
adata->res[1].name = "acp_pdm_irq";
adata->res[1].flags = IORESOURCE_IRQ;
adata->res[1].start = pci->irq;
adata->res[1].end = pci->irq;
memset(&pdevinfo, 0, sizeof(pdevinfo));
pdevinfo[0].name = "acp_rn_pdm_dma";
pdevinfo[0].id = 0;
pdevinfo[0].parent = &pci->dev;
pdevinfo[0].num_res = 2;
pdevinfo[0].res = adata->res;
pdevinfo[0].data = &irqflags;
pdevinfo[0].size_data = sizeof(irqflags);
pdevinfo[1].name = "dmic-codec";
pdevinfo[1].id = 0;
pdevinfo[1].parent = &pci->dev;
pdevinfo[2].name = "acp_pdm_mach";
pdevinfo[2].id = 0;
pdevinfo[2].parent = &pci->dev;
for (index = 0; index < ACP_DEVS; index++) {
adata->pdev[index] =
platform_device_register_full(&pdevinfo[index]);
if (IS_ERR(adata->pdev[index])) {
dev_err(&pci->dev, "cannot register %s device\n",
pdevinfo[index].name);
ret = PTR_ERR(adata->pdev[index]);
goto unregister_devs;
}
}
pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(&pci->dev);
pm_runtime_put_noidle(&pci->dev);
pm_runtime_allow(&pci->dev);
return 0;
unregister_devs:
for (index = 0; index < ACP_DEVS; index++)
platform_device_unregister(adata->pdev[index]);
de_init:
if (rn_acp_deinit(adata->acp_base))
dev_err(&pci->dev, "ACP de-init failed\n");
disable_msi:
pci_disable_msi(pci);
release_regions:
pci_release_regions(pci);
disable_pci:
pci_disable_device(pci);
return ret;
}
static int snd_rn_acp_suspend(struct device *dev)
{
int ret;
struct acp_dev_data *adata;
adata = dev_get_drvdata(dev);
ret = rn_acp_deinit(adata->acp_base);
if (ret)
dev_err(dev, "ACP de-init failed\n");
else
dev_dbg(dev, "ACP de-initialized\n");
return ret;
}
static int snd_rn_acp_resume(struct device *dev)
{
int ret;
struct acp_dev_data *adata;
adata = dev_get_drvdata(dev);
ret = rn_acp_init(adata->acp_base);
if (ret) {
dev_err(dev, "ACP init failed\n");
return ret;
}
return 0;
}
static const struct dev_pm_ops rn_acp_pm = {
.runtime_suspend = snd_rn_acp_suspend,
.runtime_resume = snd_rn_acp_resume,
.suspend = snd_rn_acp_suspend,
.resume = snd_rn_acp_resume,
};
static void snd_rn_acp_remove(struct pci_dev *pci)
{
struct acp_dev_data *adata;
int ret, index;
adata = pci_get_drvdata(pci);
for (index = 0; index < ACP_DEVS; index++)
platform_device_unregister(adata->pdev[index]);
ret = rn_acp_deinit(adata->acp_base);
if (ret)
dev_err(&pci->dev, "ACP de-init failed\n");
pm_runtime_forbid(&pci->dev);
pm_runtime_get_noresume(&pci->dev);
pci_disable_msi(pci);
pci_release_regions(pci);
pci_disable_device(pci);
}
static const struct pci_device_id snd_rn_acp_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_DEVICE_ID),
.class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
.class_mask = 0xffffff },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, snd_rn_acp_ids);
static struct pci_driver rn_acp_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_rn_acp_ids,
.probe = snd_rn_acp_probe,
.remove = snd_rn_acp_remove,
.driver = {
.pm = &rn_acp_pm,
}
};
module_pci_driver(rn_acp_driver);
MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
MODULE_DESCRIPTION("AMD ACP Renoir PCI driver");
MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,88 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* AMD ALSA SoC PDM Driver
*
* Copyright 2020 Advanced Micro Devices, Inc.
*/
#include "rn_chip_offset_byte.h"
#define ACP_DEVS 3
#define ACP_PHY_BASE_ADDRESS 0x1240000
#define ACP_REG_START 0x1240000
#define ACP_REG_END 0x1250200
#define ACP_DEVICE_ID 0x15E2
#define ACP_POWER_ON 0x00
#define ACP_POWER_ON_IN_PROGRESS 0x01
#define ACP_POWER_OFF 0x02
#define ACP_POWER_OFF_IN_PROGRESS 0x03
#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001
#define ACP_PGFSM_CNTL_POWER_ON_MASK 0x01
#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0x00
#define ACP_PGFSM_STATUS_MASK 0x03
#define ACP_POWERED_ON 0x00
#define ACP_POWER_ON_IN_PROGRESS 0x01
#define ACP_POWERED_OFF 0x02
#define ACP_POWER_OFF_IN_PROGRESS 0x03
#define ACP_ERROR_MASK 0x20000000
#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
#define PDM_DMA_STAT 0x10
#define PDM_DMA_INTR_MASK 0x10000
#define ACP_ERROR_STAT 29
#define PDM_DECIMATION_FACTOR 0x2
#define ACP_PDM_CLK_FREQ_MASK 0x07
#define ACP_WOV_MISC_CTRL_MASK 0x10
#define ACP_PDM_ENABLE 0x01
#define ACP_PDM_DISABLE 0x00
#define ACP_PDM_DMA_EN_STATUS 0x02
#define TWO_CH 0x02
#define DELAY_US 5
#define ACP_COUNTER 20000
/* time in ms for runtime suspend delay */
#define ACP_SUSPEND_DELAY_MS 2000
#define ACP_SRAM_PTE_OFFSET 0x02050000
#define PAGE_SIZE_4K_ENABLE 0x2
#define MEM_WINDOW_START 0x4000000
#define CAPTURE_MIN_NUM_PERIODS 4
#define CAPTURE_MAX_NUM_PERIODS 4
#define CAPTURE_MAX_PERIOD_SIZE 8192
#define CAPTURE_MIN_PERIOD_SIZE 4096
#define MAX_BUFFER (CAPTURE_MAX_PERIOD_SIZE * CAPTURE_MAX_NUM_PERIODS)
#define MIN_BUFFER MAX_BUFFER
struct pdm_dev_data {
u32 pdm_irq;
void __iomem *acp_base;
struct snd_pcm_substream *capture_stream;
};
struct pdm_stream_instance {
u16 num_pages;
u16 channels;
dma_addr_t dma_addr;
u64 bytescount;
void __iomem *acp_base;
};
union acp_pdm_dma_count {
struct {
u32 low;
u32 high;
} bcount;
u64 bytescount;
};
static inline u32 rn_readl(void __iomem *base_addr)
{
return readl(base_addr - ACP_PHY_BASE_ADDRESS);
}
static inline void rn_writel(u32 val, void __iomem *base_addr)
{
writel(val, base_addr - ACP_PHY_BASE_ADDRESS);
}

View File

@ -0,0 +1,349 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* AMD ACP 3.1 Register Documentation
*
* Copyright 2020 Advanced Micro Devices, Inc.
*/
#ifndef _rn_OFFSET_HEADER
#define _rn_OFFSET_HEADER
// Registers from ACP_DMA block
#define ACP_DMA_CNTL_0 0x1240000
#define ACP_DMA_CNTL_1 0x1240004
#define ACP_DMA_CNTL_2 0x1240008
#define ACP_DMA_CNTL_3 0x124000C
#define ACP_DMA_CNTL_4 0x1240010
#define ACP_DMA_CNTL_5 0x1240014
#define ACP_DMA_CNTL_6 0x1240018
#define ACP_DMA_CNTL_7 0x124001C
#define ACP_DMA_DSCR_STRT_IDX_0 0x1240020
#define ACP_DMA_DSCR_STRT_IDX_1 0x1240024
#define ACP_DMA_DSCR_STRT_IDX_2 0x1240028
#define ACP_DMA_DSCR_STRT_IDX_3 0x124002C
#define ACP_DMA_DSCR_STRT_IDX_4 0x1240030
#define ACP_DMA_DSCR_STRT_IDX_5 0x1240034
#define ACP_DMA_DSCR_STRT_IDX_6 0x1240038
#define ACP_DMA_DSCR_STRT_IDX_7 0x124003C
#define ACP_DMA_DSCR_CNT_0 0x1240040
#define ACP_DMA_DSCR_CNT_1 0x1240044
#define ACP_DMA_DSCR_CNT_2 0x1240048
#define ACP_DMA_DSCR_CNT_3 0x124004C
#define ACP_DMA_DSCR_CNT_4 0x1240050
#define ACP_DMA_DSCR_CNT_5 0x1240054
#define ACP_DMA_DSCR_CNT_6 0x1240058
#define ACP_DMA_DSCR_CNT_7 0x124005C
#define ACP_DMA_PRIO_0 0x1240060
#define ACP_DMA_PRIO_1 0x1240064
#define ACP_DMA_PRIO_2 0x1240068
#define ACP_DMA_PRIO_3 0x124006C
#define ACP_DMA_PRIO_4 0x1240070
#define ACP_DMA_PRIO_5 0x1240074
#define ACP_DMA_PRIO_6 0x1240078
#define ACP_DMA_PRIO_7 0x124007C
#define ACP_DMA_CUR_DSCR_0 0x1240080
#define ACP_DMA_CUR_DSCR_1 0x1240084
#define ACP_DMA_CUR_DSCR_2 0x1240088
#define ACP_DMA_CUR_DSCR_3 0x124008C
#define ACP_DMA_CUR_DSCR_4 0x1240090
#define ACP_DMA_CUR_DSCR_5 0x1240094
#define ACP_DMA_CUR_DSCR_6 0x1240098
#define ACP_DMA_CUR_DSCR_7 0x124009C
#define ACP_DMA_CUR_TRANS_CNT_0 0x12400A0
#define ACP_DMA_CUR_TRANS_CNT_1 0x12400A4
#define ACP_DMA_CUR_TRANS_CNT_2 0x12400A8
#define ACP_DMA_CUR_TRANS_CNT_3 0x12400AC
#define ACP_DMA_CUR_TRANS_CNT_4 0x12400B0
#define ACP_DMA_CUR_TRANS_CNT_5 0x12400B4
#define ACP_DMA_CUR_TRANS_CNT_6 0x12400B8
#define ACP_DMA_CUR_TRANS_CNT_7 0x12400BC
#define ACP_DMA_ERR_STS_0 0x12400C0
#define ACP_DMA_ERR_STS_1 0x12400C4
#define ACP_DMA_ERR_STS_2 0x12400C8
#define ACP_DMA_ERR_STS_3 0x12400CC
#define ACP_DMA_ERR_STS_4 0x12400D0
#define ACP_DMA_ERR_STS_5 0x12400D4
#define ACP_DMA_ERR_STS_6 0x12400D8
#define ACP_DMA_ERR_STS_7 0x12400DC
#define ACP_DMA_DESC_BASE_ADDR 0x12400E0
#define ACP_DMA_DESC_MAX_NUM_DSCR 0x12400E4
#define ACP_DMA_CH_STS 0x12400E8
#define ACP_DMA_CH_GROUP 0x12400EC
#define ACP_DMA_CH_RST_STS 0x12400F0
// Registers from ACP_AXI2AXIATU block
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1 0x1240C00
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_1 0x1240C04
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2 0x1240C08
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_2 0x1240C0C
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_3 0x1240C10
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_3 0x1240C14
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_4 0x1240C18
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_4 0x1240C1C
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5 0x1240C20
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0x1240C24
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_6 0x1240C28
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_6 0x1240C2C
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_7 0x1240C30
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_7 0x1240C34
#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_8 0x1240C38
#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_8 0x1240C3C
#define ACPAXI2AXI_ATU_CTRL 0x1240C40
// Registers from ACP_CLKRST block
#define ACP_SOFT_RESET 0x1241000
#define ACP_CONTROL 0x1241004
#define ACP_STATUS 0x1241008
#define ACP_DYNAMIC_CG_MASTER_CONTROL 0x1241010
// Registers from ACP_MISC block
#define ACP_EXTERNAL_INTR_ENB 0x1241800
#define ACP_EXTERNAL_INTR_CNTL 0x1241804
#define ACP_EXTERNAL_INTR_STAT 0x1241808
#define ACP_PGMEM_CTRL 0x12418C0
#define ACP_ERROR_STATUS 0x12418C4
#define ACP_SW_I2S_ERROR_REASON 0x12418C8
#define ACP_MEM_PG_STS 0x12418CC
// Registers from ACP_PGFSM block
#define ACP_I2S_PIN_CONFIG 0x1241400
#define ACP_PAD_PULLUP_PULLDOWN_CTRL 0x1241404
#define ACP_PAD_DRIVE_STRENGTH_CTRL 0x1241408
#define ACP_SW_PAD_KEEPER_EN 0x124140C
#define ACP_PGFSM_CONTROL 0x124141C
#define ACP_PGFSM_STATUS 0x1241420
#define ACP_CLKMUX_SEL 0x1241424
#define ACP_DEVICE_STATE 0x1241428
#define AZ_DEVICE_STATE 0x124142C
#define ACP_INTR_URGENCY_TIMER 0x1241430
#define AZ_INTR_URGENCY_TIMER 0x1241434
// Registers from ACP_SCRATCH block
#define ACP_SCRATCH_REG_0 0x1250000
#define ACP_SCRATCH_REG_1 0x1250004
#define ACP_SCRATCH_REG_2 0x1250008
#define ACP_SCRATCH_REG_3 0x125000C
#define ACP_SCRATCH_REG_4 0x1250010
#define ACP_SCRATCH_REG_5 0x1250014
#define ACP_SCRATCH_REG_6 0x1250018
#define ACP_SCRATCH_REG_7 0x125001C
#define ACP_SCRATCH_REG_8 0x1250020
#define ACP_SCRATCH_REG_9 0x1250024
#define ACP_SCRATCH_REG_10 0x1250028
#define ACP_SCRATCH_REG_11 0x125002C
#define ACP_SCRATCH_REG_12 0x1250030
#define ACP_SCRATCH_REG_13 0x1250034
#define ACP_SCRATCH_REG_14 0x1250038
#define ACP_SCRATCH_REG_15 0x125003C
#define ACP_SCRATCH_REG_16 0x1250040
#define ACP_SCRATCH_REG_17 0x1250044
#define ACP_SCRATCH_REG_18 0x1250048
#define ACP_SCRATCH_REG_19 0x125004C
#define ACP_SCRATCH_REG_20 0x1250050
#define ACP_SCRATCH_REG_21 0x1250054
#define ACP_SCRATCH_REG_22 0x1250058
#define ACP_SCRATCH_REG_23 0x125005C
#define ACP_SCRATCH_REG_24 0x1250060
#define ACP_SCRATCH_REG_25 0x1250064
#define ACP_SCRATCH_REG_26 0x1250068
#define ACP_SCRATCH_REG_27 0x125006C
#define ACP_SCRATCH_REG_28 0x1250070
#define ACP_SCRATCH_REG_29 0x1250074
#define ACP_SCRATCH_REG_30 0x1250078
#define ACP_SCRATCH_REG_31 0x125007C
#define ACP_SCRATCH_REG_32 0x1250080
#define ACP_SCRATCH_REG_33 0x1250084
#define ACP_SCRATCH_REG_34 0x1250088
#define ACP_SCRATCH_REG_35 0x125008C
#define ACP_SCRATCH_REG_36 0x1250090
#define ACP_SCRATCH_REG_37 0x1250094
#define ACP_SCRATCH_REG_38 0x1250098
#define ACP_SCRATCH_REG_39 0x125009C
#define ACP_SCRATCH_REG_40 0x12500A0
#define ACP_SCRATCH_REG_41 0x12500A4
#define ACP_SCRATCH_REG_42 0x12500A8
#define ACP_SCRATCH_REG_43 0x12500AC
#define ACP_SCRATCH_REG_44 0x12500B0
#define ACP_SCRATCH_REG_45 0x12500B4
#define ACP_SCRATCH_REG_46 0x12500B8
#define ACP_SCRATCH_REG_47 0x12500BC
#define ACP_SCRATCH_REG_48 0x12500C0
#define ACP_SCRATCH_REG_49 0x12500C4
#define ACP_SCRATCH_REG_50 0x12500C8
#define ACP_SCRATCH_REG_51 0x12500CC
#define ACP_SCRATCH_REG_52 0x12500D0
#define ACP_SCRATCH_REG_53 0x12500D4
#define ACP_SCRATCH_REG_54 0x12500D8
#define ACP_SCRATCH_REG_55 0x12500DC
#define ACP_SCRATCH_REG_56 0x12500E0
#define ACP_SCRATCH_REG_57 0x12500E4
#define ACP_SCRATCH_REG_58 0x12500E8
#define ACP_SCRATCH_REG_59 0x12500EC
#define ACP_SCRATCH_REG_60 0x12500F0
#define ACP_SCRATCH_REG_61 0x12500F4
#define ACP_SCRATCH_REG_62 0x12500F8
#define ACP_SCRATCH_REG_63 0x12500FC
#define ACP_SCRATCH_REG_64 0x1250100
#define ACP_SCRATCH_REG_65 0x1250104
#define ACP_SCRATCH_REG_66 0x1250108
#define ACP_SCRATCH_REG_67 0x125010C
#define ACP_SCRATCH_REG_68 0x1250110
#define ACP_SCRATCH_REG_69 0x1250114
#define ACP_SCRATCH_REG_70 0x1250118
#define ACP_SCRATCH_REG_71 0x125011C
#define ACP_SCRATCH_REG_72 0x1250120
#define ACP_SCRATCH_REG_73 0x1250124
#define ACP_SCRATCH_REG_74 0x1250128
#define ACP_SCRATCH_REG_75 0x125012C
#define ACP_SCRATCH_REG_76 0x1250130
#define ACP_SCRATCH_REG_77 0x1250134
#define ACP_SCRATCH_REG_78 0x1250138
#define ACP_SCRATCH_REG_79 0x125013C
#define ACP_SCRATCH_REG_80 0x1250140
#define ACP_SCRATCH_REG_81 0x1250144
#define ACP_SCRATCH_REG_82 0x1250148
#define ACP_SCRATCH_REG_83 0x125014C
#define ACP_SCRATCH_REG_84 0x1250150
#define ACP_SCRATCH_REG_85 0x1250154
#define ACP_SCRATCH_REG_86 0x1250158
#define ACP_SCRATCH_REG_87 0x125015C
#define ACP_SCRATCH_REG_88 0x1250160
#define ACP_SCRATCH_REG_89 0x1250164
#define ACP_SCRATCH_REG_90 0x1250168
#define ACP_SCRATCH_REG_91 0x125016C
#define ACP_SCRATCH_REG_92 0x1250170
#define ACP_SCRATCH_REG_93 0x1250174
#define ACP_SCRATCH_REG_94 0x1250178
#define ACP_SCRATCH_REG_95 0x125017C
#define ACP_SCRATCH_REG_96 0x1250180
#define ACP_SCRATCH_REG_97 0x1250184
#define ACP_SCRATCH_REG_98 0x1250188
#define ACP_SCRATCH_REG_99 0x125018C
#define ACP_SCRATCH_REG_100 0x1250190
#define ACP_SCRATCH_REG_101 0x1250194
#define ACP_SCRATCH_REG_102 0x1250198
#define ACP_SCRATCH_REG_103 0x125019C
#define ACP_SCRATCH_REG_104 0x12501A0
#define ACP_SCRATCH_REG_105 0x12501A4
#define ACP_SCRATCH_REG_106 0x12501A8
#define ACP_SCRATCH_REG_107 0x12501AC
#define ACP_SCRATCH_REG_108 0x12501B0
#define ACP_SCRATCH_REG_109 0x12501B4
#define ACP_SCRATCH_REG_110 0x12501B8
#define ACP_SCRATCH_REG_111 0x12501BC
#define ACP_SCRATCH_REG_112 0x12501C0
#define ACP_SCRATCH_REG_113 0x12501C4
#define ACP_SCRATCH_REG_114 0x12501C8
#define ACP_SCRATCH_REG_115 0x12501CC
#define ACP_SCRATCH_REG_116 0x12501D0
#define ACP_SCRATCH_REG_117 0x12501D4
#define ACP_SCRATCH_REG_118 0x12501D8
#define ACP_SCRATCH_REG_119 0x12501DC
#define ACP_SCRATCH_REG_120 0x12501E0
#define ACP_SCRATCH_REG_121 0x12501E4
#define ACP_SCRATCH_REG_122 0x12501E8
#define ACP_SCRATCH_REG_123 0x12501EC
#define ACP_SCRATCH_REG_124 0x12501F0
#define ACP_SCRATCH_REG_125 0x12501F4
#define ACP_SCRATCH_REG_126 0x12501F8
#define ACP_SCRATCH_REG_127 0x12501FC
#define ACP_SCRATCH_REG_128 0x1250200
// Registers from ACP_AUDIO_BUFFERS block
#define ACP_I2S_RX_RINGBUFADDR 0x1242000
#define ACP_I2S_RX_RINGBUFSIZE 0x1242004
#define ACP_I2S_RX_LINKPOSITIONCNTR 0x1242008
#define ACP_I2S_RX_FIFOADDR 0x124200C
#define ACP_I2S_RX_FIFOSIZE 0x1242010
#define ACP_I2S_RX_DMA_SIZE 0x1242014
#define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x1242018
#define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW 0x124201C
#define ACP_I2S_RX_INTR_WATERMARK_SIZE 0x1242020
#define ACP_I2S_TX_RINGBUFADDR 0x1242024
#define ACP_I2S_TX_RINGBUFSIZE 0x1242028
#define ACP_I2S_TX_LINKPOSITIONCNTR 0x124202C
#define ACP_I2S_TX_FIFOADDR 0x1242030
#define ACP_I2S_TX_FIFOSIZE 0x1242034
#define ACP_I2S_TX_DMA_SIZE 0x1242038
#define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x124203C
#define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW 0x1242040
#define ACP_I2S_TX_INTR_WATERMARK_SIZE 0x1242044
#define ACP_BT_RX_RINGBUFADDR 0x1242048
#define ACP_BT_RX_RINGBUFSIZE 0x124204C
#define ACP_BT_RX_LINKPOSITIONCNTR 0x1242050
#define ACP_BT_RX_FIFOADDR 0x1242054
#define ACP_BT_RX_FIFOSIZE 0x1242058
#define ACP_BT_RX_DMA_SIZE 0x124205C
#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH 0x1242060
#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW 0x1242064
#define ACP_BT_RX_INTR_WATERMARK_SIZE 0x1242068
#define ACP_BT_TX_RINGBUFADDR 0x124206C
#define ACP_BT_TX_RINGBUFSIZE 0x1242070
#define ACP_BT_TX_LINKPOSITIONCNTR 0x1242074
#define ACP_BT_TX_FIFOADDR 0x1242078
#define ACP_BT_TX_FIFOSIZE 0x124207C
#define ACP_BT_TX_DMA_SIZE 0x1242080
#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x1242084
#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x1242088
#define ACP_BT_TX_INTR_WATERMARK_SIZE 0x124208C
#define ACP_HS_RX_RINGBUFADDR 0x1242090
#define ACP_HS_RX_RINGBUFSIZE 0x1242094
#define ACP_HS_RX_LINKPOSITIONCNTR 0x1242098
#define ACP_HS_RX_FIFOADDR 0x124209C
#define ACP_HS_RX_FIFOSIZE 0x12420A0
#define ACP_HS_RX_DMA_SIZE 0x12420A4
#define ACP_HS_RX_LINEARPOSITIONCNTR_HIGH 0x12420A8
#define ACP_HS_RX_LINEARPOSITIONCNTR_LOW 0x12420AC
#define ACP_HS_RX_INTR_WATERMARK_SIZE 0x12420B0
#define ACP_HS_TX_RINGBUFADDR 0x12420B4
#define ACP_HS_TX_RINGBUFSIZE 0x12420B8
#define ACP_HS_TX_LINKPOSITIONCNTR 0x12420BC
#define ACP_HS_TX_FIFOADDR 0x12420C0
#define ACP_HS_TX_FIFOSIZE 0x12420C4
#define ACP_HS_TX_DMA_SIZE 0x12420C8
#define ACP_HS_TX_LINEARPOSITIONCNTR_HIGH 0x12420CC
#define ACP_HS_TX_LINEARPOSITIONCNTR_LOW 0x12420D0
#define ACP_HS_TX_INTR_WATERMARK_SIZE 0x12420D4
// Registers from ACP_I2S_TDM block
#define ACP_I2STDM_IER 0x1242400
#define ACP_I2STDM_IRER 0x1242404
#define ACP_I2STDM_RXFRMT 0x1242408
#define ACP_I2STDM_ITER 0x124240C
#define ACP_I2STDM_TXFRMT 0x1242410
// Registers from ACP_BT_TDM block
#define ACP_BTTDM_IER 0x1242800
#define ACP_BTTDM_IRER 0x1242804
#define ACP_BTTDM_RXFRMT 0x1242808
#define ACP_BTTDM_ITER 0x124280C
#define ACP_BTTDM_TXFRMT 0x1242810
// Registers from ACP_WOV block
#define ACP_WOV_PDM_ENABLE 0x1242C04
#define ACP_WOV_PDM_DMA_ENABLE 0x1242C08
#define ACP_WOV_RX_RINGBUFADDR 0x1242C0C
#define ACP_WOV_RX_RINGBUFSIZE 0x1242C10
#define ACP_WOV_RX_LINKPOSITIONCNTR 0x1242C14
#define ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH 0x1242C18
#define ACP_WOV_RX_LINEARPOSITIONCNTR_LOW 0x1242C1C
#define ACP_WOV_RX_INTR_WATERMARK_SIZE 0x1242C20
#define ACP_WOV_PDM_FIFO_FLUSH 0x1242C24
#define ACP_WOV_PDM_NO_OF_CHANNELS 0x1242C28
#define ACP_WOV_PDM_DECIMATION_FACTOR 0x1242C2C
#define ACP_WOV_PDM_VAD_CTRL 0x1242C30
#define ACP_WOV_BUFFER_STATUS 0x1242C58
#define ACP_WOV_MISC_CTRL 0x1242C5C
#define ACP_WOV_CLK_CTRL 0x1242C60
#define ACP_PDM_VAD_DYNAMIC_CLK_GATING_EN 0x1242C64
#define ACP_WOV_ERROR_STATUS_REGISTER 0x1242C68
#endif

View File

@ -765,7 +765,7 @@ static int atmel_ssc_suspend(struct snd_soc_component *component)
struct atmel_ssc_info *ssc_p;
struct platform_device *pdev = to_platform_device(component->dev);
if (!component->active)
if (!snd_soc_component_active(component))
return 0;
ssc_p = &ssc_info[pdev->id];
@ -793,7 +793,7 @@ static int atmel_ssc_resume(struct snd_soc_component *component)
struct platform_device *pdev = to_platform_device(component->dev);
u32 cr;
if (!component->active)
if (!snd_soc_component_active(component))
return 0;
ssc_p = &ssc_info[pdev->id];

View File

@ -653,7 +653,7 @@ static void bcm2835_i2s_stop(struct bcm2835_i2s_dev *dev,
BCM2835_I2S_CS_A_REG, mask, 0);
/* Stop also the clock when not SND_SOC_DAIFMT_CONT */
if (!dai->active && !(dev->fmt & SND_SOC_DAIFMT_CONT))
if (!snd_soc_dai_active(dai) && !(dev->fmt & SND_SOC_DAIFMT_CONT))
bcm2835_i2s_stop_clock(dev);
}
@ -695,7 +695,7 @@ static int bcm2835_i2s_startup(struct snd_pcm_substream *substream,
{
struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
if (dai->active)
if (snd_soc_dai_active(dai))
return 0;
/* Should this still be running stop it */
@ -723,7 +723,7 @@ static void bcm2835_i2s_shutdown(struct snd_pcm_substream *substream,
bcm2835_i2s_stop(dev, substream, dai);
/* If both streams are stopped, disable module and clock */
if (dai->active)
if (snd_soc_dai_active(dai))
return;
/* Disable the module */

View File

@ -1056,7 +1056,7 @@ static int __cygnus_ssp_suspend(struct snd_soc_dai *cpu_dai)
{
struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
if (!cpu_dai->active)
if (!snd_soc_dai_active(cpu_dai))
return 0;
if (!aio->is_slave) {
@ -1097,7 +1097,7 @@ static int __cygnus_ssp_resume(struct snd_soc_dai *cpu_dai)
struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
int error;
if (!cpu_dai->active)
if (!snd_soc_dai_active(cpu_dai))
return 0;
if (!aio->is_slave) {

View File

@ -368,7 +368,7 @@ static int ep93xx_i2s_suspend(struct snd_soc_component *component)
{
struct ep93xx_i2s_info *info = snd_soc_component_get_drvdata(component);
if (!component->active)
if (!snd_soc_component_active(component))
return 0;
ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK);
@ -381,7 +381,7 @@ static int ep93xx_i2s_resume(struct snd_soc_component *component)
{
struct ep93xx_i2s_info *info = snd_soc_component_get_drvdata(component);
if (!component->active)
if (!snd_soc_component_active(component))
return 0;
ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK);

View File

@ -116,6 +116,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_MAX98926
imply SND_SOC_MAX98927
imply SND_SOC_MAX98373
imply SND_SOC_MAX98390
imply SND_SOC_MAX9850
imply SND_SOC_MAX9860
imply SND_SOC_MAX9759
@ -167,7 +168,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_RT5668
imply SND_SOC_RT5670
imply SND_SOC_RT5677
imply SND_SOC_RT5682
imply SND_SOC_RT5682_I2C
imply SND_SOC_RT5682_SDW
imply SND_SOC_RT700_SDW
imply SND_SOC_RT711_SDW
@ -272,6 +273,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_WM9712
imply SND_SOC_WM9713
imply SND_SOC_WSA881X
imply SND_SOC_ZL38060
help
Normally ASoC codec drivers are only built if a machine driver which
uses them is also built since they are only usable with a machine
@ -537,8 +539,7 @@ config SND_SOC_CQ0093VC
config SND_SOC_CROS_EC_CODEC
tristate "codec driver for ChromeOS EC"
depends on CROS_EC
select CRYPTO
select CRYPTO_SHA256
select CRYPTO_LIB_SHA256
help
If you say yes here you will get support for the
ChromeOS Embedded Controller's Audio Codec.
@ -681,6 +682,7 @@ config SND_SOC_CX2072X
config SND_SOC_JZ4740_CODEC
depends on MIPS || COMPILE_TEST
depends on OF
select REGMAP_MMIO
tristate "Ingenic JZ4740 internal CODEC"
help
@ -692,6 +694,7 @@ config SND_SOC_JZ4740_CODEC
config SND_SOC_JZ4725B_CODEC
depends on MIPS || COMPILE_TEST
depends on OF
select REGMAP
tristate "Ingenic JZ4725B internal CODEC"
help
@ -703,6 +706,7 @@ config SND_SOC_JZ4725B_CODEC
config SND_SOC_JZ4770_CODEC
depends on MIPS || COMPILE_TEST
depends on OF
select REGMAP
tristate "Ingenic JZ4770 internal CODEC"
help
@ -717,7 +721,7 @@ config SND_SOC_L3
config SND_SOC_DA7210
tristate
depends on I2C
depends on SND_SOC_I2C_AND_SPI
config SND_SOC_DA7213
tristate "Dialog DA7213 CODEC"
@ -867,6 +871,10 @@ config SND_SOC_MAX98373
tristate "Maxim Integrated MAX98373 Speaker Amplifier"
depends on I2C
config SND_SOC_MAX98390
tristate "Maxim Integrated MAX98390 Speaker Amplifier"
depends on I2C
config SND_SOC_MAX9850
tristate
depends on I2C
@ -1135,7 +1143,11 @@ config SND_SOC_RT5677_SPI
config SND_SOC_RT5682
tristate
depends on I2C || SOUNDWIRE
config SND_SOC_RT5682_I2C
tristate
depends on I2C
select SND_SOC_RT5682
config SND_SOC_RT5682_SDW
tristate "Realtek RT5682 Codec - SDW"
@ -1569,7 +1581,7 @@ config SND_SOC_WM8978
config SND_SOC_WM8983
tristate
depends on I2C
depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8985
tristate "Wolfson Microelectronics WM8985 and WM8758 codec driver"
@ -1620,19 +1632,19 @@ config SND_SOC_WM9090
config SND_SOC_WM9705
tristate
depends on SND_SOC_AC97_BUS
depends on SND_SOC_AC97_BUS || AC97_BUS_NEW
select REGMAP_AC97
select AC97_BUS_COMPAT if AC97_BUS_NEW
config SND_SOC_WM9712
tristate
depends on SND_SOC_AC97_BUS
depends on SND_SOC_AC97_BUS || AC97_BUS_NEW
select REGMAP_AC97
select AC97_BUS_COMPAT if AC97_BUS_NEW
config SND_SOC_WM9713
tristate
depends on SND_SOC_AC97_BUS
depends on SND_SOC_AC97_BUS || AC97_BUS_NEW
select REGMAP_AC97
select AC97_BUS_COMPAT if AC97_BUS_NEW
@ -1645,6 +1657,16 @@ config SND_SOC_WSA881X
This enables support for Qualcomm WSA8810/WSA8815 Class-D
Smart Speaker Amplifier.
config SND_SOC_ZL38060
tristate "Microsemi ZL38060 Connected Home Audio Processor"
depends on SPI_MASTER
select GPIOLIB
select REGMAP
help
Support for ZL38060 Connected Home Audio Processor from Microsemi,
which consists of a Digital Signal Processor (DSP), several Digital
Audio Interfaces (DAIs), analog outputs, and a block of 14 GPIOs.
config SND_SOC_ZX_AUD96P22
tristate "ZTE ZX AUD96P22 CODEC"
depends on I2C

View File

@ -115,6 +115,7 @@ snd-soc-max98925-objs := max98925.o
snd-soc-max98926-objs := max98926.o
snd-soc-max98927-objs := max98927.o
snd-soc-max98373-objs := max98373.o
snd-soc-max98390-objs := max98390.o
snd-soc-max9850-objs := max9850.o
snd-soc-max9860-objs := max9860.o
snd-soc-mc13783-objs := mc13783.o
@ -178,6 +179,7 @@ snd-soc-rt5677-objs := rt5677.o
snd-soc-rt5677-spi-objs := rt5677-spi.o
snd-soc-rt5682-objs := rt5682.o
snd-soc-rt5682-sdw-objs := rt5682-sdw.o
snd-soc-rt5682-i2c-objs := rt5682-i2c.o
snd-soc-rt700-objs := rt700.o rt700-sdw.o
snd-soc-rt711-objs := rt711.o rt711-sdw.o
snd-soc-rt715-objs := rt715.o rt715-sdw.o
@ -288,6 +290,7 @@ snd-soc-wm9712-objs := wm9712.o
snd-soc-wm9713-objs := wm9713.o
snd-soc-wm-hubs-objs := wm_hubs.o
snd-soc-wsa881x-objs := wsa881x.o
snd-soc-zl38060-objs := zl38060.o
snd-soc-zx-aud96p22-objs := zx_aud96p22.o
# Amp
snd-soc-max9877-objs := max9877.o
@ -415,6 +418,7 @@ obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o
obj-$(CONFIG_SND_SOC_MAX98373) += snd-soc-max98373.o
obj-$(CONFIG_SND_SOC_MAX98390) += snd-soc-max98390.o
obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o
obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
@ -478,6 +482,7 @@ obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o
obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o
obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o
obj-$(CONFIG_SND_SOC_RT5682) += snd-soc-rt5682.o
obj-$(CONFIG_SND_SOC_RT5682_I2C) += snd-soc-rt5682-i2c.o
obj-$(CONFIG_SND_SOC_RT5682_SDW) += snd-soc-rt5682-sdw.o
obj-$(CONFIG_SND_SOC_RT700) += snd-soc-rt700.o
obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o
@ -588,6 +593,7 @@ obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o
obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o
obj-$(CONFIG_SND_SOC_ZL38060) += snd-soc-zl38060.o
obj-$(CONFIG_SND_SOC_ZX_AUD96P22) += snd-soc-zx-aud96p22.o
# Amp

View File

@ -2,7 +2,7 @@
/*
* ad1980.c -- ALSA Soc AD1980 codec support
*
* Copyright: Analog Device Inc.
* Copyright: Analog Devices Inc.
* Author: Roy Huang <roy.huang@analog.com>
* Cliff Cai <cliff.cai@analog.com>
*/

View File

@ -2,7 +2,7 @@
/*
* ad73311.c -- ALSA Soc AD73311 codec support
*
* Copyright: Analog Device Inc.
* Copyright: Analog Devices Inc.
* Author: Cliff Cai <cliff.cai@analog.com>
*/

View File

@ -725,7 +725,7 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component;
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
if (!snd_soc_component_is_active(component) || !adav80x->rate)
if (!snd_soc_component_active(component) || !adav80x->rate)
return 0;
return snd_pcm_hw_constraint_single(substream->runtime,
@ -738,7 +738,7 @@ static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component;
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
if (!snd_soc_component_is_active(component))
if (!snd_soc_component_active(component))
adav80x->rate = 0;
}

View File

@ -1926,7 +1926,7 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
if (clk_id == dai_priv->clk)
return 0;
if (dai->active) {
if (snd_soc_dai_active(dai)) {
dev_err(component->dev, "Can't change clock on active DAI %d\n",
dai->id);
return -EBUSY;

View File

@ -8,7 +8,6 @@
* EC for audio function.
*/
#include <crypto/hash.h>
#include <crypto/sha.h>
#include <linux/acpi.h>
#include <linux/delay.h>
@ -107,24 +106,11 @@ error:
static int calculate_sha256(struct cros_ec_codec_priv *priv,
uint8_t *buf, uint32_t size, uint8_t *digest)
{
struct crypto_shash *tfm;
struct sha256_state sctx;
tfm = crypto_alloc_shash("sha256", CRYPTO_ALG_TYPE_SHASH, 0);
if (IS_ERR(tfm)) {
dev_err(priv->dev, "can't alloc shash\n");
return PTR_ERR(tfm);
}
{
SHASH_DESC_ON_STACK(desc, tfm);
desc->tfm = tfm;
crypto_shash_digest(desc, buf, size, digest);
shash_desc_zero(desc);
}
crypto_free_shash(tfm);
sha256_init(&sctx);
sha256_update(&sctx, buf, size);
sha256_final(&sctx, digest);
#ifdef DEBUG
{

View File

@ -356,9 +356,9 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
*/
if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
!dai->stream_active[SNDRV_PCM_STREAM_CAPTURE]) ||
!snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE)) ||
(substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
!dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK])) {
!snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK))) {
ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
CS4271_MODE2_PDN,
CS4271_MODE2_PDN);

View File

@ -1229,11 +1229,10 @@ static struct snd_soc_dai_driver cs47l15_dai[] = {
},
};
static int cs47l15_open(struct snd_compr_stream *stream)
static int cs47l15_open(struct snd_soc_component *component,
struct snd_compr_stream *stream)
{
struct snd_soc_pcm_runtime *rtd = stream->private_data;
struct snd_soc_component *component =
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
struct madera_priv *priv = &cs47l15->core;
struct madera *madera = priv->madera;
@ -1329,7 +1328,7 @@ static unsigned int cs47l15_digital_vu[] = {
MADERA_DAC_DIGITAL_VOLUME_5R,
};
static const struct snd_compr_ops cs47l15_compr_ops = {
static const struct snd_compress_ops cs47l15_compress_ops = {
.open = &cs47l15_open,
.free = &wm_adsp_compr_free,
.set_params = &wm_adsp_compr_set_params,
@ -1345,7 +1344,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l15 = {
.set_sysclk = &madera_set_sysclk,
.set_pll = &cs47l15_set_fll,
.name = DRV_NAME,
.compr_ops = &cs47l15_compr_ops,
.compress_ops = &cs47l15_compress_ops,
.controls = cs47l15_snd_controls,
.num_controls = ARRAY_SIZE(cs47l15_snd_controls),
.dapm_widgets = cs47l15_dapm_widgets,

View File

@ -1068,10 +1068,10 @@ static struct snd_soc_dai_driver cs47l24_dai[] = {
},
};
static int cs47l24_open(struct snd_compr_stream *stream)
static int cs47l24_open(struct snd_soc_component *component,
struct snd_compr_stream *stream)
{
struct snd_soc_pcm_runtime *rtd = stream->private_data;
struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct cs47l24_priv *priv = snd_soc_component_get_drvdata(component);
struct arizona *arizona = priv->core.arizona;
int n_adsp;
@ -1178,7 +1178,7 @@ static unsigned int cs47l24_digital_vu[] = {
ARIZONA_DAC_DIGITAL_VOLUME_4L,
};
static struct snd_compr_ops cs47l24_compr_ops = {
static struct snd_compress_ops cs47l24_compress_ops = {
.open = cs47l24_open,
.free = wm_adsp_compr_free,
.set_params = wm_adsp_compr_set_params,
@ -1194,7 +1194,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l24 = {
.set_sysclk = arizona_set_sysclk,
.set_pll = cs47l24_set_fll,
.name = DRV_NAME,
.compr_ops = &cs47l24_compr_ops,
.compress_ops = &cs47l24_compress_ops,
.controls = cs47l24_snd_controls,
.num_controls = ARRAY_SIZE(cs47l24_snd_controls),
.dapm_widgets = cs47l24_dapm_widgets,

View File

@ -1504,11 +1504,10 @@ static struct snd_soc_dai_driver cs47l35_dai[] = {
},
};
static int cs47l35_open(struct snd_compr_stream *stream)
static int cs47l35_open(struct snd_soc_component *component,
struct snd_compr_stream *stream)
{
struct snd_soc_pcm_runtime *rtd = stream->private_data;
struct snd_soc_component *component =
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct cs47l35 *cs47l35 = snd_soc_component_get_drvdata(component);
struct madera_priv *priv = &cs47l35->core;
struct madera *madera = priv->madera;
@ -1622,7 +1621,7 @@ static unsigned int cs47l35_digital_vu[] = {
MADERA_DAC_DIGITAL_VOLUME_5R,
};
static const struct snd_compr_ops cs47l35_compr_ops = {
static const struct snd_compress_ops cs47l35_compress_ops = {
.open = &cs47l35_open,
.free = &wm_adsp_compr_free,
.set_params = &wm_adsp_compr_set_params,
@ -1638,7 +1637,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l35 = {
.set_sysclk = &madera_set_sysclk,
.set_pll = &cs47l35_set_fll,
.name = DRV_NAME,
.compr_ops = &cs47l35_compr_ops,
.compress_ops = &cs47l35_compress_ops,
.controls = cs47l35_snd_controls,
.num_controls = ARRAY_SIZE(cs47l35_snd_controls),
.dapm_widgets = cs47l35_dapm_widgets,

View File

@ -2447,11 +2447,10 @@ static struct snd_soc_dai_driver cs47l85_dai[] = {
},
};
static int cs47l85_open(struct snd_compr_stream *stream)
static int cs47l85_open(struct snd_soc_component *component,
struct snd_compr_stream *stream)
{
struct snd_soc_pcm_runtime *rtd = stream->private_data;
struct snd_soc_component *component =
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct cs47l85 *cs47l85 = snd_soc_component_get_drvdata(component);
struct madera_priv *priv = &cs47l85->core;
struct madera *madera = priv->madera;
@ -2566,7 +2565,7 @@ static const unsigned int cs47l85_digital_vu[] = {
MADERA_DAC_DIGITAL_VOLUME_6R,
};
static const struct snd_compr_ops cs47l85_compr_ops = {
static const struct snd_compress_ops cs47l85_compress_ops = {
.open = &cs47l85_open,
.free = &wm_adsp_compr_free,
.set_params = &wm_adsp_compr_set_params,
@ -2582,7 +2581,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l85 = {
.set_sysclk = &madera_set_sysclk,
.set_pll = &cs47l85_set_fll,
.name = DRV_NAME,
.compr_ops = &cs47l85_compr_ops,
.compress_ops = &cs47l85_compress_ops,
.controls = cs47l85_snd_controls,
.num_controls = ARRAY_SIZE(cs47l85_snd_controls),
.dapm_widgets = cs47l85_dapm_widgets,

View File

@ -2358,11 +2358,10 @@ static struct snd_soc_dai_driver cs47l90_dai[] = {
},
};
static int cs47l90_open(struct snd_compr_stream *stream)
static int cs47l90_open(struct snd_soc_component *component,
struct snd_compr_stream *stream)
{
struct snd_soc_pcm_runtime *rtd = stream->private_data;
struct snd_soc_component *component =
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct cs47l90 *cs47l90 = snd_soc_component_get_drvdata(component);
struct madera_priv *priv = &cs47l90->core;
struct madera *madera = priv->madera;
@ -2473,7 +2472,7 @@ static unsigned int cs47l90_digital_vu[] = {
MADERA_DAC_DIGITAL_VOLUME_5R,
};
static const struct snd_compr_ops cs47l90_compr_ops = {
static const struct snd_compress_ops cs47l90_compress_ops = {
.open = &cs47l90_open,
.free = &wm_adsp_compr_free,
.set_params = &wm_adsp_compr_set_params,
@ -2489,7 +2488,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l90 = {
.set_sysclk = &madera_set_sysclk,
.set_pll = &cs47l90_set_fll,
.name = DRV_NAME,
.compr_ops = &cs47l90_compr_ops,
.compress_ops = &cs47l90_compress_ops,
.controls = cs47l90_snd_controls,
.num_controls = ARRAY_SIZE(cs47l90_snd_controls),
.dapm_widgets = cs47l90_dapm_widgets,

View File

@ -1830,11 +1830,10 @@ static struct snd_soc_dai_driver cs47l92_dai[] = {
},
};
static int cs47l92_open(struct snd_compr_stream *stream)
static int cs47l92_open(struct snd_soc_component *component,
struct snd_compr_stream *stream)
{
struct snd_soc_pcm_runtime *rtd = stream->private_data;
struct snd_soc_component *component =
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component);
struct madera_priv *priv = &cs47l92->core;
struct madera *madera = priv->madera;
@ -1933,7 +1932,7 @@ static unsigned int cs47l92_digital_vu[] = {
MADERA_DAC_DIGITAL_VOLUME_5R,
};
static const struct snd_compr_ops cs47l92_compr_ops = {
static const struct snd_compress_ops cs47l92_compress_ops = {
.open = &cs47l92_open,
.free = &wm_adsp_compr_free,
.set_params = &wm_adsp_compr_set_params,
@ -1949,7 +1948,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l92 = {
.set_sysclk = &madera_set_sysclk,
.set_pll = &cs47l92_set_fll,
.name = DRV_NAME,
.compr_ops = &cs47l92_compr_ops,
.compress_ops = &cs47l92_compress_ops,
.controls = cs47l92_snd_controls,
.num_controls = ARRAY_SIZE(cs47l92_snd_controls),
.dapm_widgets = cs47l92_dapm_widgets,

View File

@ -19,6 +19,7 @@
#include <linux/module.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <linux/pm_runtime.h>
#include <sound/soc.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@ -806,6 +807,11 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
*/
static const struct snd_soc_dapm_widget da7213_dapm_widgets[] = {
/*
* Power Supply
*/
SND_SOC_DAPM_REGULATOR_SUPPLY("VDDMIC", 0, 0),
/*
* Input & Output
*/
@ -932,6 +938,9 @@ static const struct snd_soc_dapm_route da7213_audio_map[] = {
/* Dest Connecting Widget source */
/* Input path */
{"Mic Bias 1", NULL, "VDDMIC"},
{"Mic Bias 2", NULL, "VDDMIC"},
{"MIC1", NULL, "Mic Bias 1"},
{"MIC2", NULL, "Mic Bias 2"},
@ -1334,10 +1343,10 @@ static int da7213_mute(struct snd_soc_dai *dai, int mute)
#define DA7213_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir)
static int da7213_set_component_sysclk(struct snd_soc_component *component,
int clk_id, int source,
unsigned int freq, int dir)
{
struct snd_soc_component *component = codec_dai->component;
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
int ret = 0;
@ -1345,7 +1354,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
return 0;
if (((freq < 5000000) && (freq != 32768)) || (freq > 54000000)) {
dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
dev_err(component->dev, "Unsupported MCLK value %d\n",
freq);
return -EINVAL;
}
@ -1361,7 +1370,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
DA7213_PLL_MCLK_SQR_EN);
break;
default:
dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
dev_err(component->dev, "Unknown clock source %d\n", clk_id);
return -EINVAL;
}
@ -1371,7 +1380,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
freq = clk_round_rate(da7213->mclk, freq);
ret = clk_set_rate(da7213->mclk, freq);
if (ret) {
dev_err(codec_dai->dev, "Failed to set clock rate %d\n",
dev_err(component->dev, "Failed to set clock rate %d\n",
freq);
return ret;
}
@ -1383,10 +1392,10 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
}
/* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */
static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
int source, unsigned int fref, unsigned int fout)
static int da7213_set_component_pll(struct snd_soc_component *component,
int pll_id, int source,
unsigned int fref, unsigned int fout)
{
struct snd_soc_component *component = codec_dai->component;
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
u8 pll_ctrl, indiv_bits, indiv;
@ -1498,8 +1507,6 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
static const struct snd_soc_dai_ops da7213_dai_ops = {
.hw_params = da7213_hw_params,
.set_fmt = da7213_set_dai_fmt,
.set_sysclk = da7213_set_dai_sysclk,
.set_pll = da7213_set_dai_pll,
.digital_mute = da7213_mute,
};
@ -1571,6 +1578,7 @@ static int da7213_set_bias_level(struct snd_soc_component *component,
#if defined(CONFIG_OF)
/* DT */
static const struct of_device_id da7213_of_match[] = {
{ .compatible = "dlg,da7212", },
{ .compatible = "dlg,da7213", },
{ }
};
@ -1690,6 +1698,8 @@ static int da7213_probe(struct snd_soc_component *component)
{
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
pm_runtime_get_sync(component->dev);
/* Default to using ALC auto offset calibration mode. */
snd_soc_component_update_bits(component, DA7213_ALC_CTRL1,
DA7213_ALC_CALIB_MODE_MAN, 0);
@ -1810,6 +1820,8 @@ static int da7213_probe(struct snd_soc_component *component)
DA7213_DMIC_CLK_RATE_MASK, dmic_cfg);
}
pm_runtime_put_sync(component->dev);
/* Check if MCLK provided */
da7213->mclk = devm_clk_get(component->dev, "mclk");
if (IS_ERR(da7213->mclk)) {
@ -1831,6 +1843,8 @@ static const struct snd_soc_component_driver soc_component_dev_da7213 = {
.num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets),
.dapm_routes = da7213_audio_map,
.num_dapm_routes = ARRAY_SIZE(da7213_audio_map),
.set_sysclk = da7213_set_component_sysclk,
.set_pll = da7213_set_component_pll,
.idle_bias_on = 1,
.use_pmdown_time = 1,
.endianness = 1,
@ -1847,11 +1861,22 @@ static const struct regmap_config da7213_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
static void da7213_power_off(void *data)
{
struct da7213_priv *da7213 = data;
regulator_bulk_disable(DA7213_NUM_SUPPLIES, da7213->supplies);
}
static const char *da7213_supply_names[DA7213_NUM_SUPPLIES] = {
[DA7213_SUPPLY_VDDA] = "VDDA",
[DA7213_SUPPLY_VDDIO] = "VDDIO",
};
static int da7213_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct da7213_priv *da7213;
int ret;
int i, ret;
da7213 = devm_kzalloc(&i2c->dev, sizeof(*da7213), GFP_KERNEL);
if (!da7213)
@ -1859,6 +1884,25 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, da7213);
/* Get required supplies */
for (i = 0; i < DA7213_NUM_SUPPLIES; ++i)
da7213->supplies[i].supply = da7213_supply_names[i];
ret = devm_regulator_bulk_get(&i2c->dev, DA7213_NUM_SUPPLIES,
da7213->supplies);
if (ret) {
dev_err(&i2c->dev, "Failed to get supplies: %d\n", ret);
return ret;
}
ret = regulator_bulk_enable(DA7213_NUM_SUPPLIES, da7213->supplies);
if (ret < 0)
return ret;
ret = devm_add_action_or_reset(&i2c->dev, da7213_power_off, da7213);
if (ret < 0)
return ret;
da7213->regmap = devm_regmap_init_i2c(i2c, &da7213_regmap_config);
if (IS_ERR(da7213->regmap)) {
ret = PTR_ERR(da7213->regmap);
@ -1866,6 +1910,11 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
return ret;
}
pm_runtime_set_autosuspend_delay(&i2c->dev, 100);
pm_runtime_use_autosuspend(&i2c->dev);
pm_runtime_set_active(&i2c->dev);
pm_runtime_enable(&i2c->dev);
ret = devm_snd_soc_register_component(&i2c->dev,
&soc_component_dev_da7213, &da7213_dai, 1);
if (ret < 0) {
@ -1875,6 +1924,34 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
return ret;
}
static int __maybe_unused da7213_runtime_suspend(struct device *dev)
{
struct da7213_priv *da7213 = dev_get_drvdata(dev);
regcache_cache_only(da7213->regmap, true);
regcache_mark_dirty(da7213->regmap);
regulator_bulk_disable(DA7213_NUM_SUPPLIES, da7213->supplies);
return 0;
}
static int __maybe_unused da7213_runtime_resume(struct device *dev)
{
struct da7213_priv *da7213 = dev_get_drvdata(dev);
int ret;
ret = regulator_bulk_enable(DA7213_NUM_SUPPLIES, da7213->supplies);
if (ret < 0)
return ret;
regcache_cache_only(da7213->regmap, false);
regcache_sync(da7213->regmap);
return 0;
}
static const struct dev_pm_ops da7213_pm = {
SET_RUNTIME_PM_OPS(da7213_runtime_suspend, da7213_runtime_resume, NULL)
};
static const struct i2c_device_id da7213_i2c_id[] = {
{ "da7213", 0 },
{ }
@ -1887,6 +1964,7 @@ static struct i2c_driver da7213_i2c_driver = {
.name = "da7213",
.of_match_table = of_match_ptr(da7213_of_match),
.acpi_match_table = ACPI_PTR(da7213_acpi_match),
.pm = &da7213_pm,
},
.probe = da7213_i2c_probe,
.id_table = da7213_i2c_id,

View File

@ -12,6 +12,7 @@
#include <linux/clk.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <sound/da7213.h>
/*
@ -521,9 +522,17 @@ enum da7213_sys_clk {
DA7213_SYSCLK_PLL_32KHZ
};
/* Regulators */
enum da7213_supplies {
DA7213_SUPPLY_VDDA = 0,
DA7213_SUPPLY_VDDIO,
DA7213_NUM_SUPPLIES,
};
/* Codec private data */
struct da7213_priv {
struct regmap *regmap;
struct regulator_bulk_data supplies[DA7213_NUM_SUPPLIES];
struct clk *mclk;
unsigned int mclk_rate;
int clk_src;

View File

@ -59,14 +59,14 @@ static int dmic_aif_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_POST_PMU:
if (dmic->gpio_en)
gpiod_set_value(dmic->gpio_en, 1);
gpiod_set_value_cansleep(dmic->gpio_en, 1);
if (dmic->wakeup_delay)
msleep(dmic->wakeup_delay);
break;
case SND_SOC_DAPM_POST_PMD:
if (dmic->gpio_en)
gpiod_set_value(dmic->gpio_en, 0);
gpiod_set_value_cansleep(dmic->gpio_en, 0);
break;
}

View File

@ -574,19 +574,17 @@ static int jz4725b_codec_probe(struct platform_device *pdev)
return ret;
}
#ifdef CONFIG_OF
static const struct of_device_id jz4725b_codec_of_matches[] = {
{ .compatible = "ingenic,jz4725b-codec", },
{ }
};
MODULE_DEVICE_TABLE(of, jz4725b_codec_of_matches);
#endif
static struct platform_driver jz4725b_codec_driver = {
.probe = jz4725b_codec_probe,
.driver = {
.name = "jz4725b-codec",
.of_match_table = of_match_ptr(jz4725b_codec_of_matches),
.of_match_table = jz4725b_codec_of_matches,
},
};
module_platform_driver(jz4725b_codec_driver);

View File

@ -344,19 +344,17 @@ static int jz4740_codec_probe(struct platform_device *pdev)
return ret;
}
#ifdef CONFIG_OF
static const struct of_device_id jz4740_codec_of_matches[] = {
{ .compatible = "ingenic,jz4740-codec", },
{ }
};
MODULE_DEVICE_TABLE(of, jz4740_codec_of_matches);
#endif
static struct platform_driver jz4740_codec_driver = {
.probe = jz4740_codec_probe,
.driver = {
.name = "jz4740-codec",
.of_match_table = of_match_ptr(jz4740_codec_of_matches),
.of_match_table = jz4740_codec_of_matches,
},
};

View File

@ -937,7 +937,7 @@ static struct platform_driver jz4770_codec_driver = {
.probe = jz4770_codec_probe,
.driver = {
.name = "jz4770-codec",
.of_match_table = of_match_ptr(jz4770_codec_of_matches),
.of_match_table = jz4770_codec_of_matches,
},
};
module_platform_driver(jz4770_codec_driver);

View File

@ -3279,7 +3279,7 @@ static int madera_dai_set_sysclk(struct snd_soc_dai *dai,
if (is_sync == madera_is_syncclk(dai_priv->clk))
return 0;
if (dai->active) {
if (snd_soc_dai_active(dai)) {
dev_err(component->dev, "Can't change clock on active DAI %d\n",
dai->id);
return -EBUSY;

View File

@ -2039,7 +2039,7 @@ static int max98090_dai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
if (!max98090->master && dai->active == 1)
if (!max98090->master && snd_soc_dai_active(dai) == 1)
queue_delayed_work(system_power_efficient_wq,
&max98090->pll_det_enable_work,
msecs_to_jiffies(10));
@ -2047,7 +2047,7 @@ static int max98090_dai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
if (!max98090->master && dai->active == 1)
if (!max98090->master && snd_soc_dai_active(dai) == 1)
schedule_work(&max98090->pll_det_disable_work);
break;
default:
@ -2109,7 +2109,7 @@ static void max98090_pll_work(struct max98090_priv *max98090)
unsigned int pll;
int i;
if (!snd_soc_component_is_active(component))
if (!snd_soc_component_active(component))
return;
dev_info_ratelimited(component->dev, "PLL unlocked\n");

1040
sound/soc/codecs/max98390.c Normal file

File diff suppressed because it is too large Load Diff

663
sound/soc/codecs/max98390.h Normal file
View File

@ -0,0 +1,663 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2020, Maxim Integrated.
*/
#ifndef _MAX98390_H
#define _MAX98390_H
/* MAX98390 Register Address */
#define MAX98390_SOFTWARE_RESET 0x2000
#define MAX98390_INT_RAW1 0x2002
#define MAX98390_INT_RAW2 0x2003
#define MAX98390_INT_RAW3 0x2004
#define MAX98390_INT_STATE1 0x2005
#define MAX98390_INT_STATE2 0x2006
#define MAX98390_INT_STATE3 0x2007
#define MAX98390_INT_FLAG1 0x2008
#define MAX98390_INT_FLAG2 0x2009
#define MAX98390_INT_FLAG3 0x200a
#define MAX98390_INT_EN1 0x200b
#define MAX98390_INT_EN2 0x200c
#define MAX98390_INT_EN3 0x200d
#define MAX98390_INT_FLAG_CLR1 0x200e
#define MAX98390_INT_FLAG_CLR2 0x200f
#define MAX98390_INT_FLAG_CLR3 0x2010
#define MAX98390_IRQ_CTRL 0x2011
#define MAX98390_CLK_MON 0x2012
#define MAX98390_DAT_MON 0x2014
#define MAX98390_WDOG_CTRL 0x2015
#define MAX98390_WDOG_RST 0x2016
#define MAX98390_MEAS_ADC_THERM_WARN_THRESH 0x2017
#define MAX98390_MEAS_ADC_THERM_SHDN_THRESH 0x2018
#define MAX98390_MEAS_ADC_THERM_HYSTERESIS 0x2019
#define MAX98390_PIN_CFG 0x201a
#define MAX98390_PCM_RX_EN_A 0x201b
#define MAX98390_PCM_RX_EN_B 0x201c
#define MAX98390_PCM_TX_EN_A 0x201d
#define MAX98390_PCM_TX_EN_B 0x201e
#define MAX98390_PCM_TX_HIZ_CTRL_A 0x201f
#define MAX98390_PCM_TX_HIZ_CTRL_B 0x2020
#define MAX98390_PCM_CH_SRC_1 0x2021
#define MAX98390_PCM_CH_SRC_2 0x2022
#define MAX98390_PCM_CH_SRC_3 0x2023
#define MAX98390_PCM_MODE_CFG 0x2024
#define MAX98390_PCM_MASTER_MODE 0x2025
#define MAX98390_PCM_CLK_SETUP 0x2026
#define MAX98390_PCM_SR_SETUP 0x2027
#define MAX98390_ICC_RX_EN_A 0x202c
#define MAX98390_ICC_RX_EN_B 0x202d
#define MAX98390_ICC_TX_EN_A 0x202e
#define MAX98390_ICC_TX_EN_B 0x202f
#define MAX98390_ICC_HIZ_MANUAL_MODE 0x2030
#define MAX98390_ICC_TX_HIZ_EN_A 0x2031
#define MAX98390_ICC_TX_HIZ_EN_B 0x2032
#define MAX98390_ICC_LNK_EN 0x2033
#define MAX98390_R2039_AMP_DSP_CFG 0x2039
#define MAX98390_R203A_AMP_EN 0x203a
#define MAX98390_TONE_GEN_DC_CFG 0x203b
#define MAX98390_SPK_SRC_SEL 0x203c
#define MAX98390_R203D_SPK_GAIN 0x203d
#define MAX98390_SSM_CFG 0x203e
#define MAX98390_MEAS_EN 0x203f
#define MAX98390_MEAS_DSP_CFG 0x2040
#define MAX98390_BOOST_CTRL0 0x2041
#define MAX98390_BOOST_CTRL3 0x2042
#define MAX98390_BOOST_CTRL1 0x2043
#define MAX98390_MEAS_ADC_CFG 0x2044
#define MAX98390_MEAS_ADC_BASE_MSB 0x2045
#define MAX98390_MEAS_ADC_BASE_LSB 0x2046
#define MAX98390_ADC_CH0_DIVIDE 0x2047
#define MAX98390_ADC_CH1_DIVIDE 0x2048
#define MAX98390_ADC_CH2_DIVIDE 0x2049
#define MAX98390_ADC_CH0_FILT_CFG 0x204a
#define MAX98390_ADC_CH1_FILT_CFG 0x204b
#define MAX98390_ADC_CH2_FILT_CFG 0x204c
#define MAX98390_MEAS_ADC_CH0_READ 0x204d
#define MAX98390_MEAS_ADC_CH1_READ 0x204e
#define MAX98390_MEAS_ADC_CH2_READ 0x204f
#define MAX98390_PWR_GATE_CTL 0x2050
#define MAX98390_PWR_GATE_STATUS 0x2051
#define MAX98390_VBAT_LOW_STATUS 0x2052
#define MAX98390_PVDD_LOW_STATUS 0x2053
#define MAX98390_BROWNOUT_STATUS 0x2054
#define MAX98390_BROWNOUT_EN 0x2055
#define MAX98390_BROWNOUT_INFINITE_HOLD 0x2056
#define MAX98390_BROWNOUT_INFINITE_HOLD_CLR 0x2057
#define MAX98390_BROWNOUT_LVL_HOLD 0x2058
#define MAX98390_BROWNOUT_LVL1_THRESH 0x2059
#define MAX98390_BROWNOUT_LVL2_THRESH 0x205a
#define MAX98390_BROWNOUT_LVL3_THRESH 0x205b
#define MAX98390_BROWNOUT_LVL4_THRESH 0x205c
#define MAX98390_BROWNOUT_THRESH_HYSTERYSIS 0x205d
#define MAX98390_BROWNOUT_AMP_LIMITER_ATK_REL 0x205e
#define MAX98390_BROWNOUT_AMP_GAIN_ATK_REL 0x205f
#define MAX98390_BROWNOUT_AMP1_CLIP_MODE 0x2060
#define MAX98390_BROWNOUT_LVL1_CUR_LIMIT 0x2061
#define MAX98390_BROWNOUT_LVL1_AMP1_CTRL1 0x2062
#define MAX98390_BROWNOUT_LVL1_AMP1_CTRL2 0x2063
#define MAX98390_BROWNOUT_LVL1_AMP1_CTRL3 0x2064
#define MAX98390_BROWNOUT_LVL2_CUR_LIMIT 0x2065
#define MAX98390_BROWNOUT_LVL2_AMP1_CTRL1 0x2066
#define MAX98390_BROWNOUT_LVL2_AMP1_CTRL2 0x2067
#define MAX98390_BROWNOUT_LVL2_AMP1_CTRL3 0x2068
#define MAX98390_BROWNOUT_LVL3_CUR_LIMIT 0x2069
#define MAX98390_BROWNOUT_LVL3_AMP1_CTRL1 0x206a
#define MAX98390_BROWNOUT_LVL3_AMP1_CTRL2 0x206b
#define MAX98390_BROWNOUT_LVL3_AMP1_CTRL3 0x206c
#define MAX98390_BROWNOUT_LVL4_CUR_LIMIT 0x206d
#define MAX98390_BROWNOUT_LVL4_AMP1_CTRL1 0x206e
#define MAX98390_BROWNOUT_LVL4_AMP1_CTRL2 0x206f
#define MAX98390_BROWNOUT_LVL4_AMP1_CTRL3 0x2070
#define MAX98390_BROWNOUT_LOWEST_STATUS 0x2071
#define MAX98390_BROWNOUT_ILIM_HLD 0x2072
#define MAX98390_BROWNOUT_LIM_HLD 0x2073
#define MAX98390_BROWNOUT_CLIP_HLD 0x2074
#define MAX98390_BROWNOUT_GAIN_HLD 0x2075
#define MAX98390_ENV_TRACK_VOUT_HEADROOM 0x2076
#define MAX98390_ENV_TRACK_BOOST_VOUT_DELAY 0x2077
#define MAX98390_ENV_TRACK_REL_RATE 0x2078
#define MAX98390_ENV_TRACK_HOLD_RATE 0x2079
#define MAX98390_ENV_TRACK_CTRL 0x207a
#define MAX98390_ENV_TRACK_BOOST_VOUT_READ 0x207b
#define MAX98390_BOOST_BYPASS1 0x207c
#define MAX98390_BOOST_BYPASS2 0x207d
#define MAX98390_BOOST_BYPASS3 0x207e
#define MAX98390_FET_SCALING1 0x207f
#define MAX98390_FET_SCALING2 0x2080
#define MAX98390_FET_SCALING3 0x2081
#define MAX98390_FET_SCALING4 0x2082
#define MAX98390_SPK_SPEEDUP 0x2084
#define DSM_STBASS_HPF_B0_BYTE0 0x2101
#define DSM_STBASS_HPF_B0_BYTE1 0x2102
#define DSM_STBASS_HPF_B0_BYTE2 0x2103
#define DSM_STBASS_HPF_B1_BYTE0 0x2105
#define DSM_STBASS_HPF_B1_BYTE1 0x2106
#define DSM_STBASS_HPF_B1_BYTE2 0x2107
#define DSM_STBASS_HPF_B2_BYTE0 0x2109
#define DSM_STBASS_HPF_B2_BYTE1 0x210a
#define DSM_STBASS_HPF_B2_BYTE2 0x210b
#define DSM_STBASS_HPF_A1_BYTE0 0x210d
#define DSM_STBASS_HPF_A1_BYTE1 0x210e
#define DSM_STBASS_HPF_A1_BYTE2 0x210f
#define DSM_STBASS_HPF_A2_BYTE0 0x2111
#define DSM_STBASS_HPF_A2_BYTE1 0x2112
#define DSM_STBASS_HPF_A2_BYTE2 0x2113
#define DSM_STBASS_LPF_B0_BYTE0 0x2115
#define DSM_STBASS_LPF_B0_BYTE1 0x2116
#define DSM_STBASS_LPF_B0_BYTE2 0x2117
#define DSM_STBASS_LPF_B1_BYTE0 0x2119
#define DSM_STBASS_LPF_B1_BYTE1 0x211a
#define DSM_STBASS_LPF_B1_BYTE2 0x211b
#define DSM_STBASS_LPF_B2_BYTE0 0x211d
#define DSM_STBASS_LPF_B2_BYTE1 0x211e
#define DSM_STBASS_LPF_B2_BYTE2 0x211f
#define DSM_STBASS_LPF_A1_BYTE0 0x2121
#define DSM_STBASS_LPF_A1_BYTE1 0x2122
#define DSM_STBASS_LPF_A1_BYTE2 0x2123
#define DSM_STBASS_LPF_A2_BYTE0 0x2125
#define DSM_STBASS_LPF_A2_BYTE1 0x2126
#define DSM_STBASS_LPF_A2_BYTE2 0x2127
#define DSM_EQ_BQ1_B0_BYTE0 0x2129
#define DSM_EQ_BQ1_B0_BYTE1 0x212a
#define DSM_EQ_BQ1_B0_BYTE2 0x212b
#define DSM_EQ_BQ1_B1_BYTE0 0x212d
#define DSM_EQ_BQ1_B1_BYTE1 0x212e
#define DSM_EQ_BQ1_B1_BYTE2 0x212f
#define DSM_EQ_BQ1_B2_BYTE0 0x2131
#define DSM_EQ_BQ1_B2_BYTE1 0x2132
#define DSM_EQ_BQ1_B2_BYTE2 0x2133
#define DSM_EQ_BQ1_A1_BYTE0 0x2135
#define DSM_EQ_BQ1_A1_BYTE1 0x2136
#define DSM_EQ_BQ1_A1_BYTE2 0x2137
#define DSM_EQ_BQ1_A2_BYTE0 0x2139
#define DSM_EQ_BQ1_A2_BYTE1 0x213a
#define DSM_EQ_BQ1_A2_BYTE2 0x213b
#define DSM_EQ_BQ2_B0_BYTE0 0x213d
#define DSM_EQ_BQ2_B0_BYTE1 0x213e
#define DSM_EQ_BQ2_B0_BYTE2 0x213f
#define DSM_EQ_BQ2_B1_BYTE0 0x2141
#define DSM_EQ_BQ2_B1_BYTE1 0x2142
#define DSM_EQ_BQ2_B1_BYTE2 0x2143
#define DSM_EQ_BQ2_B2_BYTE0 0x2145
#define DSM_EQ_BQ2_B2_BYTE1 0x2146
#define DSM_EQ_BQ2_B2_BYTE2 0x2147
#define DSM_EQ_BQ2_A1_BYTE0 0x2149
#define DSM_EQ_BQ2_A1_BYTE1 0x214a
#define DSM_EQ_BQ2_A1_BYTE2 0x214b
#define DSM_EQ_BQ2_A2_BYTE0 0x214d
#define DSM_EQ_BQ2_A2_BYTE1 0x214e
#define DSM_EQ_BQ2_A2_BYTE2 0x214f
#define DSM_EQ_BQ3_B0_BYTE0 0x2151
#define DSM_EQ_BQ3_B0_BYTE1 0x2152
#define DSM_EQ_BQ3_B0_BYTE2 0x2153
#define DSM_EQ_BQ3_B1_BYTE0 0x2155
#define DSM_EQ_BQ3_B1_BYTE1 0x2156
#define DSM_EQ_BQ3_B1_BYTE2 0x2157
#define DSM_EQ_BQ3_B2_BYTE0 0x2159
#define DSM_EQ_BQ3_B2_BYTE1 0x215a
#define DSM_EQ_BQ3_B2_BYTE2 0x215b
#define DSM_EQ_BQ3_A1_BYTE0 0x215d
#define DSM_EQ_BQ3_A1_BYTE1 0x215e
#define DSM_EQ_BQ3_A1_BYTE2 0x215f
#define DSM_EQ_BQ3_A2_BYTE0 0x2161
#define DSM_EQ_BQ3_A2_BYTE1 0x2162
#define DSM_EQ_BQ3_A2_BYTE2 0x2163
#define DSM_EQ_BQ4_B0_BYTE0 0x2165
#define DSM_EQ_BQ4_B0_BYTE1 0x2166
#define DSM_EQ_BQ4_B0_BYTE2 0x2167
#define DSM_EQ_BQ4_B1_BYTE0 0x2169
#define DSM_EQ_BQ4_B1_BYTE1 0x216a
#define DSM_EQ_BQ4_B1_BYTE2 0x216b
#define DSM_EQ_BQ4_B2_BYTE0 0x216d
#define DSM_EQ_BQ4_B2_BYTE1 0x216e
#define DSM_EQ_BQ4_B2_BYTE2 0x216f
#define DSM_EQ_BQ4_A1_BYTE0 0x2171
#define DSM_EQ_BQ4_A1_BYTE1 0x2172
#define DSM_EQ_BQ4_A1_BYTE2 0x2173
#define DSM_EQ_BQ4_A2_BYTE0 0x2175
#define DSM_EQ_BQ4_A2_BYTE1 0x2176
#define DSM_EQ_BQ4_A2_BYTE2 0x2177
#define DSM_EQ_BQ5_B0_BYTE0 0x2179
#define DSM_EQ_BQ5_B0_BYTE1 0x217a
#define DSM_EQ_BQ5_B0_BYTE2 0x217b
#define DSM_EQ_BQ5_B1_BYTE0 0x217d
#define DSM_EQ_BQ5_B1_BYTE1 0x217e
#define DSM_EQ_BQ5_B1_BYTE2 0x217f
#define DSM_EQ_BQ5_B2_BYTE0 0x2181
#define DSM_EQ_BQ5_B2_BYTE1 0x2182
#define DSM_EQ_BQ5_B2_BYTE2 0x2183
#define DSM_EQ_BQ5_A1_BYTE0 0x2185
#define DSM_EQ_BQ5_A1_BYTE1 0x2186
#define DSM_EQ_BQ5_A1_BYTE2 0x2187
#define DSM_EQ_BQ5_A2_BYTE0 0x2189
#define DSM_EQ_BQ5_A2_BYTE1 0x218a
#define DSM_EQ_BQ5_A2_BYTE2 0x218b
#define DSM_EQ_BQ6_B0_BYTE0 0x218d
#define DSM_EQ_BQ6_B0_BYTE1 0x218e
#define DSM_EQ_BQ6_B0_BYTE2 0x218f
#define DSM_EQ_BQ6_B1_BYTE0 0x2191
#define DSM_EQ_BQ6_B1_BYTE1 0x2192
#define DSM_EQ_BQ6_B1_BYTE2 0x2193
#define DSM_EQ_BQ6_B2_BYTE0 0x2195
#define DSM_EQ_BQ6_B2_BYTE1 0x2196
#define DSM_EQ_BQ6_B2_BYTE2 0x2197
#define DSM_EQ_BQ6_A1_BYTE0 0x2199
#define DSM_EQ_BQ6_A1_BYTE1 0x219a
#define DSM_EQ_BQ6_A1_BYTE2 0x219b
#define DSM_EQ_BQ6_A2_BYTE0 0x219d
#define DSM_EQ_BQ6_A2_BYTE1 0x219e
#define DSM_EQ_BQ6_A2_BYTE2 0x219f
#define DSM_EQ_BQ7_B0_BYTE0 0x21a1
#define DSM_EQ_BQ7_B0_BYTE1 0x21a2
#define DSM_EQ_BQ7_B0_BYTE2 0x21a3
#define DSM_EQ_BQ7_B1_BYTE0 0x21a5
#define DSM_EQ_BQ7_B1_BYTE1 0x21a6
#define DSM_EQ_BQ7_B1_BYTE2 0x21a7
#define DSM_EQ_BQ7_B2_BYTE0 0x21a9
#define DSM_EQ_BQ7_B2_BYTE1 0x21aa
#define DSM_EQ_BQ7_B2_BYTE2 0x21ab
#define DSM_EQ_BQ7_A1_BYTE0 0x21ad
#define DSM_EQ_BQ7_A1_BYTE1 0x21ae
#define DSM_EQ_BQ7_A1_BYTE2 0x21af
#define DSM_EQ_BQ7_A2_BYTE0 0x21b1
#define DSM_EQ_BQ7_A2_BYTE1 0x21b2
#define DSM_EQ_BQ7_A2_BYTE2 0x21b3
#define DSM_EQ_BQ8_B0_BYTE0 0x21b5
#define DSM_EQ_BQ8_B0_BYTE1 0x21b6
#define DSM_EQ_BQ8_B0_BYTE2 0x21b7
#define DSM_EQ_BQ8_B1_BYTE0 0x21b9
#define DSM_EQ_BQ8_B1_BYTE1 0x21ba
#define DSM_EQ_BQ8_B1_BYTE2 0x21bb
#define DSM_EQ_BQ8_B2_BYTE0 0x21bd
#define DSM_EQ_BQ8_B2_BYTE1 0x21be
#define DSM_EQ_BQ8_B2_BYTE2 0x21bf
#define DSM_EQ_BQ8_A1_BYTE0 0x21c1
#define DSM_EQ_BQ8_A1_BYTE1 0x21c2
#define DSM_EQ_BQ8_A1_BYTE2 0x21c3
#define DSM_EQ_BQ8_A2_BYTE0 0x21c5
#define DSM_EQ_BQ8_A2_BYTE1 0x21c6
#define DSM_EQ_BQ8_A2_BYTE2 0x21c7
#define DSM_LFX_BQ_B0_BYTE0 0x21c9
#define DSM_LFX_BQ_B0_BYTE1 0x21ca
#define DSM_LFX_BQ_B0_BYTE2 0x21cb
#define DSM_LFX_BQ_B1_BYTE0 0x21cd
#define DSM_LFX_BQ_B1_BYTE1 0x21ce
#define DSM_LFX_BQ_B1_BYTE2 0x21cf
#define DSM_LFX_BQ_B2_BYTE0 0x21d1
#define DSM_LFX_BQ_B2_BYTE1 0x21d2
#define DSM_LFX_BQ_B2_BYTE2 0x21d3
#define DSM_LFX_BQ_A1_BYTE0 0x21d5
#define DSM_LFX_BQ_A1_BYTE1 0x21d6
#define DSM_LFX_BQ_A1_BYTE2 0x21d7
#define DSM_LFX_BQ_A2_BYTE0 0x21d9
#define DSM_LFX_BQ_A2_BYTE1 0x21da
#define DSM_LFX_BQ_A2_BYTE2 0x21db
#define DSM_PPR_HPF_B0_BYTE0 0x21dd
#define DSM_PPR_HPF_B0_BYTE1 0x21de
#define DSM_PPR_HPF_B0_BYTE2 0x21df
#define DSM_PPR_HPF_B1_BYTE0 0x21e1
#define DSM_PPR_HPF_B1_BYTE1 0x21e2
#define DSM_PPR_HPF_B1_BYTE2 0x21e3
#define DSM_PPR_HPF_B2_BYTE0 0x21e5
#define DSM_PPR_HPF_B2_BYTE1 0x21e6
#define DSM_PPR_HPF_B2_BYTE2 0x21e7
#define DSM_PPR_HPF_A1_BYTE0 0x21e9
#define DSM_PPR_HPF_A1_BYTE1 0x21ea
#define DSM_PPR_HPF_A1_BYTE2 0x21eb
#define DSM_PPR_HPF_A2_BYTE0 0x21ed
#define DSM_PPR_HPF_A2_BYTE1 0x21ee
#define DSM_PPR_HPF_A2_BYTE2 0x21ef
#define DSM_PPR_LPF_B0_BYTE0 0x21f1
#define DSM_PPR_LPF_B0_BYTE1 0x21f2
#define DSM_PPR_LPF_B0_BYTE2 0x21f3
#define DSM_PPR_LPF_B1_BYTE0 0x21f5
#define DSM_PPR_LPF_B1_BYTE1 0x21f6
#define DSM_PPR_LPF_B1_BYTE2 0x21f7
#define DSM_PPR_LPF_B2_BYTE0 0x21f9
#define DSM_PPR_LPF_B2_BYTE1 0x21fa
#define DSM_PPR_LPF_B2_BYTE2 0x21fb
#define DSM_PPR_LPF_A1_BYTE0 0x21fd
#define DSM_PPR_LPF_A1_BYTE1 0x21fe
#define DSM_PPR_LPF_A1_BYTE2 0x21ff
#define DSM_PPR_LPF_A2_BYTE0 0x2201
#define DSM_PPR_LPF_A2_BYTE1 0x2202
#define DSM_PPR_LPF_A2_BYTE2 0x2203
#define DSM_SPL_BQ_B0_BYTE0 0x2205
#define DSM_SPL_BQ_B0_BYTE1 0x2206
#define DSM_SPL_BQ_B0_BYTE2 0x2207
#define DSM_SPL_BQ_B1_BYTE0 0x2209
#define DSM_SPL_BQ_B1_BYTE1 0x220a
#define DSM_SPL_BQ_B1_BYTE2 0x220b
#define DSM_SPL_BQ_B2_BYTE0 0x220d
#define DSM_SPL_BQ_B2_BYTE1 0x220e
#define DSM_SPL_BQ_B2_BYTE2 0x220f
#define DSM_SPL_BQ_A1_BYTE0 0x2211
#define DSM_SPL_BQ_A1_BYTE1 0x2212
#define DSM_SPL_BQ_A1_BYTE2 0x2213
#define DSM_SPL_BQ_A2_BYTE0 0x2215
#define DSM_SPL_BQ_A2_BYTE1 0x2216
#define DSM_SPL_BQ_A2_BYTE2 0x2217
#define DSM_EXCUR_BQ_B0_BYTE0 0x2219
#define DSM_EXCUR_BQ_B0_BYTE1 0x221a
#define DSM_EXCUR_BQ_B0_BYTE2 0x221b
#define DSM_EXCUR_BQ_B1_BYTE0 0x221d
#define DSM_EXCUR_BQ_B1_BYTE1 0x221e
#define DSM_EXCUR_BQ_B1_BYTE2 0x221f
#define DSM_EXCUR_BQ_B2_BYTE0 0x2221
#define DSM_EXCUR_BQ_B2_BYTE1 0x2222
#define DSM_EXCUR_BQ_B2_BYTE2 0x2223
#define DSM_EXCUR_BQ_A1_BYTE0 0x2225
#define DSM_EXCUR_BQ_A1_BYTE1 0x2226
#define DSM_EXCUR_BQ_A1_BYTE2 0x2227
#define DSM_EXCUR_BQ_A2_BYTE0 0x2229
#define DSM_EXCUR_BQ_A2_BYTE1 0x222a
#define DSM_EXCUR_BQ_A2_BYTE2 0x222b
#define DSM_EXCPROT_HPF1_B0_BYTE0 0x222d
#define DSM_EXCPROT_HPF1_B0_BYTE1 0x222e
#define DSM_EXCPROT_HPF1_B0_BYTE2 0x222f
#define DSM_EXCPROT_HPF1_B1_BYTE0 0x2231
#define DSM_EXCPROT_HPF1_B1_BYTE1 0x2232
#define DSM_EXCPROT_HPF1_B1_BYTE2 0x2233
#define DSM_EXCPROT_HPF1_B2_BYTE0 0x2235
#define DSM_EXCPROT_HPF1_B2_BYTE1 0x2236
#define DSM_EXCPROT_HPF1_B2_BYTE2 0x2237
#define DSM_EXCPROT_HPF1_A1_BYTE0 0x2239
#define DSM_EXCPROT_HPF1_A1_BYTE1 0x223a
#define DSM_EXCPROT_HPF1_A1_BYTE2 0x223b
#define DSM_EXCPROT_HPF1_A2_BYTE0 0x223d
#define DSM_EXCPROT_HPF1_A2_BYTE1 0x223e
#define DSM_EXCPROT_HPF1_A2_BYTE2 0x223f
#define DSM_EXCPROT_HPF2_B0_BYTE0 0x2241
#define DSM_EXCPROT_HPF2_B0_BYTE1 0x2242
#define DSM_EXCPROT_HPF2_B0_BYTE2 0x2243
#define DSM_EXCPROT_HPF2_B1_BYTE0 0x2245
#define DSM_EXCPROT_HPF2_B1_BYTE1 0x2246
#define DSM_EXCPROT_HPF2_B1_BYTE2 0x2247
#define DSM_EXCPROT_HPF2_B2_BYTE0 0x2249
#define DSM_EXCPROT_HPF2_B2_BYTE1 0x224a
#define DSM_EXCPROT_HPF2_B2_BYTE2 0x224b
#define DSM_EXCPROT_HPF2_A1_BYTE0 0x224d
#define DSM_EXCPROT_HPF2_A1_BYTE1 0x224e
#define DSM_EXCPROT_HPF2_A1_BYTE2 0x224f
#define DSM_EXCPROT_HPF2_A2_BYTE0 0x2251
#define DSM_EXCPROT_HPF2_A2_BYTE1 0x2252
#define DSM_EXCPROT_HPF2_A2_BYTE2 0x2253
#define DSM_EXCPROT_HPF3_B0_BYTE0 0x2255
#define DSM_EXCPROT_HPF3_B0_BYTE1 0x2256
#define DSM_EXCPROT_HPF3_B0_BYTE2 0x2257
#define DSM_EXCPROT_HPF3_B1_BYTE0 0x2259
#define DSM_EXCPROT_HPF3_B1_BYTE1 0x225a
#define DSM_EXCPROT_HPF3_B1_BYTE2 0x225b
#define DSM_EXCPROT_HPF3_B2_BYTE0 0x225d
#define DSM_EXCPROT_HPF3_B2_BYTE1 0x225e
#define DSM_EXCPROT_HPF3_B2_BYTE2 0x225f
#define DSM_EXCPROT_HPF3_A1_BYTE0 0x2261
#define DSM_EXCPROT_HPF3_A1_BYTE1 0x2262
#define DSM_EXCPROT_HPF3_A1_BYTE2 0x2263
#define DSM_EXCPROT_HPF3_A2_BYTE0 0x2265
#define DSM_EXCPROT_HPF3_A2_BYTE1 0x2266
#define DSM_EXCPROT_HPF3_A2_BYTE2 0x2267
#define DSM_EXCPROT_HPF4_B0_BYTE0 0x2269
#define DSM_EXCPROT_HPF4_B0_BYTE1 0x226a
#define DSM_EXCPROT_HPF4_B0_BYTE2 0x226b
#define DSM_EXCPROT_HPF4_B1_BYTE0 0x226d
#define DSM_EXCPROT_HPF4_B1_BYTE1 0x226e
#define DSM_EXCPROT_HPF4_B1_BYTE2 0x226f
#define DSM_EXCPROT_HPF4_B2_BYTE0 0x2271
#define DSM_EXCPROT_HPF4_B2_BYTE1 0x2272
#define DSM_EXCPROT_HPF4_B2_BYTE2 0x2273
#define DSM_EXCPROT_HPF4_A1_BYTE0 0x2275
#define DSM_EXCPROT_HPF4_A1_BYTE1 0x2276
#define DSM_EXCPROT_HPF4_A1_BYTE2 0x2277
#define DSM_EXCPROT_HPF4_A2_BYTE0 0x2279
#define DSM_EXCPROT_HPF4_A2_BYTE1 0x227a
#define DSM_EXCPROT_HPF4_A2_BYTE2 0x227b
#define DSM_EXCPROT_HPF5_B0_BYTE0 0x227d
#define DSM_EXCPROT_HPF5_B0_BYTE1 0x227e
#define DSM_EXCPROT_HPF5_B0_BYTE2 0x227f
#define DSM_EXCPROT_HPF5_B1_BYTE0 0x2281
#define DSM_EXCPROT_HPF5_B1_BYTE1 0x2282
#define DSM_EXCPROT_HPF5_B1_BYTE2 0x2283
#define DSM_EXCPROT_HPF5_B2_BYTE0 0x2285
#define DSM_EXCPROT_HPF5_B2_BYTE1 0x2286
#define DSM_EXCPROT_HPF5_B2_BYTE2 0x2287
#define DSM_EXCPROT_HPF5_A1_BYTE0 0x2289
#define DSM_EXCPROT_HPF5_A1_BYTE1 0x228a
#define DSM_EXCPROT_HPF5_A1_BYTE2 0x228b
#define DSM_EXCPROT_HPF5_A2_BYTE0 0x228d
#define DSM_EXCPROT_HPF5_A2_BYTE1 0x228e
#define DSM_EXCPROT_HPF5_A2_BYTE2 0x228f
#define DSM_DEBUZZ_BPF_B0_BYTE0 0x2291
#define DSM_DEBUZZ_BPF_B0_BYTE1 0x2292
#define DSM_DEBUZZ_BPF_B0_BYTE2 0x2293
#define DSM_DEBUZZ_BPF_B1_BYTE0 0x2295
#define DSM_DEBUZZ_BPF_B1_BYTE1 0x2296
#define DSM_DEBUZZ_BPF_B1_BYTE2 0x2297
#define DSM_DEBUZZ_BPF_B2_BYTE0 0x2299
#define DSM_DEBUZZ_BPF_B2_BYTE1 0x229a
#define DSM_DEBUZZ_BPF_B2_BYTE2 0x229b
#define DSM_DEBUZZ_BPF_A1_BYTE0 0x229d
#define DSM_DEBUZZ_BPF_A1_BYTE1 0x229e
#define DSM_DEBUZZ_BPF_A1_BYTE2 0x229f
#define DSM_DEBUZZ_BPF_A2_BYTE0 0x22a1
#define DSM_DEBUZZ_BPF_A2_BYTE1 0x22a2
#define DSM_DEBUZZ_BPF_A2_BYTE2 0x22a3
#define DSM_DEBUZZ_PORT_B0_BYTE0 0x22a5
#define DSM_DEBUZZ_PORT_B0_BYTE1 0x22a6
#define DSM_DEBUZZ_PORT_B0_BYTE2 0x22a7
#define DSM_DEBUZZ_PORT_B1_BYTE0 0x22a9
#define DSM_DEBUZZ_PORT_B1_BYTE1 0x22aa
#define DSM_DEBUZZ_PORT_B1_BYTE2 0x22ab
#define DSM_DEBUZZ_PORT_B2_BYTE0 0x22ad
#define DSM_DEBUZZ_PORT_B2_BYTE1 0x22ae
#define DSM_DEBUZZ_PORT_B2_BYTE2 0x22af
#define DSM_DEBUZZ_PORT_A1_BYTE0 0x22b1
#define DSM_DEBUZZ_PORT_A1_BYTE1 0x22b2
#define DSM_DEBUZZ_PORT_A1_BYTE2 0x22b3
#define DSM_DEBUZZ_PORT_A2_BYTE0 0x22b5
#define DSM_DEBUZZ_PORT_A2_BYTE1 0x22b6
#define DSM_DEBUZZ_PORT_A2_BYTE2 0x22b7
#define DSM_DEBUZZ_NOTCH_B0_BYTE0 0x22b9
#define DSM_DEBUZZ_NOTCH_B0_BYTE1 0x22ba
#define DSM_DEBUZZ_NOTCH_B0_BYTE2 0x22bb
#define DSM_DEBUZZ_NOTCH_B1_BYTE0 0x22bd
#define DSM_DEBUZZ_NOTCH_B1_BYTE1 0x22be
#define DSM_DEBUZZ_NOTCH_B1_BYTE2 0x22bf
#define DSM_DEBUZZ_NOTCH_B2_BYTE0 0x22c1
#define DSM_DEBUZZ_NOTCH_B2_BYTE1 0x22c2
#define DSM_DEBUZZ_NOTCH_B2_BYTE2 0x22c3
#define DSM_DEBUZZ_NOTCH_A1_BYTE0 0x22c5
#define DSM_DEBUZZ_NOTCH_A1_BYTE1 0x22c6
#define DSM_DEBUZZ_NOTCH_A1_BYTE2 0x22c7
#define DSM_DEBUZZ_NOTCH_A2_BYTE0 0x22c9
#define DSM_DEBUZZ_NOTCH_A2_BYTE1 0x22ca
#define DSM_DEBUZZ_NOTCH_A2_BYTE2 0x22cb
#define DSM_THERMAL_BQ_B0_BYTE0 0x22cd
#define DSM_THERMAL_BQ_B0_BYTE1 0x22ce
#define DSM_THERMAL_BQ_B0_BYTE2 0x22cf
#define DSM_THERMAL_BQ_B1_BYTE0 0x22d1
#define DSM_THERMAL_BQ_B1_BYTE1 0x22d2
#define DSM_THERMAL_BQ_B1_BYTE2 0x22d3
#define DSM_THERMAL_BQ_B2_BYTE0 0x22d5
#define DSM_THERMAL_BQ_B2_BYTE1 0x22d6
#define DSM_THERMAL_BQ_B2_BYTE2 0x22d7
#define DSM_THERMAL_BQ_A1_BYTE0 0x22d9
#define DSM_THERMAL_BQ_A1_BYTE1 0x22da
#define DSM_THERMAL_BQ_A1_BYTE2 0x22db
#define DSM_THERMAL_BQ_A2_BYTE0 0x22dd
#define DSM_THERMAL_BQ_A2_BYTE1 0x22de
#define DSM_THERMAL_BQ_A2_BYTE2 0x22df
#define DSM_WBDRC_FILT1_B0_BYTE0 0x22e1
#define DSM_WBDRC_FILT1_B0_BYTE1 0x22e2
#define DSM_WBDRC_FILT1_B0_BYTE2 0x22e3
#define DSM_WBDRC_FILT1_B1_BYTE0 0x22e5
#define DSM_WBDRC_FILT1_B1_BYTE1 0x22e6
#define DSM_WBDRC_FILT1_B1_BYTE2 0x22e7
#define DSM_WBDRC_FILT1_B2_BYTE0 0x22e9
#define DSM_WBDRC_FILT1_B2_BYTE1 0x22ea
#define DSM_WBDRC_FILT1_B2_BYTE2 0x22eb
#define DSM_WBDRC_FILT1_A1_BYTE0 0x22ed
#define DSM_WBDRC_FILT1_A1_BYTE1 0x22ee
#define DSM_WBDRC_FILT1_A1_BYTE2 0x22ef
#define DSM_WBDRC_FILT1_A2_BYTE0 0x22f1
#define DSM_WBDRC_FILT1_A2_BYTE1 0x22f2
#define DSM_WBDRC_FILT1_A2_BYTE2 0x22f3
#define DSM_WBDRC_FILT2_B0_BYTE0 0x22f5
#define DSM_WBDRC_FILT2_B0_BYTE1 0x22f6
#define DSM_WBDRC_FILT2_B0_BYTE2 0x22f7
#define DSM_WBDRC_FILT2_B1_BYTE0 0x22f9
#define DSM_WBDRC_FILT2_B1_BYTE1 0x22fa
#define DSM_WBDRC_FILT2_B1_BYTE2 0x22fb
#define DSM_WBDRC_FILT2_B2_BYTE0 0x22fd
#define DSM_WBDRC_FILT2_B2_BYTE1 0x22fe
#define DSM_WBDRC_FILT2_B2_BYTE2 0x22ff
#define DSM_WBDRC_FILT2_A1_BYTE0 0x2301
#define DSM_WBDRC_FILT2_A1_BYTE1 0x2302
#define DSM_WBDRC_FILT2_A1_BYTE2 0x2303
#define DSM_WBDRC_FILT2_A2_BYTE0 0x2305
#define DSM_WBDRC_FILT2_A2_BYTE1 0x2306
#define DSM_WBDRC_FILT2_A2_BYTE2 0x2307
#define DSM_PPR_RELEASE_TIME_BYTE0 0x2309
#define DSM_PPR_RELEASE_TIME_BYTE1 0x230a
#define DSM_PPR_RELEASE_TIME_BYTE2 0x230b
#define DSM_PPR_ATTACK_TIME_BYTE0 0x230d
#define DSM_PPR_ATTACK_TIME_BYTE1 0x230e
#define DSM_PPR_ATTACK_TIME_BYTE2 0x230f
#define DSM_DEBUZZER_RELEASE_TIME_BYTE0 0x2311
#define DSM_DEBUZZER_RELEASE_TIME_BYTE1 0x2312
#define DSM_DEBUZZER_RELEASE_TIME_BYTE2 0x2313
#define DSM_DEBUZZER_ATTACK_TIME_BYTE0 0x2315
#define DSM_DEBUZZER_ATTACK_TIME_BYTE1 0x2316
#define DSM_DEBUZZER_ATTACK_TIME_BYTE2 0x2317
#define DSMIG_WB_DRC_RELEASE_TIME_1 0x2380
#define DSMIG_WB_DRC_RELEASE_TIME_2 0x2381
#define DSMIG_WB_DRC_ATTACK_TIME_1 0x2382
#define DSMIG_WB_DRC_ATTACK_TIME_2 0x2383
#define DSMIG_WB_DRC_COMPRESSION_RATIO 0x2384
#define DSMIG_WB_DRC_COMPRESSION_THRESHOLD 0x2385
#define DSMIG_WB_DRC_MAKEUPGAIN 0x2386
#define DSMIG_WB_DRC_NOISE_GATE_THRESHOLD 0x2387
#define DSMIG_WBDRC_HPF_ENABLE 0x2388
#define DSMIG_WB_DRC_TEST_SMOOTHER_OUT_EN 0x2389
#define DSMIG_PPR_THRESHOLD 0x238b
#define DSM_STEREO_BASS_CHANNEL_SELECT 0x238d
#define DSM_TPROT_THRESHOLD_BYTE0 0x238e
#define DSM_TPROT_THRESHOLD_BYTE1 0x238f
#define DSM_TPROT_ROOM_TEMPERATURE_BYTE0 0x2390
#define DSM_TPROT_ROOM_TEMPERATURE_BYTE1 0x2391
#define DSM_TPROT_RECIP_RDC_ROOM_BYTE0 0x2392
#define DSM_TPROT_RECIP_RDC_ROOM_BYTE1 0x2393
#define DSM_TPROT_RECIP_RDC_ROOM_BYTE2 0x2394
#define DSM_TPROT_RECIP_TCONST_BYTE0 0x2395
#define DSM_TPROT_RECIP_TCONST_BYTE1 0x2396
#define DSM_TPROT_RECIP_TCONST_BYTE2 0x2397
#define DSM_THERMAL_ATTENUATION_SETTINGS 0x2398
#define DSM_THERMAL_PILOT_TONE_ATTENUATION 0x2399
#define DSM_TPROT_PG_TEMP_THRESH_BYTE0 0x239a
#define DSM_TPROT_PG_TEMP_THRESH_BYTE1 0x239b
#define THERMAL_RDC_RD_BACK_BYTE1 0x239c
#define THERMAL_RDC_RD_BACK_BYTE0 0x239d
#define THERMAL_COILTEMP_RD_BACK_BYTE1 0x239e
#define THERMAL_COILTEMP_RD_BACK_BYTE0 0x239f
#define DSMIG_DEBUZZER_THRESHOLD 0x23b5
#define DSMIG_DEBUZZER_ALPHA_COEF_TEST_ONLY 0x23b6
#define DSM_VOL_ENA 0x23b9
#define DSM_VOL_CTRL 0x23ba
#define DSMIG_EN 0x23e0
#define MAX98390_R23E1_DSP_GLOBAL_EN 0x23e1
#define DSM_THERMAL_GAIN 0x23f0
#define DSM_PPR_GAIN 0x23f1
#define DSM_DBZ_GAIN 0x23f2
#define DSM_WBDRC_GAIN 0x23f3
#define MAX98390_R23FF_GLOBAL_EN 0x23FF
#define MAX98390_R24FF_REV_ID 0x24FF
/* MAX98390_R2021_PCM_RX_SRC_1 */
#define MAX98390_PCM_RX_CH_SRC_SHIFT (0)
#define MAX98390_PCM_RX_CH_SRC_BASS_SHIFT (4)
/* MAX98390_R2022_PCM_TX_SRC_1 */
#define MAX98390_PCM_TX_CH_SRC_A_V_SHIFT (0)
#define MAX98390_PCM_TX_CH_SRC_A_I_SHIFT (4)
/* MAX98390_R2024_PCM_DATA_FMT_CFG */
#define MAX98390_PCM_MODE_CFG_FORMAT_MASK (0x7 << 3)
#define MAX98390_PCM_MODE_CFG_FORMAT_SHIFT (3)
#define MAX98390_PCM_TX_CH_INTERLEAVE_MASK (0x1 << 2)
#define MAX98390_PCM_FORMAT_I2S (0x0 << 0)
#define MAX98390_PCM_FORMAT_LJ (0x1 << 0)
#define MAX98390_PCM_FORMAT_TDM_MODE0 (0x3 << 0)
#define MAX98390_PCM_FORMAT_TDM_MODE1 (0x4 << 0)
#define MAX98390_PCM_FORMAT_TDM_MODE2 (0x5 << 0)
#define MAX98390_PCM_MODE_CFG_CHANSZ_MASK (0x3 << 6)
#define MAX98390_PCM_MODE_CFG_CHANSZ_16 (0x1 << 6)
#define MAX98390_PCM_MODE_CFG_CHANSZ_24 (0x2 << 6)
#define MAX98390_PCM_MODE_CFG_CHANSZ_32 (0x3 << 6)
/* MAX98390_R2039_AMP_DSP_CFG */
#define MAX98390_AMP_DSP_CFG_RMP_UP_SHIFT (4)
#define MAX98390_AMP_DSP_CFG_RMP_DN_SHIFT (5)
/* MAX98390_R203A_AMP_EN */
#define MAX98390_R203A_AMP_EN_SHIFT (0)
/* MAX98390_PCM_MASTER_MODE */
#define MAX98390_PCM_MASTER_MODE_MASK (0x3 << 0)
#define MAX98390_PCM_MASTER_MODE_SLAVE (0x0 << 0)
#define MAX98390_PCM_MASTER_MODE_MASTER (0x3 << 0)
#define MAX98390_PCM_MASTER_MODE_MCLK_MASK (0xF << 2)
#define MAX98390_PCM_MASTER_MODE_MCLK_RATE_SHIFT (2)
/* PCM_CLK_SETUP */
#define MAX98390_PCM_MODE_CFG_PCM_BCLKEDGE (0x1 << 2)
#define MAX98390_PCM_CLK_SETUP_BSEL_MASK (0xF << 0)
/* PCM_SR_SETUP */
#define MAX98390_PCM_SR_SET1_SR_MASK (0xF << 0)
#define MAX98390_PCM_SR_SET1_SR_8000 (0x0 << 0)
#define MAX98390_PCM_SR_SET1_SR_11025 (0x1 << 0)
#define MAX98390_PCM_SR_SET1_SR_12000 (0x2 << 0)
#define MAX98390_PCM_SR_SET1_SR_16000 (0x3 << 0)
#define MAX98390_PCM_SR_SET1_SR_22050 (0x4 << 0)
#define MAX98390_PCM_SR_SET1_SR_24000 (0x5 << 0)
#define MAX98390_PCM_SR_SET1_SR_32000 (0x6 << 0)
#define MAX98390_PCM_SR_SET1_SR_44100 (0x7 << 0)
#define MAX98390_PCM_SR_SET1_SR_48000 (0x8 << 0)
/* PCM_TO_SPK_MONO_MIX_1 */
#define MAX98390_PCM_TO_SPK_MONOMIX_CFG_MASK (0x3 << 6)
#define MAX98390_PCM_TO_SPK_MONOMIX_CFG_SHIFT (6)
#define MAX98390_PCM_TO_SPK_CH0_SRC_MASK (0xF << 0)
#define MAX98390_PCM_TO_SPK_CH1_SRC_MASK (0xF << 4)
/* MAX98390_BOOST_CTRL3 */
#define MAX98390_BOOST_CLK_PHASE_CFG_SHIFT (2)
/* SOFT_RESET */
#define MAX98390_SOFT_RESET_MASK (0x1 << 0)
#define MAX98390_GLOBAL_EN_MASK (0x1 << 0)
#define MAX98390_AMP_EN_MASK (0x1 << 0)
/* DSM register offset */
#define MAX98390_DSM_PAYLOAD_OFFSET 16
#define MAX98390_DSM_PAYLOAD_OFFSET_2 495
struct max98390_priv {
struct regmap *regmap;
unsigned int sysclk;
unsigned int master;
unsigned int tdm_mode;
unsigned int ref_rdc_value;
unsigned int ambient_temp_value;
};
#endif

View File

@ -23,8 +23,21 @@ static const char *const max9867_spmode[] = {
};
static const char *const max9867_filter_text[] = {"IIR", "FIR"};
static const char *const max9867_adc_dac_filter_text[] = {
"Disabled",
"Elliptical/16/256",
"Butterworth/16/500",
"Elliptical/8/256",
"Butterworth/8/500",
"Butterworth/8-24"
};
static SOC_ENUM_SINGLE_DECL(max9867_filter, MAX9867_CODECFLTR, 7,
max9867_filter_text);
static SOC_ENUM_SINGLE_DECL(max9867_dac_filter, MAX9867_CODECFLTR, 0,
max9867_adc_dac_filter_text);
static SOC_ENUM_SINGLE_DECL(max9867_adc_filter, MAX9867_CODECFLTR, 4,
max9867_adc_dac_filter_text);
static SOC_ENUM_SINGLE_DECL(max9867_spkmode, MAX9867_MODECONFIG, 0,
max9867_spmode);
static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max9867_master_tlv,
@ -64,6 +77,9 @@ static const struct snd_kcontrol_new max9867_snd_controls[] = {
SOC_SINGLE("Volume Smoothing Switch", MAX9867_MODECONFIG, 6, 1, 0),
SOC_SINGLE("Line ZC Switch", MAX9867_MODECONFIG, 5, 1, 0),
SOC_ENUM("DSP Filter", max9867_filter),
SOC_ENUM("ADC Filter", max9867_adc_filter),
SOC_ENUM("DAC Filter", max9867_dac_filter),
SOC_SINGLE("Mono Playback Switch", MAX9867_IFC1B, 3, 1, 0),
};
/* Input mixer */
@ -88,20 +104,38 @@ static const struct snd_kcontrol_new max9867_line_out_control =
SOC_DAPM_DOUBLE_R("Switch",
MAX9867_LEFTVOL, MAX9867_RIGHTVOL, 6, 1, 1);
/* DMIC mux */
static const char *const dmic_mux_text[] = {
"ADC", "DMIC"
};
static SOC_ENUM_SINGLE_DECL(left_dmic_mux_enum,
MAX9867_MICCONFIG, 5, dmic_mux_text);
static SOC_ENUM_SINGLE_DECL(right_dmic_mux_enum,
MAX9867_MICCONFIG, 4, dmic_mux_text);
static const struct snd_kcontrol_new max9867_left_dmic_mux =
SOC_DAPM_ENUM("DMICL Mux", left_dmic_mux_enum);
static const struct snd_kcontrol_new max9867_right_dmic_mux =
SOC_DAPM_ENUM("DMICR Mux", right_dmic_mux_enum);
static const struct snd_soc_dapm_widget max9867_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("MICL"),
SND_SOC_DAPM_INPUT("MICR"),
SND_SOC_DAPM_INPUT("DMICL"),
SND_SOC_DAPM_INPUT("DMICR"),
SND_SOC_DAPM_INPUT("LINL"),
SND_SOC_DAPM_INPUT("LINR"),
SND_SOC_DAPM_PGA("Left Line Input", MAX9867_PWRMAN, 6, 0, NULL, 0),
SND_SOC_DAPM_PGA("Right Line Input", MAX9867_PWRMAN, 5, 0, NULL, 0),
SND_SOC_DAPM_PGA("Left Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("Right Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER_NAMED_CTL("Input Mixer", SND_SOC_NOPM, 0, 0,
max9867_input_mixer_controls,
ARRAY_SIZE(max9867_input_mixer_controls)),
SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", MAX9867_PWRMAN, 1, 0),
SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", MAX9867_PWRMAN, 0, 0),
SND_SOC_DAPM_MUX("DMICL Mux", SND_SOC_NOPM, 0, 0,
&max9867_left_dmic_mux),
SND_SOC_DAPM_MUX("DMICR Mux", SND_SOC_NOPM, 0, 0,
&max9867_right_dmic_mux),
SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_MIXER("Digital", SND_SOC_NOPM, 0, 0,
max9867_sidetone_mixer_controls,
@ -109,8 +143,8 @@ static const struct snd_soc_dapm_widget max9867_dapm_widgets[] = {
SND_SOC_DAPM_MIXER_NAMED_CTL("Output Mixer", SND_SOC_NOPM, 0, 0,
max9867_output_mixer_controls,
ARRAY_SIZE(max9867_output_mixer_controls)),
SND_SOC_DAPM_DAC("DACL", "HiFi Playback", MAX9867_PWRMAN, 3, 0),
SND_SOC_DAPM_DAC("DACR", "HiFi Playback", MAX9867_PWRMAN, 2, 0),
SND_SOC_DAPM_DAC("DACL", "HiFi Playback", SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC("DACR", "HiFi Playback", SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_SWITCH("Master Playback", SND_SOC_NOPM, 0, 0,
&max9867_line_out_control),
SND_SOC_DAPM_OUTPUT("LOUT"),
@ -124,8 +158,12 @@ static const struct snd_soc_dapm_route max9867_audio_map[] = {
{"Input Mixer", "Mic Capture Switch", "MICR"},
{"Input Mixer", "Line Capture Switch", "Left Line Input"},
{"Input Mixer", "Line Capture Switch", "Right Line Input"},
{"ADCL", NULL, "Input Mixer"},
{"ADCR", NULL, "Input Mixer"},
{"DMICL Mux", "DMIC", "DMICL"},
{"DMICR Mux", "DMIC", "DMICR"},
{"DMICL Mux", "ADC", "Input Mixer"},
{"DMICR Mux", "ADC", "Input Mixer"},
{"ADCL", NULL, "DMICL Mux"},
{"ADCR", NULL, "DMICR Mux"},
{"Digital", "Sidetone Switch", "ADCL"},
{"Digital", "Sidetone Switch", "ADCR"},
@ -346,7 +384,8 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
}
regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A);
regmap_write(max9867->regmap, MAX9867_IFC1B, iface1B);
regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
MAX9867_IFC1B_BCLK_MASK, iface1B);
return 0;
}
@ -413,15 +452,14 @@ static int max9867_set_bias_level(struct snd_soc_component *component,
if (err)
return err;
err = regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
MAX9867_SHTDOWN, MAX9867_SHTDOWN);
err = regmap_write(max9867->regmap,
MAX9867_PWRMAN, 0xff);
if (err)
return err;
}
break;
case SND_SOC_BIAS_OFF:
err = regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
MAX9867_SHTDOWN, 0);
err = regmap_write(max9867->regmap, MAX9867_PWRMAN, 0);
if (err)
return err;
@ -463,35 +501,10 @@ static bool max9867_volatile_register(struct device *dev, unsigned int reg)
}
}
static const struct reg_default max9867_reg[] = {
{ 0x04, 0x00 },
{ 0x05, 0x00 },
{ 0x06, 0x00 },
{ 0x07, 0x00 },
{ 0x08, 0x00 },
{ 0x09, 0x00 },
{ 0x0A, 0x00 },
{ 0x0B, 0x00 },
{ 0x0C, 0x00 },
{ 0x0D, 0x00 },
{ 0x0E, 0x40 },
{ 0x0F, 0x40 },
{ 0x10, 0x00 },
{ 0x11, 0x00 },
{ 0x12, 0x00 },
{ 0x13, 0x00 },
{ 0x14, 0x00 },
{ 0x15, 0x00 },
{ 0x16, 0x00 },
{ 0x17, 0x00 },
};
static const struct regmap_config max9867_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MAX9867_REVISION,
.reg_defaults = max9867_reg,
.num_reg_defaults = ARRAY_SIZE(max9867_reg),
.volatile_reg = max9867_volatile_register,
.cache_type = REGCACHE_RBTREE,
};

View File

@ -58,7 +58,6 @@
#define MAX9867_MICCONFIG 0x15
#define MAX9867_MODECONFIG 0x16
#define MAX9867_PWRMAN 0x17
#define MAX9867_SHTDOWN 0x80
#define MAX9867_REVISION 0xff
#define MAX9867_CACHEREGNUM 10

View File

@ -355,6 +355,8 @@ static const struct snd_kcontrol_new nau8810_snd_controls[] = {
/* Speaker Output Mixer */
static const struct snd_kcontrol_new nau8810_speaker_mixer_controls[] = {
SOC_DAPM_SINGLE("AUX Bypass Switch", NAU8810_REG_SPKMIX,
NAU8810_AUXSPK_SFT, 1, 0),
SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_SPKMIX,
NAU8810_BYPSPK_SFT, 1, 0),
SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_SPKMIX,
@ -363,6 +365,8 @@ static const struct snd_kcontrol_new nau8810_speaker_mixer_controls[] = {
/* Mono Output Mixer */
static const struct snd_kcontrol_new nau8810_mono_mixer_controls[] = {
SOC_DAPM_SINGLE("AUX Bypass Switch", NAU8810_REG_MONOMIX,
NAU8810_AUXMOUT_SFT, 1, 0),
SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_MONOMIX,
NAU8810_BYPMOUT_SFT, 1, 0),
SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_MONOMIX,
@ -371,6 +375,8 @@ static const struct snd_kcontrol_new nau8810_mono_mixer_controls[] = {
/* PGA Mute */
static const struct snd_kcontrol_new nau8810_pgaboost_mixer_controls[] = {
SOC_DAPM_SINGLE("AUX PGA Switch", NAU8810_REG_ADCBOOST,
NAU8810_AUXBSTGAIN_SFT, 0x7, 0),
SOC_DAPM_SINGLE("PGA Mute Switch", NAU8810_REG_PGAGAIN,
NAU8810_PGAMT_SFT, 1, 1),
SOC_DAPM_SINGLE("PMIC PGA Switch", NAU8810_REG_ADCBOOST,
@ -379,6 +385,8 @@ static const struct snd_kcontrol_new nau8810_pgaboost_mixer_controls[] = {
/* Input PGA */
static const struct snd_kcontrol_new nau8810_inpga[] = {
SOC_DAPM_SINGLE("AUX Switch", NAU8810_REG_INPUT_SIGNAL,
NAU8810_AUXPGA_SFT, 1, 0),
SOC_DAPM_SINGLE("MicN Switch", NAU8810_REG_INPUT_SIGNAL,
NAU8810_NMICPGA_SFT, 1, 0),
SOC_DAPM_SINGLE("MicP Switch", NAU8810_REG_INPUT_SIGNAL,
@ -401,6 +409,23 @@ static int check_mclk_select_pll(struct snd_soc_dapm_widget *source,
return (value & NAU8810_CLKM_MASK);
}
static int check_mic_enabled(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink)
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(source->dapm);
struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
unsigned int value;
regmap_read(nau8810->regmap, NAU8810_REG_INPUT_SIGNAL, &value);
if (value & NAU8810_PMICPGA_EN || value & NAU8810_NMICPGA_EN)
return 1;
regmap_read(nau8810->regmap, NAU8810_REG_ADCBOOST, &value);
if (value & NAU8810_PMICBSTGAIN_MASK)
return 1;
return 0;
}
static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = {
SND_SOC_DAPM_MIXER("Speaker Mixer", NAU8810_REG_POWER3,
NAU8810_SPKMX_EN_SFT, 0, &nau8810_speaker_mixer_controls[0],
@ -425,6 +450,8 @@ static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = {
SND_SOC_DAPM_MIXER("Input Boost Stage", NAU8810_REG_POWER2,
NAU8810_BST_EN_SFT, 0, nau8810_pgaboost_mixer_controls,
ARRAY_SIZE(nau8810_pgaboost_mixer_controls)),
SND_SOC_DAPM_PGA("AUX Input", NAU8810_REG_POWER1,
NAU8810_AUX_EN_SFT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("Mic Bias", NAU8810_REG_POWER1,
NAU8810_MICBIAS_EN_SFT, 0, NULL, 0),
@ -434,6 +461,7 @@ static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = {
SND_SOC_DAPM_SWITCH("Digital Loopback", SND_SOC_NOPM, 0, 0,
&nau8810_loopback),
SND_SOC_DAPM_INPUT("AUX"),
SND_SOC_DAPM_INPUT("MICN"),
SND_SOC_DAPM_INPUT("MICP"),
SND_SOC_DAPM_OUTPUT("MONOOUT"),
@ -445,10 +473,12 @@ static const struct snd_soc_dapm_route nau8810_dapm_routes[] = {
{"DAC", NULL, "PLL", check_mclk_select_pll},
/* Mono output mixer */
{"Mono Mixer", "AUX Bypass Switch", "AUX Input"},
{"Mono Mixer", "PCM Playback Switch", "DAC"},
{"Mono Mixer", "Line Bypass Switch", "Input Boost Stage"},
/* Speaker output mixer */
{"Speaker Mixer", "AUX Bypass Switch", "AUX Input"},
{"Speaker Mixer", "PCM Playback Switch", "DAC"},
{"Speaker Mixer", "Line Bypass Switch", "Input Boost Stage"},
@ -463,13 +493,16 @@ static const struct snd_soc_dapm_route nau8810_dapm_routes[] = {
/* Input Boost Stage */
{"ADC", NULL, "Input Boost Stage"},
{"ADC", NULL, "PLL", check_mclk_select_pll},
{"Input Boost Stage", "AUX PGA Switch", "AUX Input"},
{"Input Boost Stage", "PGA Mute Switch", "Input PGA"},
{"Input Boost Stage", "PMIC PGA Switch", "MICP"},
/* Input PGA */
{"Input PGA", NULL, "Mic Bias"},
{"Input PGA", NULL, "Mic Bias", check_mic_enabled},
{"Input PGA", "AUX Switch", "AUX Input"},
{"Input PGA", "MicN Switch", "MICN"},
{"Input PGA", "MicP Switch", "MICP"},
{"AUX Input", NULL, "AUX"},
/* Digital Looptack */
{"Digital Loopback", "Switch", "ADC"},
@ -862,6 +895,8 @@ static int nau8810_i2c_probe(struct i2c_client *i2c,
static const struct i2c_device_id nau8810_i2c_id[] = {
{ "nau8810", 0 },
{ "nau8812", 0 },
{ "nau8814", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, nau8810_i2c_id);
@ -869,6 +904,8 @@ MODULE_DEVICE_TABLE(i2c, nau8810_i2c_id);
#ifdef CONFIG_OF
static const struct of_device_id nau8810_of_match[] = {
{ .compatible = "nuvoton,nau8810", },
{ .compatible = "nuvoton,nau8812", },
{ .compatible = "nuvoton,nau8814", },
{ }
};
MODULE_DEVICE_TABLE(of, nau8810_of_match);

View File

@ -69,6 +69,7 @@
/* NAU8810_REG_POWER1 (0x1) */
#define NAU8810_DCBUF_EN (0x1 << 8)
#define NAU8810_AUX_EN_SFT 6
#define NAU8810_PLL_EN_SFT 5
#define NAU8810_MICBIAS_EN_SFT 4
#define NAU8810_ABIAS_EN (0x1 << 3)
@ -228,7 +229,10 @@
/* NAU8810_REG_INPUT_SIGNAL (0x2C) */
#define NAU8810_PMICPGA_SFT 0
#define NAU8810_PMICPGA_EN (0x1 << NAU8810_PMICPGA_SFT)
#define NAU8810_NMICPGA_SFT 1
#define NAU8810_NMICPGA_EN (0x1 << NAU8810_NMICPGA_SFT)
#define NAU8810_AUXPGA_SFT 2
/* NAU8810_REG_PGAGAIN (0x2D) */
#define NAU8810_PGAGAIN_SFT 0
@ -236,12 +240,15 @@
#define NAU8810_PGAZC_SFT 7
/* NAU8810_REG_ADCBOOST (0x2F) */
#define NAU8810_AUXBSTGAIN_SFT 0
#define NAU8810_PMICBSTGAIN_SFT 4
#define NAU8810_PMICBSTGAIN_MASK (0x7 << NAU8810_PMICBSTGAIN_SFT)
#define NAU8810_PGABST_SFT 8
/* NAU8810_REG_SPKMIX (0x32) */
#define NAU8810_DACSPK_SFT 0
#define NAU8810_BYPSPK_SFT 1
#define NAU8810_AUXSPK_SFT 5
/* NAU8810_REG_SPKGAIN (0x36) */
#define NAU8810_SPKGAIN_SFT 0
@ -251,6 +258,7 @@
/* NAU8810_REG_MONOMIX (0x38) */
#define NAU8810_DACMOUT_SFT 0
#define NAU8810_BYPMOUT_SFT 1
#define NAU8810_AUXMOUT_SFT 2
#define NAU8810_MOUTMXMT_SFT 6

View File

@ -97,12 +97,13 @@ struct pll_calc_map {
int n;
int m;
bool m_bp;
bool k_bp;
};
static const struct pll_calc_map pll_preset_table[] = {
{19200000, 4096000, 23, 14, 1, false},
{19200000, 24576000, 3, 30, 3, false},
{3840000, 24576000, 3, 30, 0, true},
{19200000, 4096000, 23, 14, 1, false, false},
{19200000, 24576000, 3, 30, 3, false, false},
{3840000, 24576000, 3, 30, 0, true, false},
};
static unsigned int find_best_div(unsigned int in,
@ -128,7 +129,7 @@ static unsigned int find_best_div(unsigned int in,
* rl6231_pll_calc - Calcualte PLL M/N/K code.
* @freq_in: external clock provided to codec.
* @freq_out: target clock which codec works on.
* @pll_code: Pointer to structure with M, N, K and bypass flag.
* @pll_code: Pointer to structure with M, N, K, m_bypass and k_bypass flag.
*
* Calcualte M/N/K code to configure PLL for codec.
*
@ -143,7 +144,7 @@ int rl6231_pll_calc(const unsigned int freq_in,
unsigned int red, pll_out, in_t, out_t, div, div_t;
unsigned int red_t = abs(freq_out - freq_in);
unsigned int f_in, f_out, f_max;
bool bypass = false;
bool m_bypass = false, k_bypass = false;
if (RL6231_PLL_INP_MAX < freq_in || RL6231_PLL_INP_MIN > freq_in)
return -EINVAL;
@ -154,7 +155,8 @@ int rl6231_pll_calc(const unsigned int freq_in,
k = pll_preset_table[i].k;
m = pll_preset_table[i].m;
n = pll_preset_table[i].n;
bypass = pll_preset_table[i].m_bp;
m_bypass = pll_preset_table[i].m_bp;
k_bypass = pll_preset_table[i].k_bp;
pr_debug("Use preset PLL parameter table\n");
goto code_find;
}
@ -172,12 +174,14 @@ int rl6231_pll_calc(const unsigned int freq_in,
f_in = freq_in / div;
f_out = freq_out / div;
k = min_k;
if (min_k < -1)
min_k = -1;
for (k_t = min_k; k_t <= max_k; k_t++) {
for (n_t = 0; n_t <= max_n; n_t++) {
in_t = f_in * (n_t + 2);
pll_out = f_out * (k_t + 2);
if (in_t == pll_out) {
bypass = true;
m_bypass = true;
n = n_t;
k = k_t;
goto code_find;
@ -185,7 +189,7 @@ int rl6231_pll_calc(const unsigned int freq_in,
out_t = in_t / (k_t + 2);
red = abs(f_out - out_t);
if (red < red_t) {
bypass = true;
m_bypass = true;
n = n_t;
m = 0;
k = k_t;
@ -197,7 +201,7 @@ int rl6231_pll_calc(const unsigned int freq_in,
out_t = in_t / ((m_t + 2) * (k_t + 2));
red = abs(f_out - out_t);
if (red < red_t) {
bypass = false;
m_bypass = false;
n = n_t;
m = m_t;
k = k_t;
@ -211,8 +215,13 @@ int rl6231_pll_calc(const unsigned int freq_in,
pr_debug("Only get approximation about PLL\n");
code_find:
if (k == -1) {
k_bypass = true;
k = 0;
}
pll_code->m_bp = bypass;
pll_code->m_bp = m_bypass;
pll_code->k_bp = k_bypass;
pll_code->m_code = m;
pll_code->n_code = n;
pll_code->k_code = k;

View File

@ -18,6 +18,7 @@
struct rl6231_pll_code {
bool m_bp; /* Indicates bypass m code or not. */
bool k_bp; /* Indicates bypass k code or not. */
int m_code;
int n_code;
int k_code;

View File

@ -475,7 +475,7 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,
snd_soc_component_write(component,
RT1015_CLSD_INTERNAL9, 0x0140);
snd_soc_component_write(component,
RT1015_GAT_BOOST, 0x00fe);
RT1015_GAT_BOOST, 0x0efe);
snd_soc_component_write(component,
RT1015_PWR_STATE_CTRL, 0x000d);
msleep(500);
@ -780,6 +780,14 @@ static int rt1015_set_component_pll(struct snd_soc_component *component,
freq_out == rt1015->pll_out)
return 0;
if (source == RT1015_PLL_S_BCLK) {
if (rt1015->bclk_ratio == 0) {
dev_err(component->dev,
"Can not support bclk ratio as 0.\n");
return -EINVAL;
}
}
switch (source) {
case RT1015_PLL_S_MCLK:
snd_soc_component_update_bits(component, RT1015_CLK2,
@ -819,12 +827,30 @@ static int rt1015_set_component_pll(struct snd_soc_component *component,
return 0;
}
static int rt1015_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
{
struct snd_soc_component *component = dai->component;
struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component);
dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
rt1015->bclk_ratio = ratio;
if (ratio == 50) {
dev_dbg(component->dev, "Unsupport bclk ratio\n");
return -EINVAL;
}
return 0;
}
static int rt1015_probe(struct snd_soc_component *component)
{
struct rt1015_priv *rt1015 =
snd_soc_component_get_drvdata(component);
rt1015->component = component;
rt1015->bclk_ratio = 0;
snd_soc_component_write(component, RT1015_BAT_RPO_STEP1, 0x061c);
return 0;
@ -844,6 +870,7 @@ static void rt1015_remove(struct snd_soc_component *component)
static struct snd_soc_dai_ops rt1015_aif_dai_ops = {
.hw_params = rt1015_hw_params,
.set_fmt = rt1015_set_dai_fmt,
.set_bclk_ratio = rt1015_set_bclk_ratio,
};
static struct snd_soc_dai_driver rt1015_dai[] = {

View File

@ -362,6 +362,7 @@ struct rt1015_priv {
int sysclk_src;
int lrck;
int bclk;
int bclk_ratio;
int id;
int pll_src;
int pll_in;

695
sound/soc/codecs/rt1016.c Normal file
View File

@ -0,0 +1,695 @@
// SPDX-License-Identifier: GPL-2.0
//
// rt1016.c -- RT1016 ALSA SoC audio amplifier driver
//
// Copyright 2020 Realtek Semiconductor Corp.
// Author: Oder Chiou <oder_chiou@realtek.com>
//
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/regmap.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/firmware.h>
#include <linux/gpio.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include "rl6231.h"
#include "rt1016.h"
static const struct reg_sequence rt1016_patch[] = {
{RT1016_VOL_CTRL_3, 0x8900},
{RT1016_ANA_CTRL_1, 0xa002},
{RT1016_ANA_CTRL_2, 0x0002},
{RT1016_CLOCK_4, 0x6700},
{RT1016_CLASSD_3, 0xdc55},
{RT1016_CLASSD_4, 0x376a},
{RT1016_CLASSD_5, 0x009f},
};
static const struct reg_default rt1016_reg[] = {
{0x00, 0x0000},
{0x01, 0x5400},
{0x02, 0x5506},
{0x03, 0xf800},
{0x04, 0x0000},
{0x05, 0xbfbf},
{0x06, 0x8900},
{0x07, 0xa002},
{0x08, 0x0000},
{0x09, 0x0000},
{0x0a, 0x0000},
{0x0c, 0x0000},
{0x0d, 0x0000},
{0x0e, 0x10ec},
{0x0f, 0x6595},
{0x11, 0x0002},
{0x1c, 0x0000},
{0x1d, 0x0000},
{0x1e, 0x0000},
{0x1f, 0xf000},
{0x20, 0x0000},
{0x21, 0x6000},
{0x22, 0x0000},
{0x23, 0x6700},
{0x24, 0x0000},
{0x25, 0x0000},
{0x26, 0x0000},
{0x40, 0x0018},
{0x60, 0x00a5},
{0x80, 0x0010},
{0x81, 0x0009},
{0x82, 0x0000},
{0x83, 0x0000},
{0xa0, 0x0700},
{0xc0, 0x0080},
{0xc1, 0x02a0},
{0xc2, 0x1400},
{0xc3, 0x0a4a},
{0xc4, 0x552a},
{0xc5, 0x087e},
{0xc6, 0x0020},
{0xc7, 0xa833},
{0xc8, 0x0433},
{0xc9, 0x8040},
{0xca, 0xdc55},
{0xcb, 0x376a},
{0xcc, 0x009f},
{0xcf, 0x0020},
};
static bool rt1016_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case RT1016_ANA_FLAG:
case RT1016_VERSION2_ID:
case RT1016_VERSION1_ID:
case RT1016_VENDER_ID:
case RT1016_DEVICE_ID:
case RT1016_TEST_SIGNAL:
case RT1016_SC_CTRL_1:
return true;
default:
return false;
}
}
static bool rt1016_readable_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case RT1016_RESET:
case RT1016_PADS_CTRL_1:
case RT1016_PADS_CTRL_2:
case RT1016_I2C_CTRL:
case RT1016_VOL_CTRL_1:
case RT1016_VOL_CTRL_2:
case RT1016_VOL_CTRL_3:
case RT1016_ANA_CTRL_1:
case RT1016_MUX_SEL:
case RT1016_RX_I2S_CTRL:
case RT1016_ANA_FLAG:
case RT1016_VERSION2_ID:
case RT1016_VERSION1_ID:
case RT1016_VENDER_ID:
case RT1016_DEVICE_ID:
case RT1016_ANA_CTRL_2:
case RT1016_TEST_SIGNAL:
case RT1016_TEST_CTRL_1:
case RT1016_TEST_CTRL_2:
case RT1016_TEST_CTRL_3:
case RT1016_CLOCK_1:
case RT1016_CLOCK_2:
case RT1016_CLOCK_3:
case RT1016_CLOCK_4:
case RT1016_CLOCK_5:
case RT1016_CLOCK_6:
case RT1016_CLOCK_7:
case RT1016_I2S_CTRL:
case RT1016_DAC_CTRL_1:
case RT1016_SC_CTRL_1:
case RT1016_SC_CTRL_2:
case RT1016_SC_CTRL_3:
case RT1016_SC_CTRL_4:
case RT1016_SIL_DET:
case RT1016_SYS_CLK:
case RT1016_BIAS_CUR:
case RT1016_DAC_CTRL_2:
case RT1016_LDO_CTRL:
case RT1016_CLASSD_1:
case RT1016_PLL1:
case RT1016_PLL2:
case RT1016_PLL3:
case RT1016_CLASSD_2:
case RT1016_CLASSD_OUT:
case RT1016_CLASSD_3:
case RT1016_CLASSD_4:
case RT1016_CLASSD_5:
case RT1016_PWR_CTRL:
return true;
default:
return false;
}
}
static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -9550, 50, 0);
static const struct snd_kcontrol_new rt1016_snd_controls[] = {
SOC_DOUBLE_TLV("DAC Playback Volume", RT1016_VOL_CTRL_2,
RT1016_L_VOL_SFT, RT1016_R_VOL_SFT, 191, 0, dac_vol_tlv),
SOC_DOUBLE("DAC Playback Switch", RT1016_VOL_CTRL_1,
RT1016_DA_MUTE_L_SFT, RT1016_DA_MUTE_R_SFT, 1, 1),
};
static int rt1016_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink)
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(source->dapm);
struct rt1016_priv *rt1016 = snd_soc_component_get_drvdata(component);
if (rt1016->sysclk_src == RT1016_SCLK_S_PLL)
return 1;
else
return 0;
}
/* Interface data select */
static const char * const rt1016_data_select[] = {
"L/R", "R/L", "L/L", "R/R"
};
static SOC_ENUM_SINGLE_DECL(rt1016_if_data_swap_enum,
RT1016_I2S_CTRL, RT1016_I2S_DATA_SWAP_SFT, rt1016_data_select);
static const struct snd_kcontrol_new rt1016_if_data_swap_mux =
SOC_DAPM_ENUM("Data Swap Mux", rt1016_if_data_swap_enum);
static const struct snd_soc_dapm_widget rt1016_dapm_widgets[] = {
SND_SOC_DAPM_MUX("Data Swap Mux", SND_SOC_NOPM, 0, 0,
&rt1016_if_data_swap_mux),
SND_SOC_DAPM_SUPPLY("DAC Filter", RT1016_CLOCK_3,
RT1016_PWR_DAC_FILTER_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAMOD", RT1016_CLOCK_3, RT1016_PWR_DACMOD_BIT, 0,
NULL, 0),
SND_SOC_DAPM_SUPPLY("FIFO", RT1016_CLOCK_3, RT1016_PWR_CLK_FIFO_BIT, 0,
NULL, 0),
SND_SOC_DAPM_SUPPLY("Pure DC", RT1016_CLOCK_3,
RT1016_PWR_CLK_PUREDC_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("CLK Silence Det", RT1016_CLOCK_3,
RT1016_PWR_SIL_DET_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("RC 25M", RT1016_CLOCK_3, RT1016_PWR_RC_25M_BIT, 0,
NULL, 0),
SND_SOC_DAPM_SUPPLY("PLL1", RT1016_CLOCK_3, RT1016_PWR_PLL1_BIT, 0,
NULL, 0),
SND_SOC_DAPM_SUPPLY("ANA CTRL", RT1016_CLOCK_3, RT1016_PWR_ANA_CTRL_BIT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY("CLK SYS", RT1016_CLOCK_3, RT1016_PWR_CLK_SYS_BIT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY("LRCK Det", RT1016_CLOCK_4, RT1016_PWR_LRCK_DET_BIT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY("BCLK Det", RT1016_CLOCK_4, RT1016_PWR_BCLK_DET_BIT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY("CKGEN DAC", RT1016_DAC_CTRL_2,
RT1016_CKGEN_DAC_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("VCM SLOW", RT1016_CLASSD_1, RT1016_VCM_SLOW_BIT, 0,
NULL, 0),
SND_SOC_DAPM_SUPPLY("Silence Det", RT1016_SIL_DET,
RT1016_SIL_DET_EN_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("PLL2", RT1016_PLL2, RT1016_PLL2_EN_BIT, 0, NULL,
0),
SND_SOC_DAPM_SUPPLY_S("BG1 BG2", 1, RT1016_PWR_CTRL,
RT1016_PWR_BG_1_2_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("MBIAS BG", 1, RT1016_PWR_CTRL,
RT1016_PWR_MBIAS_BG_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("PLL", 1, RT1016_PWR_CTRL, RT1016_PWR_PLL_BIT, 0,
NULL, 0),
SND_SOC_DAPM_SUPPLY_S("BASIC", 1, RT1016_PWR_CTRL, RT1016_PWR_BASIC_BIT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("CLASS D", 1, RT1016_PWR_CTRL,
RT1016_PWR_CLSD_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("25M", 1, RT1016_PWR_CTRL, RT1016_PWR_25M_BIT, 0,
NULL, 0),
SND_SOC_DAPM_SUPPLY_S("DACL", 1, RT1016_PWR_CTRL, RT1016_PWR_DACL_BIT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("DACR", 1, RT1016_PWR_CTRL, RT1016_PWR_DACR_BIT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("LDO2", 1, RT1016_PWR_CTRL, RT1016_PWR_LDO2_BIT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("VREF", 1, RT1016_PWR_CTRL, RT1016_PWR_VREF_BIT,
0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("MBIAS", 1, RT1016_PWR_CTRL, RT1016_PWR_MBIAS_BIT,
0, NULL, 0),
SND_SOC_DAPM_AIF_IN("AIFRX", "AIF Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_OUTPUT("SPO"),
};
static const struct snd_soc_dapm_route rt1016_dapm_routes[] = {
{ "Data Swap Mux", "L/R", "AIFRX" },
{ "Data Swap Mux", "R/L", "AIFRX" },
{ "Data Swap Mux", "L/L", "AIFRX" },
{ "Data Swap Mux", "R/R", "AIFRX" },
{ "DAC", NULL, "DAC Filter" },
{ "DAC", NULL, "DAMOD" },
{ "DAC", NULL, "FIFO" },
{ "DAC", NULL, "Pure DC" },
{ "DAC", NULL, "Silence Det" },
{ "DAC", NULL, "ANA CTRL" },
{ "DAC", NULL, "CLK SYS" },
{ "DAC", NULL, "LRCK Det" },
{ "DAC", NULL, "BCLK Det" },
{ "DAC", NULL, "CKGEN DAC" },
{ "DAC", NULL, "VCM SLOW" },
{ "PLL", NULL, "PLL1" },
{ "PLL", NULL, "PLL2" },
{ "25M", NULL, "RC 25M" },
{ "Silence Det", NULL, "CLK Silence Det" },
{ "DAC", NULL, "Data Swap Mux" },
{ "DAC", NULL, "BG1 BG2" },
{ "DAC", NULL, "MBIAS BG" },
{ "DAC", NULL, "PLL", rt1016_is_sys_clk_from_pll},
{ "DAC", NULL, "BASIC" },
{ "DAC", NULL, "CLASS D" },
{ "DAC", NULL, "25M" },
{ "DAC", NULL, "DACL" },
{ "DAC", NULL, "DACR" },
{ "DAC", NULL, "LDO2" },
{ "DAC", NULL, "VREF" },
{ "DAC", NULL, "MBIAS" },
{ "SPO", NULL, "DAC" },
};
static int rt1016_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct rt1016_priv *rt1016 = snd_soc_component_get_drvdata(component);
int pre_div, bclk_ms, frame_size;
unsigned int val_len = 0;
rt1016->lrck = params_rate(params);
pre_div = rl6231_get_clk_info(rt1016->sysclk, rt1016->lrck);
if (pre_div < 0) {
dev_err(component->dev, "Unsupported clock rate\n");
return -EINVAL;
}
frame_size = snd_soc_params_to_frame_size(params);
if (frame_size < 0) {
dev_err(component->dev, "Unsupported frame size: %d\n",
frame_size);
return -EINVAL;
}
bclk_ms = frame_size > 32;
rt1016->bclk = rt1016->lrck * (32 << bclk_ms);
if (bclk_ms && rt1016->master)
snd_soc_component_update_bits(component, RT1016_I2S_CTRL,
RT1016_I2S_BCLK_MS_MASK, RT1016_I2S_BCLK_MS_64);
dev_dbg(component->dev, "lrck is %dHz and pre_div is %d for iis %d\n",
rt1016->lrck, pre_div, dai->id);
switch (params_width(params)) {
case 16:
val_len = RT1016_I2S_DL_16;
break;
case 20:
val_len = RT1016_I2S_DL_20;
break;
case 24:
val_len = RT1016_I2S_DL_24;
break;
case 32:
val_len = RT1016_I2S_DL_32;
break;
default:
return -EINVAL;
}
snd_soc_component_update_bits(component, RT1016_I2S_CTRL,
RT1016_I2S_DL_MASK, val_len);
snd_soc_component_update_bits(component, RT1016_CLOCK_2,
RT1016_FS_PD_MASK | RT1016_OSR_PD_MASK,
((pre_div + 3) << RT1016_FS_PD_SFT) |
(pre_div << RT1016_OSR_PD_SFT));
return 0;
}
static int rt1016_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct snd_soc_component *component = dai->component;
struct rt1016_priv *rt1016 = snd_soc_component_get_drvdata(component);
unsigned int reg_val = 0;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
reg_val |= RT1016_I2S_MS_M;
rt1016->master = 1;
break;
case SND_SOC_DAIFMT_CBS_CFS:
reg_val |= RT1016_I2S_MS_S;
break;
default:
return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
break;
case SND_SOC_DAIFMT_IB_NF:
reg_val |= RT1016_I2S_BCLK_POL_INV;
break;
default:
return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
break;
case SND_SOC_DAIFMT_LEFT_J:
reg_val |= RT1016_I2S_DF_LEFT;
break;
case SND_SOC_DAIFMT_DSP_A:
reg_val |= RT1016_I2S_DF_PCM_A;
break;
case SND_SOC_DAIFMT_DSP_B:
reg_val |= RT1016_I2S_DF_PCM_B;
break;
default:
return -EINVAL;
}
snd_soc_component_update_bits(component, RT1016_I2S_CTRL,
RT1016_I2S_MS_MASK | RT1016_I2S_BCLK_POL_MASK |
RT1016_I2S_DF_MASK, reg_val);
return 0;
}
static int rt1016_set_component_sysclk(struct snd_soc_component *component,
int clk_id, int source, unsigned int freq, int dir)
{
struct rt1016_priv *rt1016 = snd_soc_component_get_drvdata(component);
unsigned int reg_val = 0;
if (freq == rt1016->sysclk && clk_id == rt1016->sysclk_src)
return 0;
switch (clk_id) {
case RT1016_SCLK_S_MCLK:
reg_val |= RT1016_CLK_SYS_SEL_MCLK;
break;
case RT1016_SCLK_S_PLL:
reg_val |= RT1016_CLK_SYS_SEL_PLL;
break;
default:
dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
return -EINVAL;
}
rt1016->sysclk = freq;
rt1016->sysclk_src = clk_id;
dev_dbg(component->dev, "Sysclk is %dHz and clock id is %d\n",
freq, clk_id);
snd_soc_component_update_bits(component, RT1016_CLOCK_1,
RT1016_CLK_SYS_SEL_MASK, reg_val);
return 0;
}
static int rt1016_set_component_pll(struct snd_soc_component *component,
int pll_id, int source, unsigned int freq_in,
unsigned int freq_out)
{
struct rt1016_priv *rt1016 = snd_soc_component_get_drvdata(component);
struct rl6231_pll_code pll_code;
int ret;
if (!freq_in || !freq_out) {
dev_dbg(component->dev, "PLL disabled\n");
rt1016->pll_in = 0;
rt1016->pll_out = 0;
return 0;
}
if (source == rt1016->pll_src && freq_in == rt1016->pll_in &&
freq_out == rt1016->pll_out)
return 0;
switch (source) {
case RT1016_PLL_S_MCLK:
snd_soc_component_update_bits(component, RT1016_CLOCK_1,
RT1016_PLL_SEL_MASK, RT1016_PLL_SEL_MCLK);
break;
case RT1016_PLL_S_BCLK:
snd_soc_component_update_bits(component, RT1016_CLOCK_1,
RT1016_PLL_SEL_MASK, RT1016_PLL_SEL_BCLK);
break;
default:
dev_err(component->dev, "Unknown PLL Source %d\n", source);
return -EINVAL;
}
ret = rl6231_pll_calc(freq_in, freq_out * 4, &pll_code);
if (ret < 0) {
dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
return ret;
}
dev_dbg(component->dev, "mbypass=%d m=%d n=%d kbypass=%d k=%d\n",
pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
pll_code.n_code, pll_code.k_bp,
(pll_code.k_bp ? 0 : pll_code.k_code));
snd_soc_component_write(component, RT1016_PLL1,
(pll_code.m_bp ? 0 : pll_code.m_code) << RT1016_PLL_M_SFT |
pll_code.m_bp << RT1016_PLL_M_BP_SFT | pll_code.n_code);
snd_soc_component_write(component, RT1016_PLL2,
pll_code.k_bp << RT1016_PLL_K_BP_SFT |
(pll_code.k_bp ? 0 : pll_code.k_code));
rt1016->pll_in = freq_in;
rt1016->pll_out = freq_out;
rt1016->pll_src = source;
return 0;
}
static int rt1016_probe(struct snd_soc_component *component)
{
struct rt1016_priv *rt1016 =
snd_soc_component_get_drvdata(component);
rt1016->component = component;
return 0;
}
static void rt1016_remove(struct snd_soc_component *component)
{
struct rt1016_priv *rt1016 = snd_soc_component_get_drvdata(component);
regmap_write(rt1016->regmap, RT1016_RESET, 0);
}
#define RT1016_STEREO_RATES SNDRV_PCM_RATE_8000_48000
#define RT1016_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
static struct snd_soc_dai_ops rt1016_aif_dai_ops = {
.hw_params = rt1016_hw_params,
.set_fmt = rt1016_set_dai_fmt,
};
static struct snd_soc_dai_driver rt1016_dai[] = {
{
.name = "rt1016-aif",
.id = 0,
.playback = {
.stream_name = "AIF Playback",
.channels_min = 1,
.channels_max = 2,
.rates = RT1016_STEREO_RATES,
.formats = RT1016_FORMATS,
},
.ops = &rt1016_aif_dai_ops,
}
};
#ifdef CONFIG_PM
static int rt1016_suspend(struct snd_soc_component *component)
{
struct rt1016_priv *rt1016 = snd_soc_component_get_drvdata(component);
regcache_cache_only(rt1016->regmap, true);
regcache_mark_dirty(rt1016->regmap);
return 0;
}
static int rt1016_resume(struct snd_soc_component *component)
{
struct rt1016_priv *rt1016 = snd_soc_component_get_drvdata(component);
regcache_cache_only(rt1016->regmap, false);
regcache_sync(rt1016->regmap);
return 0;
}
#else
#define rt1016_suspend NULL
#define rt1016_resume NULL
#endif
static const struct snd_soc_component_driver soc_component_dev_rt1016 = {
.probe = rt1016_probe,
.remove = rt1016_remove,
.suspend = rt1016_suspend,
.resume = rt1016_resume,
.controls = rt1016_snd_controls,
.num_controls = ARRAY_SIZE(rt1016_snd_controls),
.dapm_widgets = rt1016_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(rt1016_dapm_widgets),
.dapm_routes = rt1016_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(rt1016_dapm_routes),
.set_sysclk = rt1016_set_component_sysclk,
.set_pll = rt1016_set_component_pll,
.use_pmdown_time = 1,
.endianness = 1,
.non_legacy_dai_naming = 1,
};
static const struct regmap_config rt1016_regmap = {
.reg_bits = 8,
.val_bits = 16,
.max_register = RT1016_PWR_CTRL,
.volatile_reg = rt1016_volatile_register,
.readable_reg = rt1016_readable_register,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = rt1016_reg,
.num_reg_defaults = ARRAY_SIZE(rt1016_reg),
};
static const struct i2c_device_id rt1016_i2c_id[] = {
{ "rt1016", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, rt1016_i2c_id);
#if defined(CONFIG_OF)
static const struct of_device_id rt1016_of_match[] = {
{ .compatible = "realtek,rt1016", },
{},
};
MODULE_DEVICE_TABLE(of, rt1016_of_match);
#endif
#ifdef CONFIG_ACPI
static struct acpi_device_id rt1016_acpi_match[] = {
{"10EC1016", 0,},
{},
};
MODULE_DEVICE_TABLE(acpi, rt1016_acpi_match);
#endif
static int rt1016_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct rt1016_priv *rt1016;
int ret;
unsigned int val;
rt1016 = devm_kzalloc(&i2c->dev, sizeof(struct rt1016_priv),
GFP_KERNEL);
if (rt1016 == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c, rt1016);
rt1016->regmap = devm_regmap_init_i2c(i2c, &rt1016_regmap);
if (IS_ERR(rt1016->regmap)) {
ret = PTR_ERR(rt1016->regmap);
dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
ret);
return ret;
}
regmap_read(rt1016->regmap, RT1016_DEVICE_ID, &val);
if (val != RT1016_DEVICE_ID_VAL) {
dev_err(&i2c->dev,
"Device with ID register %x is not rt1016\n", val);
return -ENODEV;
}
regmap_write(rt1016->regmap, RT1016_RESET, 0);
ret = regmap_register_patch(rt1016->regmap, rt1016_patch,
ARRAY_SIZE(rt1016_patch));
if (ret != 0)
dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
return devm_snd_soc_register_component(&i2c->dev,
&soc_component_dev_rt1016,
rt1016_dai, ARRAY_SIZE(rt1016_dai));
}
static void rt1016_i2c_shutdown(struct i2c_client *client)
{
struct rt1016_priv *rt1016 = i2c_get_clientdata(client);
regmap_write(rt1016->regmap, RT1016_RESET, 0);
}
static struct i2c_driver rt1016_i2c_driver = {
.driver = {
.name = "rt1016",
.of_match_table = of_match_ptr(rt1016_of_match),
.acpi_match_table = ACPI_PTR(rt1016_acpi_match),
},
.probe = rt1016_i2c_probe,
.shutdown = rt1016_i2c_shutdown,
.id_table = rt1016_i2c_id,
};
module_i2c_driver(rt1016_i2c_driver);
MODULE_DESCRIPTION("ASoC RT1016 driver");
MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
MODULE_LICENSE("GPL v2");

232
sound/soc/codecs/rt1016.h Normal file
View File

@ -0,0 +1,232 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* rt1016.h -- RT1016 ALSA SoC audio amplifier driver
*
* Copyright 2020 Realtek Semiconductor Corp.
* Author: Oder Chiou <oder_chiou@realtek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __RT1016_H__
#define __RT1016_H__
#define RT1016_DEVICE_ID_VAL 0x6595
#define RT1016_RESET 0x00
#define RT1016_PADS_CTRL_1 0x01
#define RT1016_PADS_CTRL_2 0x02
#define RT1016_I2C_CTRL 0x03
#define RT1016_VOL_CTRL_1 0x04
#define RT1016_VOL_CTRL_2 0x05
#define RT1016_VOL_CTRL_3 0x06
#define RT1016_ANA_CTRL_1 0x07
#define RT1016_MUX_SEL 0x08
#define RT1016_RX_I2S_CTRL 0x09
#define RT1016_ANA_FLAG 0x0a
#define RT1016_VERSION2_ID 0x0c
#define RT1016_VERSION1_ID 0x0d
#define RT1016_VENDER_ID 0x0e
#define RT1016_DEVICE_ID 0x0f
#define RT1016_ANA_CTRL_2 0x11
#define RT1016_TEST_SIGNAL 0x1c
#define RT1016_TEST_CTRL_1 0x1d
#define RT1016_TEST_CTRL_2 0x1e
#define RT1016_TEST_CTRL_3 0x1f
#define RT1016_CLOCK_1 0x20
#define RT1016_CLOCK_2 0x21
#define RT1016_CLOCK_3 0x22
#define RT1016_CLOCK_4 0x23
#define RT1016_CLOCK_5 0x24
#define RT1016_CLOCK_6 0x25
#define RT1016_CLOCK_7 0x26
#define RT1016_I2S_CTRL 0x40
#define RT1016_DAC_CTRL_1 0x60
#define RT1016_SC_CTRL_1 0x80
#define RT1016_SC_CTRL_2 0x81
#define RT1016_SC_CTRL_3 0x82
#define RT1016_SC_CTRL_4 0x83
#define RT1016_SIL_DET 0xa0
#define RT1016_SYS_CLK 0xc0
#define RT1016_BIAS_CUR 0xc1
#define RT1016_DAC_CTRL_2 0xc2
#define RT1016_LDO_CTRL 0xc3
#define RT1016_CLASSD_1 0xc4
#define RT1016_PLL1 0xc5
#define RT1016_PLL2 0xc6
#define RT1016_PLL3 0xc7
#define RT1016_CLASSD_2 0xc8
#define RT1016_CLASSD_OUT 0xc9
#define RT1016_CLASSD_3 0xca
#define RT1016_CLASSD_4 0xcb
#define RT1016_CLASSD_5 0xcc
#define RT1016_PWR_CTRL 0xcf
/* global definition */
#define RT1016_L_VOL_MASK (0xff << 8)
#define RT1016_L_VOL_SFT 8
#define RT1016_R_VOL_MASK (0xff)
#define RT1016_R_VOL_SFT 0
/* 0x04 */
#define RT1016_DA_MUTE_L_SFT 7
#define RT1016_DA_MUTE_R_SFT 6
/* 0x20 */
#define RT1016_CLK_SYS_SEL_MASK (0x1 << 15)
#define RT1016_CLK_SYS_SEL_SFT 15
#define RT1016_CLK_SYS_SEL_MCLK (0x0 << 15)
#define RT1016_CLK_SYS_SEL_PLL (0x1 << 15)
#define RT1016_PLL_SEL_MASK (0x1 << 13)
#define RT1016_PLL_SEL_SFT 13
#define RT1016_PLL_SEL_MCLK (0x0 << 13)
#define RT1016_PLL_SEL_BCLK (0x1 << 13)
/* 0x21 */
#define RT1016_FS_PD_MASK (0x7 << 13)
#define RT1016_FS_PD_SFT 13
#define RT1016_OSR_PD_MASK (0x3 << 10)
#define RT1016_OSR_PD_SFT 10
/* 0x22 */
#define RT1016_PWR_DAC_FILTER (0x1 << 11)
#define RT1016_PWR_DAC_FILTER_BIT 11
#define RT1016_PWR_DACMOD (0x1 << 10)
#define RT1016_PWR_DACMOD_BIT 10
#define RT1016_PWR_CLK_FIFO (0x1 << 9)
#define RT1016_PWR_CLK_FIFO_BIT 9
#define RT1016_PWR_CLK_PUREDC (0x1 << 8)
#define RT1016_PWR_CLK_PUREDC_BIT 8
#define RT1016_PWR_SIL_DET (0x1 << 7)
#define RT1016_PWR_SIL_DET_BIT 7
#define RT1016_PWR_RC_25M (0x1 << 6)
#define RT1016_PWR_RC_25M_BIT 6
#define RT1016_PWR_PLL1 (0x1 << 5)
#define RT1016_PWR_PLL1_BIT 5
#define RT1016_PWR_ANA_CTRL (0x1 << 4)
#define RT1016_PWR_ANA_CTRL_BIT 4
#define RT1016_PWR_CLK_SYS (0x1 << 3)
#define RT1016_PWR_CLK_SYS_BIT 3
/* 0x23 */
#define RT1016_PWR_LRCK_DET (0x1 << 15)
#define RT1016_PWR_LRCK_DET_BIT 15
#define RT1016_PWR_BCLK_DET (0x1 << 11)
#define RT1016_PWR_BCLK_DET_BIT 11
/* 0x40 */
#define RT1016_I2S_BCLK_MS_MASK (0x1 << 15)
#define RT1016_I2S_BCLK_MS_SFT 15
#define RT1016_I2S_BCLK_MS_32 (0x0 << 15)
#define RT1016_I2S_BCLK_MS_64 (0x1 << 15)
#define RT1016_I2S_BCLK_POL_MASK (0x1 << 13)
#define RT1016_I2S_BCLK_POL_SFT 13
#define RT1016_I2S_BCLK_POL_NOR (0x0 << 13)
#define RT1016_I2S_BCLK_POL_INV (0x1 << 13)
#define RT1016_I2S_DATA_SWAP_MASK (0x1 << 10)
#define RT1016_I2S_DATA_SWAP_SFT 10
#define RT1016_I2S_DL_MASK (0x7 << 4)
#define RT1016_I2S_DL_SFT 4
#define RT1016_I2S_DL_16 (0x1 << 4)
#define RT1016_I2S_DL_20 (0x2 << 4)
#define RT1016_I2S_DL_24 (0x3 << 4)
#define RT1016_I2S_DL_32 (0x4 << 4)
#define RT1016_I2S_MS_MASK (0x1 << 3)
#define RT1016_I2S_MS_SFT 3
#define RT1016_I2S_MS_M (0x0 << 3)
#define RT1016_I2S_MS_S (0x1 << 3)
#define RT1016_I2S_DF_MASK (0x7 << 0)
#define RT1016_I2S_DF_SFT 0
#define RT1016_I2S_DF_I2S (0x0)
#define RT1016_I2S_DF_LEFT (0x1)
#define RT1016_I2S_DF_PCM_A (0x2)
#define RT1016_I2S_DF_PCM_B (0x3)
/* 0xa0 */
#define RT1016_SIL_DET_EN (0x1 << 15)
#define RT1016_SIL_DET_EN_BIT 15
/* 0xc2 */
#define RT1016_CKGEN_DAC (0x1 << 13)
#define RT1016_CKGEN_DAC_BIT 13
/* 0xc4 */
#define RT1016_VCM_SLOW (0x1 << 6)
#define RT1016_VCM_SLOW_BIT 6
/* 0xc5 */
#define RT1016_PLL_M_MAX 0xf
#define RT1016_PLL_M_MASK (RT1016_PLL_M_MAX << 12)
#define RT1016_PLL_M_SFT 12
#define RT1016_PLL_M_BP (0x1 << 11)
#define RT1016_PLL_M_BP_SFT 11
#define RT1016_PLL_N_MAX 0x1ff
#define RT1016_PLL_N_MASK (RT1016_PLL_N_MAX << 0)
#define RT1016_PLL_N_SFT 0
/* 0xc6 */
#define RT1016_PLL2_EN (0x1 << 15)
#define RT1016_PLL2_EN_BIT 15
#define RT1016_PLL_K_BP (0x1 << 5)
#define RT1016_PLL_K_BP_SFT 5
#define RT1016_PLL_K_MAX 0x1f
#define RT1016_PLL_K_MASK (RT1016_PLL_K_MAX)
#define RT1016_PLL_K_SFT 0
/* 0xcf */
#define RT1016_PWR_BG_1_2 (0x1 << 12)
#define RT1016_PWR_BG_1_2_BIT 12
#define RT1016_PWR_MBIAS_BG (0x1 << 11)
#define RT1016_PWR_MBIAS_BG_BIT 11
#define RT1016_PWR_PLL (0x1 << 9)
#define RT1016_PWR_PLL_BIT 9
#define RT1016_PWR_BASIC (0x1 << 8)
#define RT1016_PWR_BASIC_BIT 8
#define RT1016_PWR_CLSD (0x1 << 7)
#define RT1016_PWR_CLSD_BIT 7
#define RT1016_PWR_25M (0x1 << 6)
#define RT1016_PWR_25M_BIT 6
#define RT1016_PWR_DACL (0x1 << 4)
#define RT1016_PWR_DACL_BIT 4
#define RT1016_PWR_DACR (0x1 << 3)
#define RT1016_PWR_DACR_BIT 3
#define RT1016_PWR_LDO2 (0x1 << 2)
#define RT1016_PWR_LDO2_BIT 2
#define RT1016_PWR_VREF (0x1 << 1)
#define RT1016_PWR_VREF_BIT 1
#define RT1016_PWR_MBIAS (0x1 << 0)
#define RT1016_PWR_MBIAS_BIT 0
/* System Clock Source */
enum {
RT1016_SCLK_S_MCLK,
RT1016_SCLK_S_PLL,
};
/* PLL1 Source */
enum {
RT1016_PLL_S_MCLK,
RT1016_PLL_S_BCLK,
};
enum {
RT1016_AIF1,
RT1016_AIFS,
};
struct rt1016_priv {
struct snd_soc_component *component;
struct regmap *regmap;
int sysclk;
int sysclk_src;
int lrck;
int bclk;
int master;
int pll_src;
int pll_in;
int pll_out;
};
#endif /* __RT1016_H__ */

View File

@ -178,10 +178,6 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
if (rt1308->hw_init)
return 0;
ret = rt1308_read_prop(slave);
if (ret < 0)
goto _io_init_err_;
if (rt1308->first_hw_init) {
regcache_cache_only(rt1308->regmap, false);
regcache_cache_bypass(rt1308->regmap, true);
@ -235,9 +231,9 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
efuse_c_btl_r = tmp;
regmap_read(rt1308->regmap, 0xc872, &tmp);
efuse_c_btl_r = efuse_c_btl_r | (tmp << 8);
dev_info(&slave->dev, "%s m_btl_l=0x%x, m_btl_r=0x%x\n", __func__,
dev_dbg(&slave->dev, "%s m_btl_l=0x%x, m_btl_r=0x%x\n", __func__,
efuse_m_btl_l, efuse_m_btl_r);
dev_info(&slave->dev, "%s c_btl_l=0x%x, c_btl_r=0x%x\n", __func__,
dev_dbg(&slave->dev, "%s c_btl_l=0x%x, c_btl_r=0x%x\n", __func__,
efuse_c_btl_l, efuse_c_btl_r);
/* initial settings */
@ -282,7 +278,6 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);
_io_init_err_:
return ret;
}
@ -482,6 +477,9 @@ static int rt1308_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
{
struct sdw_stream_data *stream;
if (!sdw_stream)
return 0;
stream = kzalloc(sizeof(*stream), GFP_KERNEL);
if (!stream)
return -ENOMEM;
@ -684,9 +682,6 @@ static int rt1308_sdw_probe(struct sdw_slave *slave,
{
struct regmap *regmap;
/* Assign ops */
slave->ops = &rt1308_slave_ops;
/* Regmap Initialization */
regmap = devm_regmap_init_sdw(slave, &rt1308_sdw_regmap);
if (!regmap)

View File

@ -605,20 +605,15 @@ static int rt5677_spi_probe(struct spi_device *spi)
g_spi = spi;
ret = snd_soc_register_component(&spi->dev, &rt5677_spi_dai_component,
&rt5677_spi_dai, 1);
ret = devm_snd_soc_register_component(&spi->dev,
&rt5677_spi_dai_component,
&rt5677_spi_dai, 1);
if (ret < 0)
dev_err(&spi->dev, "Failed to register component.\n");
return ret;
}
static int rt5677_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_component(&spi->dev);
return 0;
}
static const struct acpi_device_id rt5677_spi_acpi_id[] = {
{ "RT5677AA", 0 },
{ }
@ -631,7 +626,6 @@ static struct spi_driver rt5677_spi_driver = {
.acpi_match_table = ACPI_PTR(rt5677_spi_acpi_id),
},
.probe = rt5677_spi_probe,
.remove = rt5677_spi_remove,
};
module_spi_driver(rt5677_spi_driver);

View File

@ -0,0 +1,306 @@
// SPDX-License-Identifier: GPL-2.0-only
//
// rt5682.c -- RT5682 ALSA SoC audio component driver
//
// Copyright 2018 Realtek Semiconductor Corp.
// Author: Bard Liao <bardliao@realtek.com>
//
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/acpi.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/mutex.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/jack.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/rt5682.h>
#include "rl6231.h"
#include "rt5682.h"
static const struct rt5682_platform_data i2s_default_platform_data = {
.dmic1_data_pin = RT5682_DMIC1_DATA_GPIO2,
.dmic1_clk_pin = RT5682_DMIC1_CLK_GPIO3,
.jd_src = RT5682_JD1,
.btndet_delay = 16,
.dai_clk_names[RT5682_DAI_WCLK_IDX] = "rt5682-dai-wclk",
.dai_clk_names[RT5682_DAI_BCLK_IDX] = "rt5682-dai-bclk",
};
static const struct regmap_config rt5682_regmap = {
.reg_bits = 16,
.val_bits = 16,
.max_register = RT5682_I2C_MODE,
.volatile_reg = rt5682_volatile_register,
.readable_reg = rt5682_readable_register,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = rt5682_reg,
.num_reg_defaults = RT5682_REG_NUM,
.use_single_read = true,
.use_single_write = true,
};
static void rt5682_jd_check_handler(struct work_struct *work)
{
struct rt5682_priv *rt5682 = container_of(work, struct rt5682_priv,
jd_check_work.work);
if (snd_soc_component_read32(rt5682->component, RT5682_AJD1_CTRL)
& RT5682_JDH_RS_MASK) {
/* jack out */
rt5682->jack_type = rt5682_headset_detect(rt5682->component, 0);
snd_soc_jack_report(rt5682->hs_jack, rt5682->jack_type,
SND_JACK_HEADSET |
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3);
} else {
schedule_delayed_work(&rt5682->jd_check_work, 500);
}
}
static irqreturn_t rt5682_irq(int irq, void *data)
{
struct rt5682_priv *rt5682 = data;
mod_delayed_work(system_power_efficient_wq,
&rt5682->jack_detect_work, msecs_to_jiffies(250));
return IRQ_HANDLED;
}
static struct snd_soc_dai_driver rt5682_dai[] = {
{
.name = "rt5682-aif1",
.id = RT5682_AIF1,
.playback = {
.stream_name = "AIF1 Playback",
.channels_min = 1,
.channels_max = 2,
.rates = RT5682_STEREO_RATES,
.formats = RT5682_FORMATS,
},
.capture = {
.stream_name = "AIF1 Capture",
.channels_min = 1,
.channels_max = 2,
.rates = RT5682_STEREO_RATES,
.formats = RT5682_FORMATS,
},
.ops = &rt5682_aif1_dai_ops,
},
{
.name = "rt5682-aif2",
.id = RT5682_AIF2,
.capture = {
.stream_name = "AIF2 Capture",
.channels_min = 1,
.channels_max = 2,
.rates = RT5682_STEREO_RATES,
.formats = RT5682_FORMATS,
},
.ops = &rt5682_aif2_dai_ops,
},
};
static int rt5682_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct rt5682_platform_data *pdata = dev_get_platdata(&i2c->dev);
struct rt5682_priv *rt5682;
int i, ret;
unsigned int val;
rt5682 = devm_kzalloc(&i2c->dev, sizeof(struct rt5682_priv),
GFP_KERNEL);
if (!rt5682)
return -ENOMEM;
i2c_set_clientdata(i2c, rt5682);
rt5682->pdata = i2s_default_platform_data;
if (pdata)
rt5682->pdata = *pdata;
else
rt5682_parse_dt(rt5682, &i2c->dev);
rt5682->regmap = devm_regmap_init_i2c(i2c, &rt5682_regmap);
if (IS_ERR(rt5682->regmap)) {
ret = PTR_ERR(rt5682->regmap);
dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
ret);
return ret;
}
for (i = 0; i < ARRAY_SIZE(rt5682->supplies); i++)
rt5682->supplies[i].supply = rt5682_supply_names[i];
ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(rt5682->supplies),
rt5682->supplies);
if (ret) {
dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
return ret;
}
ret = regulator_bulk_enable(ARRAY_SIZE(rt5682->supplies),
rt5682->supplies);
if (ret) {
dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
return ret;
}
if (gpio_is_valid(rt5682->pdata.ldo1_en)) {
if (devm_gpio_request_one(&i2c->dev, rt5682->pdata.ldo1_en,
GPIOF_OUT_INIT_HIGH, "rt5682"))
dev_err(&i2c->dev, "Fail gpio_request gpio_ldo\n");
}
/* Sleep for 300 ms miniumum */
usleep_range(300000, 350000);
regmap_write(rt5682->regmap, RT5682_I2C_MODE, 0x1);
usleep_range(10000, 15000);
regmap_read(rt5682->regmap, RT5682_DEVICE_ID, &val);
if (val != DEVICE_ID) {
dev_err(&i2c->dev,
"Device with ID register %x is not rt5682\n", val);
return -ENODEV;
}
mutex_init(&rt5682->calibrate_mutex);
rt5682_calibrate(rt5682);
rt5682_apply_patch_list(rt5682, &i2c->dev);
regmap_write(rt5682->regmap, RT5682_DEPOP_1, 0x0000);
/* DMIC pin*/
if (rt5682->pdata.dmic1_data_pin != RT5682_DMIC1_NULL) {
switch (rt5682->pdata.dmic1_data_pin) {
case RT5682_DMIC1_DATA_GPIO2: /* share with LRCK2 */
regmap_update_bits(rt5682->regmap, RT5682_DMIC_CTRL_1,
RT5682_DMIC_1_DP_MASK, RT5682_DMIC_1_DP_GPIO2);
regmap_update_bits(rt5682->regmap, RT5682_GPIO_CTRL_1,
RT5682_GP2_PIN_MASK, RT5682_GP2_PIN_DMIC_SDA);
break;
case RT5682_DMIC1_DATA_GPIO5: /* share with DACDAT1 */
regmap_update_bits(rt5682->regmap, RT5682_DMIC_CTRL_1,
RT5682_DMIC_1_DP_MASK, RT5682_DMIC_1_DP_GPIO5);
regmap_update_bits(rt5682->regmap, RT5682_GPIO_CTRL_1,
RT5682_GP5_PIN_MASK, RT5682_GP5_PIN_DMIC_SDA);
break;
default:
dev_warn(&i2c->dev, "invalid DMIC_DAT pin\n");
break;
}
switch (rt5682->pdata.dmic1_clk_pin) {
case RT5682_DMIC1_CLK_GPIO1: /* share with IRQ */
regmap_update_bits(rt5682->regmap, RT5682_GPIO_CTRL_1,
RT5682_GP1_PIN_MASK, RT5682_GP1_PIN_DMIC_CLK);
break;
case RT5682_DMIC1_CLK_GPIO3: /* share with BCLK2 */
regmap_update_bits(rt5682->regmap, RT5682_GPIO_CTRL_1,
RT5682_GP3_PIN_MASK, RT5682_GP3_PIN_DMIC_CLK);
break;
default:
dev_warn(&i2c->dev, "invalid DMIC_CLK pin\n");
break;
}
}
regmap_update_bits(rt5682->regmap, RT5682_PWR_ANLG_1,
RT5682_LDO1_DVO_MASK | RT5682_HP_DRIVER_MASK,
RT5682_LDO1_DVO_12 | RT5682_HP_DRIVER_5X);
regmap_write(rt5682->regmap, RT5682_MICBIAS_2, 0x0380);
regmap_update_bits(rt5682->regmap, RT5682_GPIO_CTRL_1,
RT5682_GP4_PIN_MASK | RT5682_GP5_PIN_MASK,
RT5682_GP4_PIN_ADCDAT1 | RT5682_GP5_PIN_DACDAT1);
regmap_write(rt5682->regmap, RT5682_TEST_MODE_CTRL_1, 0x0000);
regmap_update_bits(rt5682->regmap, RT5682_BIAS_CUR_CTRL_8,
RT5682_HPA_CP_BIAS_CTRL_MASK, RT5682_HPA_CP_BIAS_3UA);
regmap_update_bits(rt5682->regmap, RT5682_CHARGE_PUMP_1,
RT5682_CP_CLK_HP_MASK, RT5682_CP_CLK_HP_300KHZ);
regmap_update_bits(rt5682->regmap, RT5682_HP_CHARGE_PUMP_1,
RT5682_PM_HP_MASK, RT5682_PM_HP_HV);
regmap_update_bits(rt5682->regmap, RT5682_DMIC_CTRL_1,
RT5682_FIFO_CLK_DIV_MASK, RT5682_FIFO_CLK_DIV_2);
INIT_DELAYED_WORK(&rt5682->jack_detect_work,
rt5682_jack_detect_handler);
INIT_DELAYED_WORK(&rt5682->jd_check_work,
rt5682_jd_check_handler);
if (i2c->irq) {
ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
rt5682_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
| IRQF_ONESHOT, "rt5682", rt5682);
if (ret)
dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
}
return devm_snd_soc_register_component(&i2c->dev,
&rt5682_soc_component_dev,
rt5682_dai, ARRAY_SIZE(rt5682_dai));
}
static void rt5682_i2c_shutdown(struct i2c_client *client)
{
struct rt5682_priv *rt5682 = i2c_get_clientdata(client);
rt5682_reset(rt5682);
}
static const struct of_device_id rt5682_of_match[] = {
{.compatible = "realtek,rt5682i"},
{},
};
MODULE_DEVICE_TABLE(of, rt5682_of_match);
static const struct acpi_device_id rt5682_acpi_match[] = {
{"10EC5682", 0,},
{},
};
MODULE_DEVICE_TABLE(acpi, rt5682_acpi_match);
static const struct i2c_device_id rt5682_i2c_id[] = {
{"rt5682", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, rt5682_i2c_id);
static struct i2c_driver rt5682_i2c_driver = {
.driver = {
.name = "rt5682",
.of_match_table = rt5682_of_match,
.acpi_match_table = rt5682_acpi_match,
},
.probe = rt5682_i2c_probe,
.shutdown = rt5682_i2c_shutdown,
.id_table = rt5682_i2c_id,
};
module_i2c_driver(rt5682_i2c_driver);
MODULE_DESCRIPTION("ASoC RT5682 driver");
MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
MODULE_LICENSE("GPL v2");

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