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
317 changed files with 15037 additions and 3929 deletions

View File

@@ -17,6 +17,8 @@ properties:
compatible: compatible:
enum: enum:
- fsl,imx8qxp-dsp - fsl,imx8qxp-dsp
- fsl,imx8qm-dsp
- fsl,imx8mp-dsp
reg: reg:
description: Should contain register location and length 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: Required properties:
- compatible : Should be "dlg,da7213" - compatible : Should be "dlg,da7212" or "dlg,da7213"
- reg: Specifies the I2C slave address - reg: Specifies the I2C slave address
Optional properties: Optional properties:
@@ -21,6 +21,10 @@ Optional properties:
- dlg,dmic-clkrate : DMIC clock frequency (Hz). - dlg,dmic-clkrate : DMIC clock frequency (Hz).
[<1500000>, <3000000>] [<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: Example:

View File

@@ -51,6 +51,10 @@ Optional properties:
will be in use as default. Otherwise, the big endian will be in use as default. Otherwise, the big endian
mode will be in use for all the device registers. 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: Example:
asrc: asrc@2034000 { 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,imx35-esai",
"fsl,vf610-esai", "fsl,vf610-esai",
"fsl,imx6ull-esai", "fsl,imx6ull-esai",
"fsl,imx8qm-esai",
- reg : Offset and length of the register set for the device. - 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. This device supports I2C only.
Required properties: Required properties:
- compatible : "nuvoton,nau8810" - compatible : One of "nuvoton,nau8810" or "nuvoton,nau8812" or
"nuvoton,nau8814"
- reg : the I2C address of the device. - 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,hp-det-gpios : The GPIO that detect headphones are plugged in
- nvidia,int-mic-en-gpios : The GPIO that enables the internal microphone - 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,ext-mic-en-gpios : The GPIO that enables the external microphone
- nvidia,headset : The Mic Jack represents state of the headset microphone pin
Example: Example:

View File

@@ -30,6 +30,8 @@ Required properties:
- reg : Must contain an address for each entry in reg-names. - reg : Must contain an address for each entry in reg-names.
- reg-names : A list which must include the following entries: - reg-names : A list which must include the following entries:
* "lpass-lpaif" * "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 - 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: Example:
lpass@28100000 { lpass@28100000 {
@@ -51,4 +67,13 @@ lpass@28100000 {
reg = <0x28100000 0x10000>; reg = <0x28100000 0x10000>;
reg-names = "lpass-lpaif"; reg-names = "lpass-lpaif";
qcom,adsp = <&adsp>; 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 Definition: Must be 0
= EXAMPLE = EXAMPLE
q6adm@8 { apr-service@8 {
compatible = "qcom,q6adm"; compatible = "qcom,q6adm";
reg = <APR_SVC_ADM>; reg = <APR_SVC_ADM>;
q6routing: routing { q6routing: routing {

View File

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

View File

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

View File

@@ -15,7 +15,7 @@ used by the apr service device.
example "qcom,q6core-v2.0" example "qcom,q6core-v2.0"
= EXAMPLE = EXAMPLE
q6core@3 { apr-service@3 {
compatible = "qcom,q6core"; compatible = "qcom,q6core";
reg = <APR_SVC_ADSP_CORE>; 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-gen2" if generation2 (or RZ/G1)
"renesas,rcar_sound-gen3" if generation3 (or RZ/G2) "renesas,rcar_sound-gen3" if generation3 (or RZ/G2)
Examples with soctypes are: Examples with soctypes are:
- "renesas,rcar_sound-r8a7742" (RZ/G1H)
- "renesas,rcar_sound-r8a7743" (RZ/G1M) - "renesas,rcar_sound-r8a7743" (RZ/G1M)
- "renesas,rcar_sound-r8a7744" (RZ/G1N) - "renesas,rcar_sound-r8a7744" (RZ/G1N)
- "renesas,rcar_sound-r8a7745" (RZ/G1E) - "renesas,rcar_sound-r8a7745" (RZ/G1E)

View File

@@ -24,6 +24,7 @@ properties:
- rockchip,rk3188-i2s - rockchip,rk3188-i2s
- rockchip,rk3228-i2s - rockchip,rk3228-i2s
- rockchip,rk3288-i2s - rockchip,rk3288-i2s
- rockchip,rk3308-i2s
- rockchip,rk3328-i2s - rockchip,rk3328-i2s
- rockchip,rk3366-i2s - rockchip,rk3366-i2s
- rockchip,rk3368-i2s - rockchip,rk3368-i2s
@@ -47,14 +48,15 @@ properties:
- const: i2s_hclk - const: i2s_hclk
dmas: dmas:
items: minItems: 1
- description: TX DMA Channel maxItems: 2
- description: RX DMA Channel
dma-names: dma-names:
items: oneOf:
- const: tx
- const: rx - const: rx
- items:
- const: tx
- const: rx
power-domains: power-domains:
maxItems: 1 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 - $ref: /schemas/types.yaml#/definitions/uint32
- enum: [0, 1, 2] - 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: required:
- compatible - compatible
- reg - reg
@@ -77,6 +126,8 @@ examples:
compatible = "ti,tlv320adc5140"; compatible = "ti,tlv320adc5140";
reg = <0x4c>; reg = <0x4c>;
ti,mic-bias-source = <6>; 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>; 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 - #gpio-cells : Must be 2. The first cell is the pin number and the
second cell is used to specify optional parameters (currently unused). second cell is used to specify optional parameters (currently unused).
- AVDD2-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply, - power supplies for the device, as covered in
SPKVDD1-supply, SPKVDD2-supply : power supplies for the device, as covered Documentation/devicetree/bindings/regulator/regulator.txt, depending
in Documentation/devicetree/bindings/regulator/regulator.txt 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: Optional properties:
@@ -73,11 +79,11 @@ wm8994: codec@1a {
lineout1-se; lineout1-se;
AVDD1-supply = <&regulator>;
AVDD2-supply = <&regulator>; AVDD2-supply = <&regulator>;
CPVDD-supply = <&regulator>; CPVDD-supply = <&regulator>;
DBVDD1-supply = <&regulator>; DBVDD-supply = <&regulator>;
DBVDD2-supply = <&regulator>; DCVDD-supply = <&regulator>;
DBVDD3-supply = <&regulator>;
SPKVDD1-supply = <&regulator>; SPKVDD1-supply = <&regulator>;
SPKVDD2-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 */ /* Set stream pointer on all CODEC DAIs */
for (i = 0; i < rtd->num_codecs; i++) { 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); substream->stream);
if (ret < 0) { if (ret < 0) {
dev_err(dai->dev, "failed to set stream pointer on codec dai %s", 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; 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. * 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++) order++)
/* component interface */ /* 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 { struct snd_soc_component_driver {
const char *name; const char *name;
@@ -108,7 +146,7 @@ struct snd_soc_component_driver {
struct snd_pcm_substream *substream, struct snd_pcm_substream *substream,
struct vm_area_struct *vma); 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 */ /* probe ordering - for components with runtime dependencies */
int probe_order; 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); return dev_get_drvdata(c->dev);
} }
static inline bool snd_soc_component_is_active( static inline unsigned int
struct snd_soc_component *component) snd_soc_component_active(struct snd_soc_component *component)
{ {
return component->active != 0; return component->active;
} }
/* component pin */ /* component pin */

View File

@@ -154,21 +154,59 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream); struct snd_pcm_substream *substream);
void snd_soc_dai_shutdown(struct snd_soc_dai *dai, void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream); 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, snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream); struct snd_pcm_substream *substream);
void snd_soc_dai_suspend(struct snd_soc_dai *dai); void snd_soc_dai_suspend(struct snd_soc_dai *dai);
void snd_soc_dai_resume(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, int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
struct snd_soc_pcm_runtime *rtd, int num); struct snd_soc_pcm_runtime *rtd, int num);
bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream); 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 { struct snd_soc_dai_ops {
/* /*
@@ -326,8 +364,6 @@ struct snd_soc_dai {
/* DAI runtime info */ /* DAI runtime info */
unsigned int stream_active[SNDRV_PCM_STREAM_LAST + 1]; /* usage count */ 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 *playback_widget;
struct snd_soc_dapm_widget *capture_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); 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 #endif

View File

@@ -689,7 +689,7 @@ struct snd_soc_dapm_context {
/* A list of widgets associated with an object, typically a snd_kcontrol */ /* A list of widgets associated with an object, typically a snd_kcontrol */
struct snd_soc_dapm_widget_list { struct snd_soc_dapm_widget_list {
int num_widgets; int num_widgets;
struct snd_soc_dapm_widget *widgets[0]; struct snd_soc_dapm_widget *widgets[];
}; };
#define for_each_dapm_widgets(list, i, widget) \ #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, 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_register_card(struct snd_soc_card *card);
int snd_soc_unregister_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); 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); struct snd_soc_dai_link *dai_link);
bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd); 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, int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hardware *hw, int stream); 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); const struct snd_pcm_hardware *hw);
/* Jack reporting */ /* 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); 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, int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
struct snd_soc_jack_pin *pins); 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, struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
void *data, const char *long_name, void *data, const char *long_name,
const char *prefix); 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, int snd_soc_add_component_controls(struct snd_soc_component *component,
const struct snd_kcontrol_new *controls, unsigned int num_controls); const struct snd_kcontrol_new *controls, unsigned int num_controls);
int snd_soc_add_card_controls(struct snd_soc_card *soc_card, 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; const struct snd_soc_compr_ops *compr_ops;
/* Mark this pcm with non atomic ops */ /* Mark this pcm with non atomic ops */
bool nonatomic; unsigned int nonatomic:1;
/* For unidirectional dai links */ /* For unidirectional dai links */
unsigned int playback_only:1; unsigned int playback_only:1;
@@ -1002,9 +1002,6 @@ struct snd_soc_card {
spinlock_t dpcm_lock; spinlock_t dpcm_lock;
bool instantiated;
bool topology_shortname_created;
int (*probe)(struct snd_soc_card *card); int (*probe)(struct snd_soc_card *card);
int (*late_probe)(struct snd_soc_card *card); int (*late_probe)(struct snd_soc_card *card);
int (*remove)(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; int num_of_dapm_widgets;
const struct snd_soc_dapm_route *of_dapm_routes; const struct snd_soc_dapm_route *of_dapm_routes;
int num_of_dapm_routes; int num_of_dapm_routes;
bool fully_routed;
bool disable_route_checks;
/* lists of probed devices belonging to this card */ /* lists of probed devices belonging to this card */
struct list_head component_dev_list; struct list_head component_dev_list;
@@ -1093,6 +1088,13 @@ struct snd_soc_card {
#endif #endif
u32 pop_time; 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; void *drvdata;
}; };
#define for_each_card_prelinks(card, i, link) \ #define for_each_card_prelinks(card, i, link) \
@@ -1143,14 +1145,16 @@ struct snd_soc_pcm_runtime {
/* runtime devices */ /* runtime devices */
struct snd_pcm *pcm; struct snd_pcm *pcm;
struct snd_compr *compr; 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 **dais;
struct snd_soc_dai **codec_dais;
unsigned int num_codecs; unsigned int num_codecs;
struct snd_soc_dai **cpu_dais;
unsigned int num_cpus; unsigned int num_cpus;
struct snd_soc_dapm_widget *playback_widget; struct snd_soc_dapm_widget *playback_widget;
@@ -1170,28 +1174,28 @@ struct snd_soc_pcm_runtime {
unsigned int fe_compr:1; /* for Dynamic PCM */ unsigned int fe_compr:1; /* for Dynamic PCM */
int num_components; 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() */ /* see soc_new_pcm_runtime() */
#define asoc_rtd_to_cpu(rtd, n) (rtd)->dais[n] #define asoc_rtd_to_cpu(rtd, n) (rtd)->dais[n]
#define asoc_rtd_to_codec(rtd, n) (rtd)->dais[n + (rtd)->num_cpus] #define asoc_rtd_to_codec(rtd, n) (rtd)->dais[n + (rtd)->num_cpus]
#define for_each_rtd_components(rtd, i, component) \ #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) < rtd->num_components) && ((component) = rtd->components[i]);\
(i)++) (i)++)
#define for_each_rtd_cpu_dais(rtd, i, dai) \ #define for_each_rtd_cpu_dais(rtd, i, dai) \
for ((i) = 0; \ for ((i) = 0; \
((i) < rtd->num_cpus) && ((dai) = rtd->cpu_dais[i]); \ ((i) < rtd->num_cpus) && ((dai) = asoc_rtd_to_cpu(rtd, i)); \
(i)++) (i)++)
#define for_each_rtd_cpu_dais_rollback(rtd, i, dai) \ #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) \ #define for_each_rtd_codec_dais(rtd, i, dai) \
for ((i) = 0; \ for ((i) = 0; \
((i) < rtd->num_codecs) && ((dai) = rtd->codec_dais[i]); \ ((i) < rtd->num_codecs) && ((dai) = asoc_rtd_to_codec(rtd, i)); \
(i)++) (i)++)
#define for_each_rtd_codec_dais_rollback(rtd, i, dai) \ #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) \ #define for_each_rtd_dais(rtd, i, dai) \
for ((i) = 0; \ for ((i) = 0; \
((i) < (rtd)->num_cpus + (rtd)->num_codecs) && \ ((i) < (rtd)->num_cpus + (rtd)->num_codecs) && \
@@ -1252,29 +1256,16 @@ struct soc_enum {
#endif #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) static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
{ {
if (mc->reg == mc->rreg && mc->shift == mc->rshift) 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 && mc->shift != mc->rshift, or
* mc->reg != mc->rreg means that the control is * mc->reg != mc->rreg means that the control is
* stereo (bits in one register or in two registers) * 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, 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> #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 static inline
int snd_soc_fixup_dai_links_platform_name(struct snd_soc_card *card, int snd_soc_fixup_dai_links_platform_name(struct snd_soc_card *card,
const char *platform_name) 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-component.h>
#include <sound/soc-card.h>
#endif #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 * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * redistributing this file, you may do so under either license.
@@ -27,6 +27,9 @@ struct snd_sof_pdata {
struct device *dev; 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 * notification callback used if the hardware initialization
* can take time or is handled in a workqueue. This callback * 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 * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * 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 * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * 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 * 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 * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * redistributing this file, you may do so under either license.
@@ -49,6 +49,9 @@
/* bclk idle */ /* bclk idle */
#define SOF_DAI_INTEL_SSP_CLKCTRL_BCLK_IDLE_HIGH BIT(5) #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 */ /* SSP Configuration Request - SOF_IPC_DAI_SSP_CONFIG */
struct sof_ipc_dai_ssp_params { struct sof_ipc_dai_ssp_params {
struct sof_ipc_hdr hdr; struct sof_ipc_hdr hdr;
@@ -85,15 +88,19 @@ struct sof_ipc_dai_ssp_params {
struct sof_ipc_dai_hda_params { struct sof_ipc_dai_hda_params {
struct sof_ipc_hdr hdr; struct sof_ipc_hdr hdr;
uint32_t link_dma_ch; uint32_t link_dma_ch;
uint32_t rate;
uint32_t channels;
} __packed; } __packed;
/* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */ /* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */
struct sof_ipc_dai_alh_params { struct sof_ipc_dai_alh_params {
struct sof_ipc_hdr hdr; struct sof_ipc_hdr hdr;
uint32_t stream_id; uint32_t stream_id;
uint32_t rate;
uint32_t channels;
/* reserved for future use */ /* reserved for future use */
uint32_t reserved[15]; uint32_t reserved[13];
} __packed; } __packed;
/* DMIC Configuration Request - SOF_IPC_DAI_DMIC_CONFIG */ /* 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 * 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 * 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 * 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) * 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 * 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 fifo_fs; /**< FIFO sample rate in Hz (8000..96000) */
uint32_t reserved_1; /**< Reserved */ uint32_t reserved_1; /**< Reserved */
uint16_t fifo_bits; /**< FIFO word length (16 or 32) */ 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_min; /**< Min. mic clock duty cycle in % (20..80) */
uint16_t duty_max; /**< Max. mic clock duty cycle in % (min..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 wake_up_time; /**< Time from clock start to data (us) */
uint32_t min_clock_on_time; /**< Min. time that clk is kept on (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 */ /* reserved for future use */
uint32_t reserved[5]; uint32_t reserved[5];
/**< variable number of pdm controller config */ /**< PDM controllers configuration */
struct sof_ipc_dai_dmic_pdm_ctrl pdm[0]; struct sof_ipc_dai_dmic_pdm_ctrl pdm[SOF_DAI_INTEL_DMIC_NUM_CTRL];
} __packed; } __packed;
#endif #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 * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * 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 * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * 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 * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * 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_UNUSED = 0,
SOF_IPC_EXT_WINDOW = 1, SOF_IPC_EXT_WINDOW = 1,
SOF_IPC_EXT_CC_INFO = 2, 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 */ /* FW version - SOF_IPC_GLB_VERSION */
@@ -109,9 +111,27 @@ struct sof_ipc_cc_version {
/* reserved for future use */ /* reserved for future use */
uint32_t reserved[4]; uint32_t reserved[4];
char name[16]; /* null terminated compiler name */ uint8_t name[16]; /* null terminated compiler name */
char optim[4]; /* null terminated compiler -O flag value */ uint8_t optim[4]; /* null terminated compiler -O flag value */
char desc[]; /* null terminated compiler description */ uint8_t desc[32]; /* null terminated compiler description */
} __packed; } __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 #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 * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * 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 * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * 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 * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * 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_SELECTOR, /**< channel selector component */
SOF_COMP_DEMUX, SOF_COMP_DEMUX,
SOF_COMP_ASRC, /**< Asynchronous sample rate converter */ SOF_COMP_ASRC, /**< Asynchronous sample rate converter */
SOF_COMP_DCBLOCK,
SOF_COMP_SMART_AMP, /**< smart amplifier component */
/* keep FILEREAD/FILEWRITE as the last ones */ /* keep FILEREAD/FILEWRITE as the last ones */
SOF_COMP_FILEREAD = 10000, /**< host test based file IO */ SOF_COMP_FILEREAD = 10000, /**< host test based file IO */
SOF_COMP_FILEWRITE = 10001, /**< 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_CACHE (1 << 6) /**< cacheable */
#define SOF_MEM_CAPS_EXEC (1 << 7) /**< executable */ #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 */ /* create new component buffer - SOF_IPC_TPLG_BUFFER_NEW */
struct sof_ipc_buffer { struct sof_ipc_buffer {
struct sof_ipc_comp comp; struct sof_ipc_comp comp;
uint32_t size; /**< buffer size in bytes */ uint32_t size; /**< buffer size in bytes */
uint32_t caps; /**< SOF_MEM_CAPS_ */ uint32_t caps; /**< SOF_MEM_CAPS_ */
uint32_t flags; /**< SOF_BUF_ flags defined above */
uint32_t reserved; /**< reserved for future use */
} __packed; } __packed;
/* generic component config data - must always be after struct sof_ipc_comp */ /* 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_CHAN_SELECTOR, /**< Channel Selector */
SOF_PROCESS_MUX, SOF_PROCESS_MUX,
SOF_PROCESS_DEMUX, SOF_PROCESS_DEMUX,
SOF_PROCESS_DCBLOCK,
SOF_PROCESS_SMART_AMP, /**< Smart Amplifier */
}; };
/* generic "effect", "codec" or proprietary processing component */ /* generic "effect", "codec" or proprietary processing component */
@@ -218,7 +234,7 @@ struct sof_ipc_comp_process {
/* reserved for future use */ /* reserved for future use */
uint32_t reserved[7]; uint32_t reserved[7];
unsigned char data[0]; uint8_t data[0];
} __packed; } __packed;
/* frees components, buffers and pipelines /* 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 * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * 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_panic_info {
struct sof_ipc_hdr hdr; struct sof_ipc_hdr hdr;
uint32_t code; /* SOF_IPC_PANIC_ */ uint32_t code; /* SOF_IPC_PANIC_ */
char filename[SOF_TRACE_FILENAME_SIZE]; uint8_t filename[SOF_TRACE_FILENAME_SIZE];
uint32_t linenum; uint32_t linenum;
} __packed; } __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 * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * 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_BYTE_TLV 0x100
#define SKL_CONTROL_TYPE_MIC_SELECT 0x102 #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 HDA_SST_CFG_MAX 900 /* size of copier cfg*/
#define MAX_IN_QUEUE 8 #define MAX_IN_QUEUE 8

View File

@@ -26,7 +26,7 @@
/* SOF ABI version major, minor and patch numbers */ /* SOF ABI version major, minor and patch numbers */
#define SOF_ABI_MAJOR 3 #define SOF_ABI_MAJOR 3
#define SOF_ABI_MINOR 13 #define SOF_ABI_MINOR 16
#define SOF_ABI_PATCH 0 #define SOF_ABI_PATCH 0
/* SOF ABI version number. Format within 32bit word is MMmmmppp */ /* 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_USE 1300
#define SOF_TKN_MUTE_LED_DIRECTION 1301 #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 #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 // Copyright (c) 2015-2019 Intel Corporation
#include <linux/acpi.h> #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(0x8086280f, "Icelake HDMI", patch_i915_icl_hdmi),
HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi), HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi),
HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_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(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi), HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi),
HDA_CODEC_ENTRY(0x80862883, "Braswell 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 # 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-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 snd-soc-core-$(CONFIG_SND_SOC_COMPRESS) += soc-compress.o
ifneq ($(CONFIG_SND_SOC_TOPOLOGY),) ifneq ($(CONFIG_SND_SOC_TOPOLOGY),)

View File

@@ -29,10 +29,23 @@ config SND_SOC_AMD_ACP3x
config SND_SOC_AMD_RV_RT5682_MACH config SND_SOC_AMD_RV_RT5682_MACH
tristate "AMD RV support for RT5682" tristate "AMD RV support for RT5682"
select SND_SOC_RT5682 select SND_SOC_RT5682_I2C
select SND_SOC_MAX98357A select SND_SOC_MAX98357A
select SND_SOC_CROS_EC_CODEC select SND_SOC_CROS_EC_CODEC
select I2C_CROS_EC_TUNNEL select I2C_CROS_EC_TUNNEL
depends on SND_SOC_AMD_ACP3x && I2C && CROS_EC depends on SND_SOC_AMD_ACP3x && I2C && CROS_EC
help help
This option enables machine driver for RT5682 and MAX9835. 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_CZ_RT5645_MACH) += snd-soc-acp-rt5645-mach.o
obj-$(CONFIG_SND_SOC_AMD_ACP3x) += raven/ 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_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" #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, static int acp3x_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
unsigned int fmt) 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 = { 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 = { 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_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com");
MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver"); MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" DRV_NAME); MODULE_ALIAS("platform:"DRV_NAME);

View File

@@ -15,7 +15,7 @@
#include "acp3x.h" #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 = { static const struct snd_pcm_hardware acp3x_pcm_hardware_playback = {
.info = SNDRV_PCM_INFO_INTERLEAVED | .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_pcm_runtime *prtd;
struct snd_soc_card *card; struct snd_soc_card *card;
struct acp3x_platform_info *pinfo;
struct i2s_stream_instance *rtd; struct i2s_stream_instance *rtd;
u32 pos; u32 pos;
u32 buffersize; u32 buffersize;
@@ -312,13 +311,6 @@ static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_soc_component *component,
prtd = substream->private_data; prtd = substream->private_data;
card = prtd->card; card = prtd->card;
rtd = substream->runtime->private_data; 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, buffersize = frames_to_bytes(substream->runtime,
substream->runtime->buffer_size); substream->runtime->buffer_size);
@@ -542,4 +534,4 @@ MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com");
MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver"); MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver");
MODULE_LICENSE("GPL v2"); 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 atmel_ssc_info *ssc_p;
struct platform_device *pdev = to_platform_device(component->dev); struct platform_device *pdev = to_platform_device(component->dev);
if (!component->active) if (!snd_soc_component_active(component))
return 0; return 0;
ssc_p = &ssc_info[pdev->id]; 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); struct platform_device *pdev = to_platform_device(component->dev);
u32 cr; u32 cr;
if (!component->active) if (!snd_soc_component_active(component))
return 0; return 0;
ssc_p = &ssc_info[pdev->id]; 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); BCM2835_I2S_CS_A_REG, mask, 0);
/* Stop also the clock when not SND_SOC_DAIFMT_CONT */ /* 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); 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); struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
if (dai->active) if (snd_soc_dai_active(dai))
return 0; return 0;
/* Should this still be running stop it */ /* 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); bcm2835_i2s_stop(dev, substream, dai);
/* If both streams are stopped, disable module and clock */ /* If both streams are stopped, disable module and clock */
if (dai->active) if (snd_soc_dai_active(dai))
return; return;
/* Disable the module */ /* 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); struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
if (!cpu_dai->active) if (!snd_soc_dai_active(cpu_dai))
return 0; return 0;
if (!aio->is_slave) { 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); struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
int error; int error;
if (!cpu_dai->active) if (!snd_soc_dai_active(cpu_dai))
return 0; return 0;
if (!aio->is_slave) { 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); struct ep93xx_i2s_info *info = snd_soc_component_get_drvdata(component);
if (!component->active) if (!snd_soc_component_active(component))
return 0; return 0;
ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK); 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); struct ep93xx_i2s_info *info = snd_soc_component_get_drvdata(component);
if (!component->active) if (!snd_soc_component_active(component))
return 0; return 0;
ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK); 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_MAX98926
imply SND_SOC_MAX98927 imply SND_SOC_MAX98927
imply SND_SOC_MAX98373 imply SND_SOC_MAX98373
imply SND_SOC_MAX98390
imply SND_SOC_MAX9850 imply SND_SOC_MAX9850
imply SND_SOC_MAX9860 imply SND_SOC_MAX9860
imply SND_SOC_MAX9759 imply SND_SOC_MAX9759
@@ -167,7 +168,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_RT5668 imply SND_SOC_RT5668
imply SND_SOC_RT5670 imply SND_SOC_RT5670
imply SND_SOC_RT5677 imply SND_SOC_RT5677
imply SND_SOC_RT5682 imply SND_SOC_RT5682_I2C
imply SND_SOC_RT5682_SDW imply SND_SOC_RT5682_SDW
imply SND_SOC_RT700_SDW imply SND_SOC_RT700_SDW
imply SND_SOC_RT711_SDW imply SND_SOC_RT711_SDW
@@ -272,6 +273,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_WM9712 imply SND_SOC_WM9712
imply SND_SOC_WM9713 imply SND_SOC_WM9713
imply SND_SOC_WSA881X imply SND_SOC_WSA881X
imply SND_SOC_ZL38060
help help
Normally ASoC codec drivers are only built if a machine driver which 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 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 config SND_SOC_CROS_EC_CODEC
tristate "codec driver for ChromeOS EC" tristate "codec driver for ChromeOS EC"
depends on CROS_EC depends on CROS_EC
select CRYPTO select CRYPTO_LIB_SHA256
select CRYPTO_SHA256
help help
If you say yes here you will get support for the If you say yes here you will get support for the
ChromeOS Embedded Controller's Audio Codec. ChromeOS Embedded Controller's Audio Codec.
@@ -681,6 +682,7 @@ config SND_SOC_CX2072X
config SND_SOC_JZ4740_CODEC config SND_SOC_JZ4740_CODEC
depends on MIPS || COMPILE_TEST depends on MIPS || COMPILE_TEST
depends on OF
select REGMAP_MMIO select REGMAP_MMIO
tristate "Ingenic JZ4740 internal CODEC" tristate "Ingenic JZ4740 internal CODEC"
help help
@@ -692,6 +694,7 @@ config SND_SOC_JZ4740_CODEC
config SND_SOC_JZ4725B_CODEC config SND_SOC_JZ4725B_CODEC
depends on MIPS || COMPILE_TEST depends on MIPS || COMPILE_TEST
depends on OF
select REGMAP select REGMAP
tristate "Ingenic JZ4725B internal CODEC" tristate "Ingenic JZ4725B internal CODEC"
help help
@@ -703,6 +706,7 @@ config SND_SOC_JZ4725B_CODEC
config SND_SOC_JZ4770_CODEC config SND_SOC_JZ4770_CODEC
depends on MIPS || COMPILE_TEST depends on MIPS || COMPILE_TEST
depends on OF
select REGMAP select REGMAP
tristate "Ingenic JZ4770 internal CODEC" tristate "Ingenic JZ4770 internal CODEC"
help help
@@ -717,7 +721,7 @@ config SND_SOC_L3
config SND_SOC_DA7210 config SND_SOC_DA7210
tristate tristate
depends on I2C depends on SND_SOC_I2C_AND_SPI
config SND_SOC_DA7213 config SND_SOC_DA7213
tristate "Dialog DA7213 CODEC" tristate "Dialog DA7213 CODEC"
@@ -867,6 +871,10 @@ config SND_SOC_MAX98373
tristate "Maxim Integrated MAX98373 Speaker Amplifier" tristate "Maxim Integrated MAX98373 Speaker Amplifier"
depends on I2C depends on I2C
config SND_SOC_MAX98390
tristate "Maxim Integrated MAX98390 Speaker Amplifier"
depends on I2C
config SND_SOC_MAX9850 config SND_SOC_MAX9850
tristate tristate
depends on I2C depends on I2C
@@ -1135,7 +1143,11 @@ config SND_SOC_RT5677_SPI
config SND_SOC_RT5682 config SND_SOC_RT5682
tristate tristate
depends on I2C || SOUNDWIRE
config SND_SOC_RT5682_I2C
tristate
depends on I2C
select SND_SOC_RT5682
config SND_SOC_RT5682_SDW config SND_SOC_RT5682_SDW
tristate "Realtek RT5682 Codec - SDW" tristate "Realtek RT5682 Codec - SDW"
@@ -1569,7 +1581,7 @@ config SND_SOC_WM8978
config SND_SOC_WM8983 config SND_SOC_WM8983
tristate tristate
depends on I2C depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8985 config SND_SOC_WM8985
tristate "Wolfson Microelectronics WM8985 and WM8758 codec driver" tristate "Wolfson Microelectronics WM8985 and WM8758 codec driver"
@@ -1620,19 +1632,19 @@ config SND_SOC_WM9090
config SND_SOC_WM9705 config SND_SOC_WM9705
tristate tristate
depends on SND_SOC_AC97_BUS depends on SND_SOC_AC97_BUS || AC97_BUS_NEW
select REGMAP_AC97 select REGMAP_AC97
select AC97_BUS_COMPAT if AC97_BUS_NEW select AC97_BUS_COMPAT if AC97_BUS_NEW
config SND_SOC_WM9712 config SND_SOC_WM9712
tristate tristate
depends on SND_SOC_AC97_BUS depends on SND_SOC_AC97_BUS || AC97_BUS_NEW
select REGMAP_AC97 select REGMAP_AC97
select AC97_BUS_COMPAT if AC97_BUS_NEW select AC97_BUS_COMPAT if AC97_BUS_NEW
config SND_SOC_WM9713 config SND_SOC_WM9713
tristate tristate
depends on SND_SOC_AC97_BUS depends on SND_SOC_AC97_BUS || AC97_BUS_NEW
select REGMAP_AC97 select REGMAP_AC97
select AC97_BUS_COMPAT if AC97_BUS_NEW 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 This enables support for Qualcomm WSA8810/WSA8815 Class-D
Smart Speaker Amplifier. 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 config SND_SOC_ZX_AUD96P22
tristate "ZTE ZX AUD96P22 CODEC" tristate "ZTE ZX AUD96P22 CODEC"
depends on I2C depends on I2C

View File

@@ -115,6 +115,7 @@ snd-soc-max98925-objs := max98925.o
snd-soc-max98926-objs := max98926.o snd-soc-max98926-objs := max98926.o
snd-soc-max98927-objs := max98927.o snd-soc-max98927-objs := max98927.o
snd-soc-max98373-objs := max98373.o snd-soc-max98373-objs := max98373.o
snd-soc-max98390-objs := max98390.o
snd-soc-max9850-objs := max9850.o snd-soc-max9850-objs := max9850.o
snd-soc-max9860-objs := max9860.o snd-soc-max9860-objs := max9860.o
snd-soc-mc13783-objs := mc13783.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-rt5677-spi-objs := rt5677-spi.o
snd-soc-rt5682-objs := rt5682.o snd-soc-rt5682-objs := rt5682.o
snd-soc-rt5682-sdw-objs := rt5682-sdw.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-rt700-objs := rt700.o rt700-sdw.o
snd-soc-rt711-objs := rt711.o rt711-sdw.o snd-soc-rt711-objs := rt711.o rt711-sdw.o
snd-soc-rt715-objs := rt715.o rt715-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-wm9713-objs := wm9713.o
snd-soc-wm-hubs-objs := wm_hubs.o snd-soc-wm-hubs-objs := wm_hubs.o
snd-soc-wsa881x-objs := wsa881x.o snd-soc-wsa881x-objs := wsa881x.o
snd-soc-zl38060-objs := zl38060.o
snd-soc-zx-aud96p22-objs := zx_aud96p22.o snd-soc-zx-aud96p22-objs := zx_aud96p22.o
# Amp # Amp
snd-soc-max9877-objs := max9877.o 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_MAX98926) += snd-soc-max98926.o
obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o
obj-$(CONFIG_SND_SOC_MAX98373) += snd-soc-max98373.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_MAX9850) += snd-soc-max9850.o
obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o
obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.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) += snd-soc-rt5677.o
obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.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) += 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_RT5682_SDW) += snd-soc-rt5682-sdw.o
obj-$(CONFIG_SND_SOC_RT700) += snd-soc-rt700.o obj-$(CONFIG_SND_SOC_RT700) += snd-soc-rt700.o
obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.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_ADSP) += snd-soc-wm-adsp.o
obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.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_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 obj-$(CONFIG_SND_SOC_ZX_AUD96P22) += snd-soc-zx-aud96p22.o
# Amp # Amp

View File

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

View File

@@ -2,7 +2,7 @@
/* /*
* ad73311.c -- ALSA Soc AD73311 codec support * ad73311.c -- ALSA Soc AD73311 codec support
* *
* Copyright: Analog Device Inc. * Copyright: Analog Devices Inc.
* Author: Cliff Cai <cliff.cai@analog.com> * 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 snd_soc_component *component = dai->component;
struct adav80x *adav80x = snd_soc_component_get_drvdata(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 0;
return snd_pcm_hw_constraint_single(substream->runtime, 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 snd_soc_component *component = dai->component;
struct adav80x *adav80x = snd_soc_component_get_drvdata(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; 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) if (clk_id == dai_priv->clk)
return 0; return 0;
if (dai->active) { if (snd_soc_dai_active(dai)) {
dev_err(component->dev, "Can't change clock on active DAI %d\n", dev_err(component->dev, "Can't change clock on active DAI %d\n",
dai->id); dai->id);
return -EBUSY; return -EBUSY;

View File

@@ -8,7 +8,6 @@
* EC for audio function. * EC for audio function.
*/ */
#include <crypto/hash.h>
#include <crypto/sha.h> #include <crypto/sha.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/delay.h> #include <linux/delay.h>
@@ -107,24 +106,11 @@ error:
static int calculate_sha256(struct cros_ec_codec_priv *priv, static int calculate_sha256(struct cros_ec_codec_priv *priv,
uint8_t *buf, uint32_t size, uint8_t *digest) 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); sha256_init(&sctx);
if (IS_ERR(tfm)) { sha256_update(&sctx, buf, size);
dev_err(priv->dev, "can't alloc shash\n"); sha256_final(&sctx, digest);
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);
#ifdef DEBUG #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 && 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 && (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, ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
CS4271_MODE2_PDN, CS4271_MODE2_PDN,
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_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 cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
struct madera_priv *priv = &cs47l15->core; struct madera_priv *priv = &cs47l15->core;
struct madera *madera = priv->madera; struct madera *madera = priv->madera;
@@ -1329,7 +1328,7 @@ static unsigned int cs47l15_digital_vu[] = {
MADERA_DAC_DIGITAL_VOLUME_5R, 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, .open = &cs47l15_open,
.free = &wm_adsp_compr_free, .free = &wm_adsp_compr_free,
.set_params = &wm_adsp_compr_set_params, .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_sysclk = &madera_set_sysclk,
.set_pll = &cs47l15_set_fll, .set_pll = &cs47l15_set_fll,
.name = DRV_NAME, .name = DRV_NAME,
.compr_ops = &cs47l15_compr_ops, .compress_ops = &cs47l15_compress_ops,
.controls = cs47l15_snd_controls, .controls = cs47l15_snd_controls,
.num_controls = ARRAY_SIZE(cs47l15_snd_controls), .num_controls = ARRAY_SIZE(cs47l15_snd_controls),
.dapm_widgets = cs47l15_dapm_widgets, .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_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 cs47l24_priv *priv = snd_soc_component_get_drvdata(component);
struct arizona *arizona = priv->core.arizona; struct arizona *arizona = priv->core.arizona;
int n_adsp; int n_adsp;
@@ -1178,7 +1178,7 @@ static unsigned int cs47l24_digital_vu[] = {
ARIZONA_DAC_DIGITAL_VOLUME_4L, ARIZONA_DAC_DIGITAL_VOLUME_4L,
}; };
static struct snd_compr_ops cs47l24_compr_ops = { static struct snd_compress_ops cs47l24_compress_ops = {
.open = cs47l24_open, .open = cs47l24_open,
.free = wm_adsp_compr_free, .free = wm_adsp_compr_free,
.set_params = wm_adsp_compr_set_params, .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_sysclk = arizona_set_sysclk,
.set_pll = cs47l24_set_fll, .set_pll = cs47l24_set_fll,
.name = DRV_NAME, .name = DRV_NAME,
.compr_ops = &cs47l24_compr_ops, .compress_ops = &cs47l24_compress_ops,
.controls = cs47l24_snd_controls, .controls = cs47l24_snd_controls,
.num_controls = ARRAY_SIZE(cs47l24_snd_controls), .num_controls = ARRAY_SIZE(cs47l24_snd_controls),
.dapm_widgets = cs47l24_dapm_widgets, .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_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 cs47l35 *cs47l35 = snd_soc_component_get_drvdata(component);
struct madera_priv *priv = &cs47l35->core; struct madera_priv *priv = &cs47l35->core;
struct madera *madera = priv->madera; struct madera *madera = priv->madera;
@@ -1622,7 +1621,7 @@ static unsigned int cs47l35_digital_vu[] = {
MADERA_DAC_DIGITAL_VOLUME_5R, 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, .open = &cs47l35_open,
.free = &wm_adsp_compr_free, .free = &wm_adsp_compr_free,
.set_params = &wm_adsp_compr_set_params, .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_sysclk = &madera_set_sysclk,
.set_pll = &cs47l35_set_fll, .set_pll = &cs47l35_set_fll,
.name = DRV_NAME, .name = DRV_NAME,
.compr_ops = &cs47l35_compr_ops, .compress_ops = &cs47l35_compress_ops,
.controls = cs47l35_snd_controls, .controls = cs47l35_snd_controls,
.num_controls = ARRAY_SIZE(cs47l35_snd_controls), .num_controls = ARRAY_SIZE(cs47l35_snd_controls),
.dapm_widgets = cs47l35_dapm_widgets, .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_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 cs47l85 *cs47l85 = snd_soc_component_get_drvdata(component);
struct madera_priv *priv = &cs47l85->core; struct madera_priv *priv = &cs47l85->core;
struct madera *madera = priv->madera; struct madera *madera = priv->madera;
@@ -2566,7 +2565,7 @@ static const unsigned int cs47l85_digital_vu[] = {
MADERA_DAC_DIGITAL_VOLUME_6R, 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, .open = &cs47l85_open,
.free = &wm_adsp_compr_free, .free = &wm_adsp_compr_free,
.set_params = &wm_adsp_compr_set_params, .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_sysclk = &madera_set_sysclk,
.set_pll = &cs47l85_set_fll, .set_pll = &cs47l85_set_fll,
.name = DRV_NAME, .name = DRV_NAME,
.compr_ops = &cs47l85_compr_ops, .compress_ops = &cs47l85_compress_ops,
.controls = cs47l85_snd_controls, .controls = cs47l85_snd_controls,
.num_controls = ARRAY_SIZE(cs47l85_snd_controls), .num_controls = ARRAY_SIZE(cs47l85_snd_controls),
.dapm_widgets = cs47l85_dapm_widgets, .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_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 cs47l90 *cs47l90 = snd_soc_component_get_drvdata(component);
struct madera_priv *priv = &cs47l90->core; struct madera_priv *priv = &cs47l90->core;
struct madera *madera = priv->madera; struct madera *madera = priv->madera;
@@ -2473,7 +2472,7 @@ static unsigned int cs47l90_digital_vu[] = {
MADERA_DAC_DIGITAL_VOLUME_5R, 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, .open = &cs47l90_open,
.free = &wm_adsp_compr_free, .free = &wm_adsp_compr_free,
.set_params = &wm_adsp_compr_set_params, .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_sysclk = &madera_set_sysclk,
.set_pll = &cs47l90_set_fll, .set_pll = &cs47l90_set_fll,
.name = DRV_NAME, .name = DRV_NAME,
.compr_ops = &cs47l90_compr_ops, .compress_ops = &cs47l90_compress_ops,
.controls = cs47l90_snd_controls, .controls = cs47l90_snd_controls,
.num_controls = ARRAY_SIZE(cs47l90_snd_controls), .num_controls = ARRAY_SIZE(cs47l90_snd_controls),
.dapm_widgets = cs47l90_dapm_widgets, .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_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 cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component);
struct madera_priv *priv = &cs47l92->core; struct madera_priv *priv = &cs47l92->core;
struct madera *madera = priv->madera; struct madera *madera = priv->madera;
@@ -1933,7 +1932,7 @@ static unsigned int cs47l92_digital_vu[] = {
MADERA_DAC_DIGITAL_VOLUME_5R, 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, .open = &cs47l92_open,
.free = &wm_adsp_compr_free, .free = &wm_adsp_compr_free,
.set_params = &wm_adsp_compr_set_params, .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_sysclk = &madera_set_sysclk,
.set_pll = &cs47l92_set_fll, .set_pll = &cs47l92_set_fll,
.name = DRV_NAME, .name = DRV_NAME,
.compr_ops = &cs47l92_compr_ops, .compress_ops = &cs47l92_compress_ops,
.controls = cs47l92_snd_controls, .controls = cs47l92_snd_controls,
.num_controls = ARRAY_SIZE(cs47l92_snd_controls), .num_controls = ARRAY_SIZE(cs47l92_snd_controls),
.dapm_widgets = cs47l92_dapm_widgets, .dapm_widgets = cs47l92_dapm_widgets,

View File

@@ -19,6 +19,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <linux/pm_runtime.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/initval.h> #include <sound/initval.h>
#include <sound/tlv.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[] = { static const struct snd_soc_dapm_widget da7213_dapm_widgets[] = {
/*
* Power Supply
*/
SND_SOC_DAPM_REGULATOR_SUPPLY("VDDMIC", 0, 0),
/* /*
* Input & Output * Input & Output
*/ */
@@ -932,6 +938,9 @@ static const struct snd_soc_dapm_route da7213_audio_map[] = {
/* Dest Connecting Widget source */ /* Dest Connecting Widget source */
/* Input path */ /* Input path */
{"Mic Bias 1", NULL, "VDDMIC"},
{"Mic Bias 2", NULL, "VDDMIC"},
{"MIC1", NULL, "Mic Bias 1"}, {"MIC1", NULL, "Mic Bias 1"},
{"MIC2", NULL, "Mic Bias 2"}, {"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 |\ #define DA7213_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai, static int da7213_set_component_sysclk(struct snd_soc_component *component,
int clk_id, unsigned int freq, int dir) 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); struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
int ret = 0; int ret = 0;
@@ -1345,7 +1354,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
return 0; return 0;
if (((freq < 5000000) && (freq != 32768)) || (freq > 54000000)) { 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); freq);
return -EINVAL; return -EINVAL;
} }
@@ -1361,7 +1370,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
DA7213_PLL_MCLK_SQR_EN); DA7213_PLL_MCLK_SQR_EN);
break; break;
default: 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; 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); freq = clk_round_rate(da7213->mclk, freq);
ret = clk_set_rate(da7213->mclk, freq); ret = clk_set_rate(da7213->mclk, freq);
if (ret) { 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); freq);
return ret; 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. */ /* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */
static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, static int da7213_set_component_pll(struct snd_soc_component *component,
int source, unsigned int fref, unsigned int fout) 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); struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
u8 pll_ctrl, indiv_bits, indiv; 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 = { static const struct snd_soc_dai_ops da7213_dai_ops = {
.hw_params = da7213_hw_params, .hw_params = da7213_hw_params,
.set_fmt = da7213_set_dai_fmt, .set_fmt = da7213_set_dai_fmt,
.set_sysclk = da7213_set_dai_sysclk,
.set_pll = da7213_set_dai_pll,
.digital_mute = da7213_mute, .digital_mute = da7213_mute,
}; };
@@ -1571,6 +1578,7 @@ static int da7213_set_bias_level(struct snd_soc_component *component,
#if defined(CONFIG_OF) #if defined(CONFIG_OF)
/* DT */ /* DT */
static const struct of_device_id da7213_of_match[] = { static const struct of_device_id da7213_of_match[] = {
{ .compatible = "dlg,da7212", },
{ .compatible = "dlg,da7213", }, { .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); struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
pm_runtime_get_sync(component->dev);
/* Default to using ALC auto offset calibration mode. */ /* Default to using ALC auto offset calibration mode. */
snd_soc_component_update_bits(component, DA7213_ALC_CTRL1, snd_soc_component_update_bits(component, DA7213_ALC_CTRL1,
DA7213_ALC_CALIB_MODE_MAN, 0); 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); DA7213_DMIC_CLK_RATE_MASK, dmic_cfg);
} }
pm_runtime_put_sync(component->dev);
/* Check if MCLK provided */ /* Check if MCLK provided */
da7213->mclk = devm_clk_get(component->dev, "mclk"); da7213->mclk = devm_clk_get(component->dev, "mclk");
if (IS_ERR(da7213->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), .num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets),
.dapm_routes = da7213_audio_map, .dapm_routes = da7213_audio_map,
.num_dapm_routes = ARRAY_SIZE(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, .idle_bias_on = 1,
.use_pmdown_time = 1, .use_pmdown_time = 1,
.endianness = 1, .endianness = 1,
@@ -1847,11 +1861,22 @@ static const struct regmap_config da7213_regmap_config = {
.cache_type = REGCACHE_RBTREE, .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, static int da7213_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct da7213_priv *da7213; struct da7213_priv *da7213;
int ret; int i, ret;
da7213 = devm_kzalloc(&i2c->dev, sizeof(*da7213), GFP_KERNEL); da7213 = devm_kzalloc(&i2c->dev, sizeof(*da7213), GFP_KERNEL);
if (!da7213) if (!da7213)
@@ -1859,6 +1884,25 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, da7213); 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); da7213->regmap = devm_regmap_init_i2c(i2c, &da7213_regmap_config);
if (IS_ERR(da7213->regmap)) { if (IS_ERR(da7213->regmap)) {
ret = PTR_ERR(da7213->regmap); ret = PTR_ERR(da7213->regmap);
@@ -1866,6 +1910,11 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
return ret; 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, ret = devm_snd_soc_register_component(&i2c->dev,
&soc_component_dev_da7213, &da7213_dai, 1); &soc_component_dev_da7213, &da7213_dai, 1);
if (ret < 0) { if (ret < 0) {
@@ -1875,6 +1924,34 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
return ret; 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[] = { static const struct i2c_device_id da7213_i2c_id[] = {
{ "da7213", 0 }, { "da7213", 0 },
{ } { }
@@ -1887,6 +1964,7 @@ static struct i2c_driver da7213_i2c_driver = {
.name = "da7213", .name = "da7213",
.of_match_table = of_match_ptr(da7213_of_match), .of_match_table = of_match_ptr(da7213_of_match),
.acpi_match_table = ACPI_PTR(da7213_acpi_match), .acpi_match_table = ACPI_PTR(da7213_acpi_match),
.pm = &da7213_pm,
}, },
.probe = da7213_i2c_probe, .probe = da7213_i2c_probe,
.id_table = da7213_i2c_id, .id_table = da7213_i2c_id,

View File

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

View File

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

View File

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

View File

@@ -344,19 +344,17 @@ static int jz4740_codec_probe(struct platform_device *pdev)
return ret; return ret;
} }
#ifdef CONFIG_OF
static const struct of_device_id jz4740_codec_of_matches[] = { static const struct of_device_id jz4740_codec_of_matches[] = {
{ .compatible = "ingenic,jz4740-codec", }, { .compatible = "ingenic,jz4740-codec", },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, jz4740_codec_of_matches); MODULE_DEVICE_TABLE(of, jz4740_codec_of_matches);
#endif
static struct platform_driver jz4740_codec_driver = { static struct platform_driver jz4740_codec_driver = {
.probe = jz4740_codec_probe, .probe = jz4740_codec_probe,
.driver = { .driver = {
.name = "jz4740-codec", .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, .probe = jz4770_codec_probe,
.driver = { .driver = {
.name = "jz4770-codec", .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); 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)) if (is_sync == madera_is_syncclk(dai_priv->clk))
return 0; return 0;
if (dai->active) { if (snd_soc_dai_active(dai)) {
dev_err(component->dev, "Can't change clock on active DAI %d\n", dev_err(component->dev, "Can't change clock on active DAI %d\n",
dai->id); dai->id);
return -EBUSY; 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_START:
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 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, queue_delayed_work(system_power_efficient_wq,
&max98090->pll_det_enable_work, &max98090->pll_det_enable_work,
msecs_to_jiffies(10)); 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_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 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); schedule_work(&max98090->pll_det_disable_work);
break; break;
default: default:
@@ -2109,7 +2109,7 @@ static void max98090_pll_work(struct max98090_priv *max98090)
unsigned int pll; unsigned int pll;
int i; int i;
if (!snd_soc_component_is_active(component)) if (!snd_soc_component_active(component))
return; return;
dev_info_ratelimited(component->dev, "PLL unlocked\n"); 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_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, static SOC_ENUM_SINGLE_DECL(max9867_filter, MAX9867_CODECFLTR, 7,
max9867_filter_text); 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, static SOC_ENUM_SINGLE_DECL(max9867_spkmode, MAX9867_MODECONFIG, 0,
max9867_spmode); max9867_spmode);
static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max9867_master_tlv, 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("Volume Smoothing Switch", MAX9867_MODECONFIG, 6, 1, 0),
SOC_SINGLE("Line ZC Switch", MAX9867_MODECONFIG, 5, 1, 0), SOC_SINGLE("Line ZC Switch", MAX9867_MODECONFIG, 5, 1, 0),
SOC_ENUM("DSP Filter", max9867_filter), 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 */ /* Input mixer */
@@ -88,20 +104,38 @@ static const struct snd_kcontrol_new max9867_line_out_control =
SOC_DAPM_DOUBLE_R("Switch", SOC_DAPM_DOUBLE_R("Switch",
MAX9867_LEFTVOL, MAX9867_RIGHTVOL, 6, 1, 1); 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[] = { static const struct snd_soc_dapm_widget max9867_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("MICL"), SND_SOC_DAPM_INPUT("MICL"),
SND_SOC_DAPM_INPUT("MICR"), SND_SOC_DAPM_INPUT("MICR"),
SND_SOC_DAPM_INPUT("DMICL"),
SND_SOC_DAPM_INPUT("DMICR"),
SND_SOC_DAPM_INPUT("LINL"), SND_SOC_DAPM_INPUT("LINL"),
SND_SOC_DAPM_INPUT("LINR"), SND_SOC_DAPM_INPUT("LINR"),
SND_SOC_DAPM_PGA("Left Line Input", MAX9867_PWRMAN, 6, 0, NULL, 0), SND_SOC_DAPM_PGA("Left Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_PGA("Right Line Input", MAX9867_PWRMAN, 5, 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, SND_SOC_DAPM_MIXER_NAMED_CTL("Input Mixer", SND_SOC_NOPM, 0, 0,
max9867_input_mixer_controls, max9867_input_mixer_controls,
ARRAY_SIZE(max9867_input_mixer_controls)), ARRAY_SIZE(max9867_input_mixer_controls)),
SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", MAX9867_PWRMAN, 1, 0), SND_SOC_DAPM_MUX("DMICL Mux", SND_SOC_NOPM, 0, 0,
SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", MAX9867_PWRMAN, 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, SND_SOC_DAPM_MIXER("Digital", SND_SOC_NOPM, 0, 0,
max9867_sidetone_mixer_controls, 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, SND_SOC_DAPM_MIXER_NAMED_CTL("Output Mixer", SND_SOC_NOPM, 0, 0,
max9867_output_mixer_controls, max9867_output_mixer_controls,
ARRAY_SIZE(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("DACL", "HiFi Playback", SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC("DACR", "HiFi Playback", MAX9867_PWRMAN, 2, 0), SND_SOC_DAPM_DAC("DACR", "HiFi Playback", SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_SWITCH("Master Playback", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_SWITCH("Master Playback", SND_SOC_NOPM, 0, 0,
&max9867_line_out_control), &max9867_line_out_control),
SND_SOC_DAPM_OUTPUT("LOUT"), 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", "Mic Capture Switch", "MICR"},
{"Input Mixer", "Line Capture Switch", "Left Line Input"}, {"Input Mixer", "Line Capture Switch", "Left Line Input"},
{"Input Mixer", "Line Capture Switch", "Right Line Input"}, {"Input Mixer", "Line Capture Switch", "Right Line Input"},
{"ADCL", NULL, "Input Mixer"}, {"DMICL Mux", "DMIC", "DMICL"},
{"ADCR", NULL, "Input Mixer"}, {"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", "ADCL"},
{"Digital", "Sidetone Switch", "ADCR"}, {"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_IFC1A, iface1A);
regmap_write(max9867->regmap, MAX9867_IFC1B, iface1B); regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
MAX9867_IFC1B_BCLK_MASK, iface1B);
return 0; return 0;
} }
@@ -413,15 +452,14 @@ static int max9867_set_bias_level(struct snd_soc_component *component,
if (err) if (err)
return err; return err;
err = regmap_update_bits(max9867->regmap, MAX9867_PWRMAN, err = regmap_write(max9867->regmap,
MAX9867_SHTDOWN, MAX9867_SHTDOWN); MAX9867_PWRMAN, 0xff);
if (err) if (err)
return err; return err;
} }
break; break;
case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF:
err = regmap_update_bits(max9867->regmap, MAX9867_PWRMAN, err = regmap_write(max9867->regmap, MAX9867_PWRMAN, 0);
MAX9867_SHTDOWN, 0);
if (err) if (err)
return 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 = { static const struct regmap_config max9867_regmap = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
.max_register = MAX9867_REVISION, .max_register = MAX9867_REVISION,
.reg_defaults = max9867_reg,
.num_reg_defaults = ARRAY_SIZE(max9867_reg),
.volatile_reg = max9867_volatile_register, .volatile_reg = max9867_volatile_register,
.cache_type = REGCACHE_RBTREE, .cache_type = REGCACHE_RBTREE,
}; };

View File

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

View File

@@ -355,6 +355,8 @@ static const struct snd_kcontrol_new nau8810_snd_controls[] = {
/* Speaker Output Mixer */ /* Speaker Output Mixer */
static const struct snd_kcontrol_new nau8810_speaker_mixer_controls[] = { 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, SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_SPKMIX,
NAU8810_BYPSPK_SFT, 1, 0), NAU8810_BYPSPK_SFT, 1, 0),
SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_SPKMIX, 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 */ /* Mono Output Mixer */
static const struct snd_kcontrol_new nau8810_mono_mixer_controls[] = { 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, SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_MONOMIX,
NAU8810_BYPMOUT_SFT, 1, 0), NAU8810_BYPMOUT_SFT, 1, 0),
SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_MONOMIX, 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 */ /* PGA Mute */
static const struct snd_kcontrol_new nau8810_pgaboost_mixer_controls[] = { 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, SOC_DAPM_SINGLE("PGA Mute Switch", NAU8810_REG_PGAGAIN,
NAU8810_PGAMT_SFT, 1, 1), NAU8810_PGAMT_SFT, 1, 1),
SOC_DAPM_SINGLE("PMIC PGA Switch", NAU8810_REG_ADCBOOST, 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 */ /* Input PGA */
static const struct snd_kcontrol_new nau8810_inpga[] = { 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, SOC_DAPM_SINGLE("MicN Switch", NAU8810_REG_INPUT_SIGNAL,
NAU8810_NMICPGA_SFT, 1, 0), NAU8810_NMICPGA_SFT, 1, 0),
SOC_DAPM_SINGLE("MicP Switch", NAU8810_REG_INPUT_SIGNAL, 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); 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[] = { static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = {
SND_SOC_DAPM_MIXER("Speaker Mixer", NAU8810_REG_POWER3, SND_SOC_DAPM_MIXER("Speaker Mixer", NAU8810_REG_POWER3,
NAU8810_SPKMX_EN_SFT, 0, &nau8810_speaker_mixer_controls[0], 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, SND_SOC_DAPM_MIXER("Input Boost Stage", NAU8810_REG_POWER2,
NAU8810_BST_EN_SFT, 0, nau8810_pgaboost_mixer_controls, NAU8810_BST_EN_SFT, 0, nau8810_pgaboost_mixer_controls,
ARRAY_SIZE(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, SND_SOC_DAPM_SUPPLY("Mic Bias", NAU8810_REG_POWER1,
NAU8810_MICBIAS_EN_SFT, 0, NULL, 0), 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, SND_SOC_DAPM_SWITCH("Digital Loopback", SND_SOC_NOPM, 0, 0,
&nau8810_loopback), &nau8810_loopback),
SND_SOC_DAPM_INPUT("AUX"),
SND_SOC_DAPM_INPUT("MICN"), SND_SOC_DAPM_INPUT("MICN"),
SND_SOC_DAPM_INPUT("MICP"), SND_SOC_DAPM_INPUT("MICP"),
SND_SOC_DAPM_OUTPUT("MONOOUT"), 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}, {"DAC", NULL, "PLL", check_mclk_select_pll},
/* Mono output mixer */ /* Mono output mixer */
{"Mono Mixer", "AUX Bypass Switch", "AUX Input"},
{"Mono Mixer", "PCM Playback Switch", "DAC"}, {"Mono Mixer", "PCM Playback Switch", "DAC"},
{"Mono Mixer", "Line Bypass Switch", "Input Boost Stage"}, {"Mono Mixer", "Line Bypass Switch", "Input Boost Stage"},
/* Speaker output mixer */ /* Speaker output mixer */
{"Speaker Mixer", "AUX Bypass Switch", "AUX Input"},
{"Speaker Mixer", "PCM Playback Switch", "DAC"}, {"Speaker Mixer", "PCM Playback Switch", "DAC"},
{"Speaker Mixer", "Line Bypass Switch", "Input Boost Stage"}, {"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 */ /* Input Boost Stage */
{"ADC", NULL, "Input Boost Stage"}, {"ADC", NULL, "Input Boost Stage"},
{"ADC", NULL, "PLL", check_mclk_select_pll}, {"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", "PGA Mute Switch", "Input PGA"},
{"Input Boost Stage", "PMIC PGA Switch", "MICP"}, {"Input Boost Stage", "PMIC PGA Switch", "MICP"},
/* Input PGA */ /* 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", "MicN Switch", "MICN"},
{"Input PGA", "MicP Switch", "MICP"}, {"Input PGA", "MicP Switch", "MICP"},
{"AUX Input", NULL, "AUX"},
/* Digital Looptack */ /* Digital Looptack */
{"Digital Loopback", "Switch", "ADC"}, {"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[] = { static const struct i2c_device_id nau8810_i2c_id[] = {
{ "nau8810", 0 }, { "nau8810", 0 },
{ "nau8812", 0 },
{ "nau8814", 0 },
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, nau8810_i2c_id); MODULE_DEVICE_TABLE(i2c, nau8810_i2c_id);
@@ -869,6 +904,8 @@ MODULE_DEVICE_TABLE(i2c, nau8810_i2c_id);
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct of_device_id nau8810_of_match[] = { static const struct of_device_id nau8810_of_match[] = {
{ .compatible = "nuvoton,nau8810", }, { .compatible = "nuvoton,nau8810", },
{ .compatible = "nuvoton,nau8812", },
{ .compatible = "nuvoton,nau8814", },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, nau8810_of_match); MODULE_DEVICE_TABLE(of, nau8810_of_match);

View File

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

View File

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

View File

@@ -18,6 +18,7 @@
struct rl6231_pll_code { struct rl6231_pll_code {
bool m_bp; /* Indicates bypass m code or not. */ bool m_bp; /* Indicates bypass m code or not. */
bool k_bp; /* Indicates bypass k code or not. */
int m_code; int m_code;
int n_code; int n_code;
int k_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, snd_soc_component_write(component,
RT1015_CLSD_INTERNAL9, 0x0140); RT1015_CLSD_INTERNAL9, 0x0140);
snd_soc_component_write(component, snd_soc_component_write(component,
RT1015_GAT_BOOST, 0x00fe); RT1015_GAT_BOOST, 0x0efe);
snd_soc_component_write(component, snd_soc_component_write(component,
RT1015_PWR_STATE_CTRL, 0x000d); RT1015_PWR_STATE_CTRL, 0x000d);
msleep(500); msleep(500);
@@ -780,6 +780,14 @@ static int rt1015_set_component_pll(struct snd_soc_component *component,
freq_out == rt1015->pll_out) freq_out == rt1015->pll_out)
return 0; 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) { switch (source) {
case RT1015_PLL_S_MCLK: case RT1015_PLL_S_MCLK:
snd_soc_component_update_bits(component, RT1015_CLK2, 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; 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) static int rt1015_probe(struct snd_soc_component *component)
{ {
struct rt1015_priv *rt1015 = struct rt1015_priv *rt1015 =
snd_soc_component_get_drvdata(component); snd_soc_component_get_drvdata(component);
rt1015->component = component; rt1015->component = component;
rt1015->bclk_ratio = 0;
snd_soc_component_write(component, RT1015_BAT_RPO_STEP1, 0x061c); snd_soc_component_write(component, RT1015_BAT_RPO_STEP1, 0x061c);
return 0; 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 = { static struct snd_soc_dai_ops rt1015_aif_dai_ops = {
.hw_params = rt1015_hw_params, .hw_params = rt1015_hw_params,
.set_fmt = rt1015_set_dai_fmt, .set_fmt = rt1015_set_dai_fmt,
.set_bclk_ratio = rt1015_set_bclk_ratio,
}; };
static struct snd_soc_dai_driver rt1015_dai[] = { static struct snd_soc_dai_driver rt1015_dai[] = {

View File

@@ -362,6 +362,7 @@ struct rt1015_priv {
int sysclk_src; int sysclk_src;
int lrck; int lrck;
int bclk; int bclk;
int bclk_ratio;
int id; int id;
int pll_src; int pll_src;
int pll_in; 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) if (rt1308->hw_init)
return 0; return 0;
ret = rt1308_read_prop(slave);
if (ret < 0)
goto _io_init_err_;
if (rt1308->first_hw_init) { if (rt1308->first_hw_init) {
regcache_cache_only(rt1308->regmap, false); regcache_cache_only(rt1308->regmap, false);
regcache_cache_bypass(rt1308->regmap, true); 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; efuse_c_btl_r = tmp;
regmap_read(rt1308->regmap, 0xc872, &tmp); regmap_read(rt1308->regmap, 0xc872, &tmp);
efuse_c_btl_r = efuse_c_btl_r | (tmp << 8); 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); 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); efuse_c_btl_l, efuse_c_btl_r);
/* initial settings */ /* 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__); dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);
_io_init_err_:
return ret; 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; struct sdw_stream_data *stream;
if (!sdw_stream)
return 0;
stream = kzalloc(sizeof(*stream), GFP_KERNEL); stream = kzalloc(sizeof(*stream), GFP_KERNEL);
if (!stream) if (!stream)
return -ENOMEM; return -ENOMEM;
@@ -684,9 +682,6 @@ static int rt1308_sdw_probe(struct sdw_slave *slave,
{ {
struct regmap *regmap; struct regmap *regmap;
/* Assign ops */
slave->ops = &rt1308_slave_ops;
/* Regmap Initialization */ /* Regmap Initialization */
regmap = devm_regmap_init_sdw(slave, &rt1308_sdw_regmap); regmap = devm_regmap_init_sdw(slave, &rt1308_sdw_regmap);
if (!regmap) if (!regmap)

View File

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