mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-15 16:53:54 +08:00
Merge remote-tracking branch 'asoc/for-5.8' into asoc-linus
This commit is contained in:
commit
358c7c61fd
@ -17,6 +17,8 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx8qxp-dsp
|
||||
- fsl,imx8qm-dsp
|
||||
- fsl,imx8mp-dsp
|
||||
|
||||
reg:
|
||||
description: Should contain register location and length
|
||||
|
@ -1,9 +1,9 @@
|
||||
Dialog Semiconductor DA7213 Audio Codec bindings
|
||||
Dialog Semiconductor DA7212/DA7213 Audio Codec bindings
|
||||
|
||||
======
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "dlg,da7213"
|
||||
- compatible : Should be "dlg,da7212" or "dlg,da7213"
|
||||
- reg: Specifies the I2C slave address
|
||||
|
||||
Optional properties:
|
||||
@ -21,6 +21,10 @@ Optional properties:
|
||||
- dlg,dmic-clkrate : DMIC clock frequency (Hz).
|
||||
[<1500000>, <3000000>]
|
||||
|
||||
- VDDA-supply : Regulator phandle for Analogue power supply
|
||||
- VDDMIC-supply : Regulator phandle for Mic Bias
|
||||
- VDDIO-supply : Regulator phandle for I/O power supply
|
||||
|
||||
======
|
||||
|
||||
Example:
|
||||
|
@ -51,6 +51,10 @@ Optional properties:
|
||||
will be in use as default. Otherwise, the big endian
|
||||
mode will be in use for all the device registers.
|
||||
|
||||
- fsl,asrc-format : Defines a mutual sample format used by DPCM Back
|
||||
Ends, which can replace the fsl,asrc-width.
|
||||
The value is 2 (S16_LE), or 6 (S24_LE).
|
||||
|
||||
Example:
|
||||
|
||||
asrc: asrc@2034000 {
|
||||
|
101
Documentation/devicetree/bindings/sound/fsl,easrc.yaml
Normal file
101
Documentation/devicetree/bindings/sound/fsl,easrc.yaml
Normal 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>;
|
||||
};
|
@ -12,6 +12,7 @@ Required properties:
|
||||
"fsl,imx35-esai",
|
||||
"fsl,vf610-esai",
|
||||
"fsl,imx6ull-esai",
|
||||
"fsl,imx8qm-esai",
|
||||
|
||||
- reg : Offset and length of the register set for the device.
|
||||
|
||||
|
122
Documentation/devicetree/bindings/sound/marvell,mmp-sspa.yaml
Normal file
122
Documentation/devicetree/bindings/sound/marvell,mmp-sspa.yaml
Normal 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";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -1,10 +1,11 @@
|
||||
NAU8810 audio CODEC
|
||||
NAU8810/NAU8812/NAU8814 audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "nuvoton,nau8810"
|
||||
- compatible : One of "nuvoton,nau8810" or "nuvoton,nau8812" or
|
||||
"nuvoton,nau8814"
|
||||
|
||||
- reg : the I2C address of the device.
|
||||
|
||||
|
@ -29,6 +29,7 @@ Optional properties:
|
||||
- nvidia,hp-det-gpios : The GPIO that detect headphones are plugged in
|
||||
- nvidia,int-mic-en-gpios : The GPIO that enables the internal microphone
|
||||
- nvidia,ext-mic-en-gpios : The GPIO that enables the external microphone
|
||||
- nvidia,headset : The Mic Jack represents state of the headset microphone pin
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -30,6 +30,8 @@ Required properties:
|
||||
- reg : Must contain an address for each entry in reg-names.
|
||||
- reg-names : A list which must include the following entries:
|
||||
* "lpass-lpaif"
|
||||
- #address-cells : Must be 1
|
||||
- #size-cells : Must be 0
|
||||
|
||||
|
||||
|
||||
@ -37,6 +39,20 @@ Optional properties:
|
||||
|
||||
- qcom,adsp : Phandle for the audio DSP node
|
||||
|
||||
By default, the driver uses up to 4 MI2S SD lines, for a total of 8 channels.
|
||||
The SD lines to use can be configured by adding subnodes for each of the DAIs.
|
||||
|
||||
Required properties for each DAI (represented by a subnode):
|
||||
- reg : Must be one of the DAI IDs
|
||||
(usually part of dt-bindings header)
|
||||
- qcom,playback-sd-lines: List of serial data lines to use for playback
|
||||
Each SD line should be represented by a number from 0-3.
|
||||
- qcom,capture-sd-lines : List of serial data lines to use for capture
|
||||
Each SD line should be represented by a number from 0-3.
|
||||
|
||||
Note that adding a subnode changes the default to "no lines configured",
|
||||
so both playback and capture lines should be configured when a subnode is added.
|
||||
|
||||
Example:
|
||||
|
||||
lpass@28100000 {
|
||||
@ -51,4 +67,13 @@ lpass@28100000 {
|
||||
reg = <0x28100000 0x10000>;
|
||||
reg-names = "lpass-lpaif";
|
||||
qcom,adsp = <&adsp>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/* Optional to set different MI2S SD lines */
|
||||
dai@3 {
|
||||
reg = <MI2S_QUATERNARY>;
|
||||
qcom,playback-sd-lines = <0 1>;
|
||||
};
|
||||
};
|
||||
|
@ -29,7 +29,7 @@ used by the apr service device.
|
||||
Definition: Must be 0
|
||||
|
||||
= EXAMPLE
|
||||
q6adm@8 {
|
||||
apr-service@8 {
|
||||
compatible = "qcom,q6adm";
|
||||
reg = <APR_SVC_ADM>;
|
||||
q6routing: routing {
|
||||
|
@ -100,7 +100,7 @@ configuration of each dai. Must contain the following properties.
|
||||
|
||||
= EXAMPLE
|
||||
|
||||
q6afe@4 {
|
||||
apr-service@4 {
|
||||
compatible = "qcom,q6afe";
|
||||
reg = <APR_SVC_AFE>;
|
||||
|
||||
@ -110,12 +110,12 @@ q6afe@4 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
hdmi@1 {
|
||||
reg = <1>;
|
||||
dai@1 {
|
||||
reg = <HDMI_RX>;
|
||||
};
|
||||
|
||||
tdm@24 {
|
||||
reg = <24>;
|
||||
dai@24 {
|
||||
reg = <PRIMARY_TDM_RX_0>;
|
||||
qcom,tdm-sync-mode = <1>:
|
||||
qcom,tdm-sync-src = <1>;
|
||||
qcom,tdm-data-out = <0>;
|
||||
@ -125,8 +125,8 @@ q6afe@4 {
|
||||
|
||||
};
|
||||
|
||||
tdm@25 {
|
||||
reg = <25>;
|
||||
dai@25 {
|
||||
reg = <PRIMARY_TDM_TX_0>;
|
||||
qcom,tdm-sync-mode = <1>:
|
||||
qcom,tdm-sync-src = <1>;
|
||||
qcom,tdm-data-out = <0>;
|
||||
@ -135,43 +135,43 @@ q6afe@4 {
|
||||
qcom,tdm-data-align = <0>;
|
||||
};
|
||||
|
||||
prim-mi2s-rx@16 {
|
||||
reg = <16>;
|
||||
dai@16 {
|
||||
reg = <PRIMARY_MI2S_RX>;
|
||||
qcom,sd-lines = <0 2>;
|
||||
};
|
||||
|
||||
prim-mi2s-tx@17 {
|
||||
reg = <17>;
|
||||
dai@17 {
|
||||
reg = <PRIMARY_MI2S_TX>;
|
||||
qcom,sd-lines = <1>;
|
||||
};
|
||||
|
||||
sec-mi2s-rx@18 {
|
||||
reg = <18>;
|
||||
dai@18 {
|
||||
reg = <SECONDARY_MI2S_RX>;
|
||||
qcom,sd-lines = <0 3>;
|
||||
};
|
||||
|
||||
sec-mi2s-tx@19 {
|
||||
reg = <19>;
|
||||
dai@19 {
|
||||
reg = <SECONDARY_MI2S_TX>;
|
||||
qcom,sd-lines = <1>;
|
||||
};
|
||||
|
||||
tert-mi2s-rx@20 {
|
||||
reg = <20>;
|
||||
dai@20 {
|
||||
reg = <TERTIARY_MI2S_RX>;
|
||||
qcom,sd-lines = <1 3>;
|
||||
};
|
||||
|
||||
tert-mi2s-tx@21 {
|
||||
reg = <21>;
|
||||
dai@21 {
|
||||
reg = <TERTIARY_MI2S_TX>;
|
||||
qcom,sd-lines = <0>;
|
||||
};
|
||||
|
||||
quat-mi2s-rx@22 {
|
||||
reg = <22>;
|
||||
dai@22 {
|
||||
reg = <QUATERNARY_MI2S_RX>;
|
||||
qcom,sd-lines = <0>;
|
||||
};
|
||||
|
||||
quat-mi2s-tx@23 {
|
||||
reg = <23>;
|
||||
dai@23 {
|
||||
reg = <QUATERNARY_MI2S_TX>;
|
||||
qcom,sd-lines = <1>;
|
||||
};
|
||||
};
|
||||
|
@ -51,13 +51,16 @@ configuration of each dai. Must contain the following properties.
|
||||
|
||||
= EXAMPLE
|
||||
|
||||
q6asm@7 {
|
||||
apr-service@7 {
|
||||
compatible = "qcom,q6asm";
|
||||
reg = <APR_SVC_ASM>;
|
||||
q6asmdai: dais {
|
||||
compatible = "qcom,q6asm-dais";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#sound-dai-cells = <1>;
|
||||
mm@0 {
|
||||
|
||||
dai@0 {
|
||||
reg = <0>;
|
||||
direction = <2>;
|
||||
is-compress-dai;
|
||||
|
@ -15,7 +15,7 @@ used by the apr service device.
|
||||
example "qcom,q6core-v2.0"
|
||||
|
||||
= EXAMPLE
|
||||
q6core@3 {
|
||||
apr-service@3 {
|
||||
compatible = "qcom,q6core";
|
||||
reg = <APR_SVC_ADSP_CORE>;
|
||||
};
|
||||
|
@ -263,6 +263,7 @@ Required properties:
|
||||
"renesas,rcar_sound-gen2" if generation2 (or RZ/G1)
|
||||
"renesas,rcar_sound-gen3" if generation3 (or RZ/G2)
|
||||
Examples with soctypes are:
|
||||
- "renesas,rcar_sound-r8a7742" (RZ/G1H)
|
||||
- "renesas,rcar_sound-r8a7743" (RZ/G1M)
|
||||
- "renesas,rcar_sound-r8a7744" (RZ/G1N)
|
||||
- "renesas,rcar_sound-r8a7745" (RZ/G1E)
|
||||
|
@ -24,6 +24,7 @@ properties:
|
||||
- rockchip,rk3188-i2s
|
||||
- rockchip,rk3228-i2s
|
||||
- rockchip,rk3288-i2s
|
||||
- rockchip,rk3308-i2s
|
||||
- rockchip,rk3328-i2s
|
||||
- rockchip,rk3366-i2s
|
||||
- rockchip,rk3368-i2s
|
||||
@ -47,12 +48,13 @@ properties:
|
||||
- const: i2s_hclk
|
||||
|
||||
dmas:
|
||||
items:
|
||||
- description: TX DMA Channel
|
||||
- description: RX DMA Channel
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
oneOf:
|
||||
- const: rx
|
||||
- items:
|
||||
- const: tx
|
||||
- const: rx
|
||||
|
||||
|
17
Documentation/devicetree/bindings/sound/rt1016.txt
Normal file
17
Documentation/devicetree/bindings/sound/rt1016.txt
Normal 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>;
|
||||
};
|
@ -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 = <&>;
|
||||
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>;
|
||||
};
|
||||
};
|
||||
};
|
484
Documentation/devicetree/bindings/sound/simple-card.yaml
Normal file
484
Documentation/devicetree/bindings/sound/simple-card.yaml
Normal 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 = <&>;
|
||||
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>;
|
||||
};
|
||||
};
|
||||
};
|
@ -63,6 +63,55 @@ properties:
|
||||
- $ref: /schemas/types.yaml#/definitions/uint32
|
||||
- enum: [0, 1, 2]
|
||||
|
||||
ti,pdm-edge-select:
|
||||
description: |
|
||||
Defines the PDMCLK sampling edge configuration for the PDM inputs. This
|
||||
array is defined as <PDMIN1 PDMIN2 PDMIN3 PDMIN4>.
|
||||
|
||||
0 - (default) Odd channel is latched on the negative edge and even
|
||||
channel is latched on the the positive edge.
|
||||
1 - Odd channel is latched on the positive edge and even channel is
|
||||
latched on the the negative edge.
|
||||
|
||||
PDMIN1 - PDMCLK latching edge used for channel 1 and 2 data
|
||||
PDMIN2 - PDMCLK latching edge used for channel 3 and 4 data
|
||||
PDMIN3 - PDMCLK latching edge used for channel 5 and 6 data
|
||||
PDMIN4 - PDMCLK latching edge used for channel 7 and 8 data
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
- minItems: 1
|
||||
maxItems: 4
|
||||
items:
|
||||
maximum: 1
|
||||
default: [0, 0, 0, 0]
|
||||
|
||||
ti,gpi-config:
|
||||
description: |
|
||||
Defines the configuration for the general purpose input pins (GPI).
|
||||
The array is defined as <GPI1 GPI2 GPI3 GPI4>.
|
||||
|
||||
0 - (default) disabled
|
||||
1 - GPIX is configured as a general-purpose input (GPI)
|
||||
2 - GPIX is configured as a master clock input (MCLK)
|
||||
3 - GPIX is configured as an ASI input for daisy-chain (SDIN)
|
||||
4 - GPIX is configured as a PDM data input for channel 1 and channel
|
||||
(PDMDIN1)
|
||||
5 - GPIX is configured as a PDM data input for channel 3 and channel
|
||||
(PDMDIN2)
|
||||
6 - GPIX is configured as a PDM data input for channel 5 and channel
|
||||
(PDMDIN3)
|
||||
7 - GPIX is configured as a PDM data input for channel 7 and channel
|
||||
(PDMDIN4)
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
- minItems: 1
|
||||
maxItems: 4
|
||||
items:
|
||||
maximum: 7
|
||||
default: [0, 0, 0, 0]
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@ -77,6 +126,8 @@ examples:
|
||||
compatible = "ti,tlv320adc5140";
|
||||
reg = <0x4c>;
|
||||
ti,mic-bias-source = <6>;
|
||||
ti,pdm-edge-select = <0 1 0 1>;
|
||||
ti,gpi-config = <4 5 6 7>;
|
||||
reset-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
@ -14,9 +14,15 @@ Required properties:
|
||||
- #gpio-cells : Must be 2. The first cell is the pin number and the
|
||||
second cell is used to specify optional parameters (currently unused).
|
||||
|
||||
- AVDD2-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply,
|
||||
SPKVDD1-supply, SPKVDD2-supply : power supplies for the device, as covered
|
||||
in Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
- power supplies for the device, as covered in
|
||||
Documentation/devicetree/bindings/regulator/regulator.txt, depending
|
||||
on compatible:
|
||||
- for wlf,wm1811 and wlf,wm8958:
|
||||
AVDD1-supply, AVDD2-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply,
|
||||
DCVDD-supply, CPVDD-supply, SPKVDD1-supply, SPKVDD2-supply
|
||||
- for wlf,wm8994:
|
||||
AVDD1-supply, AVDD2-supply, DBVDD-supply, DCVDD-supply, CPVDD-supply,
|
||||
SPKVDD1-supply, SPKVDD2-supply
|
||||
|
||||
Optional properties:
|
||||
|
||||
@ -73,11 +79,11 @@ wm8994: codec@1a {
|
||||
|
||||
lineout1-se;
|
||||
|
||||
AVDD1-supply = <®ulator>;
|
||||
AVDD2-supply = <®ulator>;
|
||||
CPVDD-supply = <®ulator>;
|
||||
DBVDD1-supply = <®ulator>;
|
||||
DBVDD2-supply = <®ulator>;
|
||||
DBVDD3-supply = <®ulator>;
|
||||
DBVDD-supply = <®ulator>;
|
||||
DCVDD-supply = <®ulator>;
|
||||
SPKVDD1-supply = <®ulator>;
|
||||
SPKVDD2-supply = <®ulator>;
|
||||
};
|
||||
|
69
Documentation/devicetree/bindings/sound/zl38060.yaml
Normal file
69
Documentation/devicetree/bindings/sound/zl38060.yaml
Normal 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>;
|
||||
};
|
||||
};
|
@ -669,11 +669,11 @@ static int sdw_stream_setup(struct snd_pcm_substream *substream,
|
||||
|
||||
/* Set stream pointer on all CODEC DAIs */
|
||||
for (i = 0; i < rtd->num_codecs; i++) {
|
||||
ret = snd_soc_dai_set_sdw_stream(rtd->codec_dais[i], sdw_stream,
|
||||
ret = snd_soc_dai_set_sdw_stream(asoc_rtd_to_codec(rtd, i), sdw_stream,
|
||||
substream->stream);
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "failed to set stream pointer on codec dai %s",
|
||||
rtd->codec_dais[i]->name);
|
||||
asoc_rtd_to_codec(rtd, i)->name);
|
||||
goto release_stream;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
/* SPDX-License-Identifier: GPL-2.0-only
|
||||
*
|
||||
* Copyright (C) 2013-15, Intel Corporation. All rights reserved.
|
||||
*/
|
||||
|
69
include/sound/soc-card.h
Normal file
69
include/sound/soc-card.h
Normal 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 */
|
@ -25,6 +25,44 @@
|
||||
order++)
|
||||
|
||||
/* component interface */
|
||||
struct snd_compress_ops {
|
||||
int (*open)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream);
|
||||
int (*free)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream);
|
||||
int (*set_params)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream,
|
||||
struct snd_compr_params *params);
|
||||
int (*get_params)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream,
|
||||
struct snd_codec *params);
|
||||
int (*set_metadata)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream,
|
||||
struct snd_compr_metadata *metadata);
|
||||
int (*get_metadata)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream,
|
||||
struct snd_compr_metadata *metadata);
|
||||
int (*trigger)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream, int cmd);
|
||||
int (*pointer)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream,
|
||||
struct snd_compr_tstamp *tstamp);
|
||||
int (*copy)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream, char __user *buf,
|
||||
size_t count);
|
||||
int (*mmap)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream,
|
||||
struct vm_area_struct *vma);
|
||||
int (*ack)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream, size_t bytes);
|
||||
int (*get_caps)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream,
|
||||
struct snd_compr_caps *caps);
|
||||
int (*get_codec_caps)(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream,
|
||||
struct snd_compr_codec_caps *codec);
|
||||
};
|
||||
|
||||
struct snd_soc_component_driver {
|
||||
const char *name;
|
||||
|
||||
@ -108,7 +146,7 @@ struct snd_soc_component_driver {
|
||||
struct snd_pcm_substream *substream,
|
||||
struct vm_area_struct *vma);
|
||||
|
||||
const struct snd_compr_ops *compr_ops;
|
||||
const struct snd_compress_ops *compress_ops;
|
||||
|
||||
/* probe ordering - for components with runtime dependencies */
|
||||
int probe_order;
|
||||
@ -351,10 +389,10 @@ static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
|
||||
return dev_get_drvdata(c->dev);
|
||||
}
|
||||
|
||||
static inline bool snd_soc_component_is_active(
|
||||
struct snd_soc_component *component)
|
||||
static inline unsigned int
|
||||
snd_soc_component_active(struct snd_soc_component *component)
|
||||
{
|
||||
return component->active != 0;
|
||||
return component->active;
|
||||
}
|
||||
|
||||
/* component pin */
|
||||
|
@ -154,21 +154,59 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai,
|
||||
struct snd_pcm_substream *substream);
|
||||
void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
|
||||
struct snd_pcm_substream *substream);
|
||||
int snd_soc_dai_prepare(struct snd_soc_dai *dai,
|
||||
struct snd_pcm_substream *substream);
|
||||
int snd_soc_dai_trigger(struct snd_soc_dai *dai,
|
||||
struct snd_pcm_substream *substream, int cmd);
|
||||
int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
|
||||
struct snd_pcm_substream *substream, int cmd);
|
||||
snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
|
||||
struct snd_pcm_substream *substream);
|
||||
void snd_soc_dai_suspend(struct snd_soc_dai *dai);
|
||||
void snd_soc_dai_resume(struct snd_soc_dai *dai);
|
||||
int snd_soc_dai_probe(struct snd_soc_dai *dai);
|
||||
int snd_soc_dai_remove(struct snd_soc_dai *dai);
|
||||
int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
|
||||
struct snd_soc_pcm_runtime *rtd, int num);
|
||||
bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream);
|
||||
void snd_soc_dai_action(struct snd_soc_dai *dai,
|
||||
int stream, int action);
|
||||
static inline void snd_soc_dai_activate(struct snd_soc_dai *dai,
|
||||
int stream)
|
||||
{
|
||||
snd_soc_dai_action(dai, stream, 1);
|
||||
}
|
||||
static inline void snd_soc_dai_deactivate(struct snd_soc_dai *dai,
|
||||
int stream)
|
||||
{
|
||||
snd_soc_dai_action(dai, stream, -1);
|
||||
}
|
||||
int snd_soc_dai_active(struct snd_soc_dai *dai);
|
||||
|
||||
int snd_soc_pcm_dai_probe(struct snd_soc_pcm_runtime *rtd, int order);
|
||||
int snd_soc_pcm_dai_remove(struct snd_soc_pcm_runtime *rtd, int order);
|
||||
int snd_soc_pcm_dai_new(struct snd_soc_pcm_runtime *rtd);
|
||||
int snd_soc_pcm_dai_prepare(struct snd_pcm_substream *substream);
|
||||
int snd_soc_pcm_dai_trigger(struct snd_pcm_substream *substream, int cmd);
|
||||
int snd_soc_pcm_dai_bespoke_trigger(struct snd_pcm_substream *substream,
|
||||
int cmd);
|
||||
|
||||
int snd_soc_dai_compr_startup(struct snd_soc_dai *dai,
|
||||
struct snd_compr_stream *cstream);
|
||||
void snd_soc_dai_compr_shutdown(struct snd_soc_dai *dai,
|
||||
struct snd_compr_stream *cstream);
|
||||
int snd_soc_dai_compr_trigger(struct snd_soc_dai *dai,
|
||||
struct snd_compr_stream *cstream, int cmd);
|
||||
int snd_soc_dai_compr_set_params(struct snd_soc_dai *dai,
|
||||
struct snd_compr_stream *cstream,
|
||||
struct snd_compr_params *params);
|
||||
int snd_soc_dai_compr_get_params(struct snd_soc_dai *dai,
|
||||
struct snd_compr_stream *cstream,
|
||||
struct snd_codec *params);
|
||||
int snd_soc_dai_compr_ack(struct snd_soc_dai *dai,
|
||||
struct snd_compr_stream *cstream,
|
||||
size_t bytes);
|
||||
int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai,
|
||||
struct snd_compr_stream *cstream,
|
||||
struct snd_compr_tstamp *tstamp);
|
||||
int snd_soc_dai_compr_set_metadata(struct snd_soc_dai *dai,
|
||||
struct snd_compr_stream *cstream,
|
||||
struct snd_compr_metadata *metadata);
|
||||
int snd_soc_dai_compr_get_metadata(struct snd_soc_dai *dai,
|
||||
struct snd_compr_stream *cstream,
|
||||
struct snd_compr_metadata *metadata);
|
||||
|
||||
struct snd_soc_dai_ops {
|
||||
/*
|
||||
@ -326,8 +364,6 @@ struct snd_soc_dai {
|
||||
/* DAI runtime info */
|
||||
unsigned int stream_active[SNDRV_PCM_STREAM_LAST + 1]; /* usage count */
|
||||
|
||||
unsigned int active;
|
||||
|
||||
struct snd_soc_dapm_widget *playback_widget;
|
||||
struct snd_soc_dapm_widget *capture_widget;
|
||||
|
||||
@ -443,4 +479,10 @@ static inline void *snd_soc_dai_get_sdw_stream(struct snd_soc_dai *dai,
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
snd_soc_dai_stream_active(struct snd_soc_dai *dai, int stream)
|
||||
{
|
||||
return dai->stream_active[stream];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -689,7 +689,7 @@ struct snd_soc_dapm_context {
|
||||
/* A list of widgets associated with an object, typically a snd_kcontrol */
|
||||
struct snd_soc_dapm_widget_list {
|
||||
int num_widgets;
|
||||
struct snd_soc_dapm_widget *widgets[0];
|
||||
struct snd_soc_dapm_widget *widgets[];
|
||||
};
|
||||
|
||||
#define for_each_dapm_widgets(list, i, widget) \
|
||||
|
27
include/sound/soc-link.h
Normal file
27
include/sound/soc-link.h
Normal 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 */
|
@ -414,11 +414,6 @@ enum snd_soc_pcm_subclass {
|
||||
SND_SOC_PCM_CLASS_BE = 1,
|
||||
};
|
||||
|
||||
enum snd_soc_card_subclass {
|
||||
SND_SOC_CARD_CLASS_INIT = 0,
|
||||
SND_SOC_CARD_CLASS_RUNTIME = 1,
|
||||
};
|
||||
|
||||
int snd_soc_register_card(struct snd_soc_card *card);
|
||||
int snd_soc_unregister_card(struct snd_soc_card *card);
|
||||
int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card);
|
||||
@ -468,8 +463,19 @@ struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card,
|
||||
struct snd_soc_dai_link *dai_link);
|
||||
|
||||
bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd);
|
||||
void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream);
|
||||
void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream);
|
||||
|
||||
void snd_soc_runtime_action(struct snd_soc_pcm_runtime *rtd,
|
||||
int stream, int action);
|
||||
static inline void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd,
|
||||
int stream)
|
||||
{
|
||||
snd_soc_runtime_action(rtd, stream, 1);
|
||||
}
|
||||
static inline void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd,
|
||||
int stream)
|
||||
{
|
||||
snd_soc_runtime_action(rtd, stream, -1);
|
||||
}
|
||||
|
||||
int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_pcm_hardware *hw, int stream);
|
||||
@ -498,10 +504,6 @@ int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
|
||||
const struct snd_pcm_hardware *hw);
|
||||
|
||||
/* Jack reporting */
|
||||
int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
|
||||
struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins,
|
||||
unsigned int num_pins);
|
||||
|
||||
void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask);
|
||||
int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
|
||||
struct snd_soc_jack_pin *pins);
|
||||
@ -571,8 +573,6 @@ static inline int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
|
||||
struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
|
||||
void *data, const char *long_name,
|
||||
const char *prefix);
|
||||
struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
|
||||
const char *name);
|
||||
int snd_soc_add_component_controls(struct snd_soc_component *component,
|
||||
const struct snd_kcontrol_new *controls, unsigned int num_controls);
|
||||
int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
|
||||
@ -806,7 +806,7 @@ struct snd_soc_dai_link {
|
||||
const struct snd_soc_compr_ops *compr_ops;
|
||||
|
||||
/* Mark this pcm with non atomic ops */
|
||||
bool nonatomic;
|
||||
unsigned int nonatomic:1;
|
||||
|
||||
/* For unidirectional dai links */
|
||||
unsigned int playback_only:1;
|
||||
@ -1002,9 +1002,6 @@ struct snd_soc_card {
|
||||
|
||||
spinlock_t dpcm_lock;
|
||||
|
||||
bool instantiated;
|
||||
bool topology_shortname_created;
|
||||
|
||||
int (*probe)(struct snd_soc_card *card);
|
||||
int (*late_probe)(struct snd_soc_card *card);
|
||||
int (*remove)(struct snd_soc_card *card);
|
||||
@ -1065,8 +1062,6 @@ struct snd_soc_card {
|
||||
int num_of_dapm_widgets;
|
||||
const struct snd_soc_dapm_route *of_dapm_routes;
|
||||
int num_of_dapm_routes;
|
||||
bool fully_routed;
|
||||
bool disable_route_checks;
|
||||
|
||||
/* lists of probed devices belonging to this card */
|
||||
struct list_head component_dev_list;
|
||||
@ -1093,6 +1088,13 @@ struct snd_soc_card {
|
||||
#endif
|
||||
u32 pop_time;
|
||||
|
||||
/* bit field */
|
||||
unsigned int instantiated:1;
|
||||
unsigned int topology_shortname_created:1;
|
||||
unsigned int fully_routed:1;
|
||||
unsigned int disable_route_checks:1;
|
||||
unsigned int probed:1;
|
||||
|
||||
void *drvdata;
|
||||
};
|
||||
#define for_each_card_prelinks(card, i, link) \
|
||||
@ -1143,14 +1145,16 @@ struct snd_soc_pcm_runtime {
|
||||
/* runtime devices */
|
||||
struct snd_pcm *pcm;
|
||||
struct snd_compr *compr;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
struct snd_soc_dai *cpu_dai;
|
||||
|
||||
/*
|
||||
* dais = cpu_dai + codec_dai
|
||||
* see
|
||||
* soc_new_pcm_runtime()
|
||||
* asoc_rtd_to_cpu()
|
||||
* asoc_rtd_to_codec()
|
||||
*/
|
||||
struct snd_soc_dai **dais;
|
||||
|
||||
struct snd_soc_dai **codec_dais;
|
||||
unsigned int num_codecs;
|
||||
|
||||
struct snd_soc_dai **cpu_dais;
|
||||
unsigned int num_cpus;
|
||||
|
||||
struct snd_soc_dapm_widget *playback_widget;
|
||||
@ -1170,28 +1174,28 @@ struct snd_soc_pcm_runtime {
|
||||
unsigned int fe_compr:1; /* for Dynamic PCM */
|
||||
|
||||
int num_components;
|
||||
struct snd_soc_component *components[0]; /* CPU/Codec/Platform */
|
||||
struct snd_soc_component *components[]; /* CPU/Codec/Platform */
|
||||
};
|
||||
/* see soc_new_pcm_runtime() */
|
||||
#define asoc_rtd_to_cpu(rtd, n) (rtd)->dais[n]
|
||||
#define asoc_rtd_to_codec(rtd, n) (rtd)->dais[n + (rtd)->num_cpus]
|
||||
|
||||
#define for_each_rtd_components(rtd, i, component) \
|
||||
for ((i) = 0; \
|
||||
for ((i) = 0, component = NULL; \
|
||||
((i) < rtd->num_components) && ((component) = rtd->components[i]);\
|
||||
(i)++)
|
||||
#define for_each_rtd_cpu_dais(rtd, i, dai) \
|
||||
for ((i) = 0; \
|
||||
((i) < rtd->num_cpus) && ((dai) = rtd->cpu_dais[i]); \
|
||||
((i) < rtd->num_cpus) && ((dai) = asoc_rtd_to_cpu(rtd, i)); \
|
||||
(i)++)
|
||||
#define for_each_rtd_cpu_dais_rollback(rtd, i, dai) \
|
||||
for (; (--(i) >= 0) && ((dai) = rtd->cpu_dais[i]);)
|
||||
for (; (--(i) >= 0) && ((dai) = asoc_rtd_to_cpu(rtd, i));)
|
||||
#define for_each_rtd_codec_dais(rtd, i, dai) \
|
||||
for ((i) = 0; \
|
||||
((i) < rtd->num_codecs) && ((dai) = rtd->codec_dais[i]); \
|
||||
((i) < rtd->num_codecs) && ((dai) = asoc_rtd_to_codec(rtd, i)); \
|
||||
(i)++)
|
||||
#define for_each_rtd_codec_dais_rollback(rtd, i, dai) \
|
||||
for (; (--(i) >= 0) && ((dai) = rtd->codec_dais[i]);)
|
||||
for (; (--(i) >= 0) && ((dai) = asoc_rtd_to_codec(rtd, i));)
|
||||
#define for_each_rtd_dais(rtd, i, dai) \
|
||||
for ((i) = 0; \
|
||||
((i) < (rtd)->num_cpus + (rtd)->num_codecs) && \
|
||||
@ -1252,29 +1256,16 @@ struct soc_enum {
|
||||
#endif
|
||||
};
|
||||
|
||||
/* device driver data */
|
||||
|
||||
static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
|
||||
void *data)
|
||||
{
|
||||
card->drvdata = data;
|
||||
}
|
||||
|
||||
static inline void *snd_soc_card_get_drvdata(struct snd_soc_card *card)
|
||||
{
|
||||
return card->drvdata;
|
||||
}
|
||||
|
||||
static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
|
||||
{
|
||||
if (mc->reg == mc->rreg && mc->shift == mc->rshift)
|
||||
return 0;
|
||||
return false;
|
||||
/*
|
||||
* mc->reg == mc->rreg && mc->shift != mc->rshift, or
|
||||
* mc->reg != mc->rreg means that the control is
|
||||
* stereo (bits in one register or in two registers)
|
||||
*/
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline unsigned int snd_soc_enum_val_to_item(struct soc_enum *e,
|
||||
@ -1377,20 +1368,6 @@ struct snd_soc_dai *snd_soc_find_dai(
|
||||
|
||||
#include <sound/soc-dai.h>
|
||||
|
||||
static inline
|
||||
struct snd_soc_dai *snd_soc_card_get_codec_dai(struct snd_soc_card *card,
|
||||
const char *dai_name)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
|
||||
list_for_each_entry(rtd, &card->rtd_list, list) {
|
||||
if (!strcmp(rtd->codec_dai->name, dai_name))
|
||||
return rtd->codec_dai;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline
|
||||
int snd_soc_fixup_dai_links_platform_name(struct snd_soc_card *card,
|
||||
const char *platform_name)
|
||||
@ -1436,5 +1413,6 @@ static inline void snd_soc_dapm_mutex_unlock(struct snd_soc_dapm_context *dapm)
|
||||
}
|
||||
|
||||
#include <sound/soc-component.h>
|
||||
#include <sound/soc-card.h>
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
@ -27,6 +27,9 @@ struct snd_sof_pdata {
|
||||
|
||||
struct device *dev;
|
||||
|
||||
/* indicate how many first bytes shouldn't be loaded into DSP memory. */
|
||||
size_t fw_offset;
|
||||
|
||||
/*
|
||||
* notification callback used if the hardware initialization
|
||||
* can take time or is handled in a workqueue. This callback
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
@ -49,6 +49,9 @@
|
||||
/* bclk idle */
|
||||
#define SOF_DAI_INTEL_SSP_CLKCTRL_BCLK_IDLE_HIGH BIT(5)
|
||||
|
||||
/* DMIC max. four controllers for eight microphone channels */
|
||||
#define SOF_DAI_INTEL_DMIC_NUM_CTRL 4
|
||||
|
||||
/* SSP Configuration Request - SOF_IPC_DAI_SSP_CONFIG */
|
||||
struct sof_ipc_dai_ssp_params {
|
||||
struct sof_ipc_hdr hdr;
|
||||
@ -85,15 +88,19 @@ struct sof_ipc_dai_ssp_params {
|
||||
struct sof_ipc_dai_hda_params {
|
||||
struct sof_ipc_hdr hdr;
|
||||
uint32_t link_dma_ch;
|
||||
uint32_t rate;
|
||||
uint32_t channels;
|
||||
} __packed;
|
||||
|
||||
/* ALH Configuration Request - SOF_IPC_DAI_ALH_CONFIG */
|
||||
struct sof_ipc_dai_alh_params {
|
||||
struct sof_ipc_hdr hdr;
|
||||
uint32_t stream_id;
|
||||
uint32_t rate;
|
||||
uint32_t channels;
|
||||
|
||||
/* reserved for future use */
|
||||
uint32_t reserved[15];
|
||||
uint32_t reserved[13];
|
||||
} __packed;
|
||||
|
||||
/* DMIC Configuration Request - SOF_IPC_DAI_DMIC_CONFIG */
|
||||
@ -135,7 +142,7 @@ struct sof_ipc_dai_dmic_pdm_ctrl {
|
||||
* version number used in configuration data is checked vs. version used by
|
||||
* device driver src/drivers/dmic.c need to match. It is incremented from
|
||||
* initial value 1 if updates done for the to driver would alter the operation
|
||||
* of the microhone.
|
||||
* of the microphone.
|
||||
*
|
||||
* Note: The microphone clock (pdmclk_min, pdmclk_max, duty_min, duty_max)
|
||||
* parameters need to be set as defined in microphone data sheet. E.g. clock
|
||||
@ -170,12 +177,13 @@ struct sof_ipc_dai_dmic_params {
|
||||
uint32_t fifo_fs; /**< FIFO sample rate in Hz (8000..96000) */
|
||||
uint32_t reserved_1; /**< Reserved */
|
||||
uint16_t fifo_bits; /**< FIFO word length (16 or 32) */
|
||||
uint16_t reserved_2; /**< Reserved */
|
||||
uint16_t fifo_bits_b; /**< Deprecated since firmware ABI 3.0.1 */
|
||||
|
||||
uint16_t duty_min; /**< Min. mic clock duty cycle in % (20..80) */
|
||||
uint16_t duty_max; /**< Max. mic clock duty cycle in % (min..80) */
|
||||
|
||||
uint32_t num_pdm_active; /**< Number of active pdm controllers */
|
||||
uint32_t num_pdm_active; /**< Number of active pdm controllers. */
|
||||
/**< Range is 1..SOF_DAI_INTEL_DMIC_NUM_CTRL */
|
||||
|
||||
uint32_t wake_up_time; /**< Time from clock start to data (us) */
|
||||
uint32_t min_clock_on_time; /**< Min. time that clk is kept on (us) */
|
||||
@ -184,8 +192,8 @@ struct sof_ipc_dai_dmic_params {
|
||||
/* reserved for future use */
|
||||
uint32_t reserved[5];
|
||||
|
||||
/**< variable number of pdm controller config */
|
||||
struct sof_ipc_dai_dmic_pdm_ctrl pdm[0];
|
||||
/**< PDM controllers configuration */
|
||||
struct sof_ipc_dai_dmic_pdm_ctrl pdm[SOF_DAI_INTEL_DMIC_NUM_CTRL];
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
|
95
include/sound/sof/ext_manifest.h
Normal file
95
include/sound/sof/ext_manifest.h
Normal 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__ */
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
@ -31,6 +31,8 @@ enum sof_ipc_ext_data {
|
||||
SOF_IPC_EXT_UNUSED = 0,
|
||||
SOF_IPC_EXT_WINDOW = 1,
|
||||
SOF_IPC_EXT_CC_INFO = 2,
|
||||
SOF_IPC_EXT_PROBE_INFO = 3,
|
||||
SOF_IPC_EXT_USER_ABI_INFO = 4,
|
||||
};
|
||||
|
||||
/* FW version - SOF_IPC_GLB_VERSION */
|
||||
@ -109,9 +111,27 @@ struct sof_ipc_cc_version {
|
||||
/* reserved for future use */
|
||||
uint32_t reserved[4];
|
||||
|
||||
char name[16]; /* null terminated compiler name */
|
||||
char optim[4]; /* null terminated compiler -O flag value */
|
||||
char desc[]; /* null terminated compiler description */
|
||||
uint8_t name[16]; /* null terminated compiler name */
|
||||
uint8_t optim[4]; /* null terminated compiler -O flag value */
|
||||
uint8_t desc[32]; /* null terminated compiler description */
|
||||
} __packed;
|
||||
|
||||
/* extended data: Probe setup */
|
||||
struct sof_ipc_probe_support {
|
||||
struct sof_ipc_ext_data_hdr ext_hdr;
|
||||
|
||||
uint32_t probe_points_max;
|
||||
uint32_t injection_dmas_max;
|
||||
|
||||
/* reserved for future use */
|
||||
uint32_t reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* extended data: user abi version(s) */
|
||||
struct sof_ipc_user_abi_version {
|
||||
struct sof_ipc_ext_data_hdr ext_hdr;
|
||||
|
||||
uint32_t abi_dbg_version;
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
@ -37,6 +37,8 @@ enum sof_comp_type {
|
||||
SOF_COMP_SELECTOR, /**< channel selector component */
|
||||
SOF_COMP_DEMUX,
|
||||
SOF_COMP_ASRC, /**< Asynchronous sample rate converter */
|
||||
SOF_COMP_DCBLOCK,
|
||||
SOF_COMP_SMART_AMP, /**< smart amplifier component */
|
||||
/* keep FILEREAD/FILEWRITE as the last ones */
|
||||
SOF_COMP_FILEREAD = 10000, /**< host test based file IO */
|
||||
SOF_COMP_FILEWRITE = 10001, /**< host test based file IO */
|
||||
@ -75,11 +77,23 @@ struct sof_ipc_comp {
|
||||
#define SOF_MEM_CAPS_CACHE (1 << 6) /**< cacheable */
|
||||
#define SOF_MEM_CAPS_EXEC (1 << 7) /**< executable */
|
||||
|
||||
/*
|
||||
* overrun will cause ring buffer overwrite, instead of XRUN.
|
||||
*/
|
||||
#define SOF_BUF_OVERRUN_PERMITTED BIT(0)
|
||||
|
||||
/*
|
||||
* underrun will cause readback of 0s, instead of XRUN.
|
||||
*/
|
||||
#define SOF_BUF_UNDERRUN_PERMITTED BIT(1)
|
||||
|
||||
/* create new component buffer - SOF_IPC_TPLG_BUFFER_NEW */
|
||||
struct sof_ipc_buffer {
|
||||
struct sof_ipc_comp comp;
|
||||
uint32_t size; /**< buffer size in bytes */
|
||||
uint32_t caps; /**< SOF_MEM_CAPS_ */
|
||||
uint32_t flags; /**< SOF_BUF_ flags defined above */
|
||||
uint32_t reserved; /**< reserved for future use */
|
||||
} __packed;
|
||||
|
||||
/* generic component config data - must always be after struct sof_ipc_comp */
|
||||
@ -206,6 +220,8 @@ enum sof_ipc_process_type {
|
||||
SOF_PROCESS_CHAN_SELECTOR, /**< Channel Selector */
|
||||
SOF_PROCESS_MUX,
|
||||
SOF_PROCESS_DEMUX,
|
||||
SOF_PROCESS_DCBLOCK,
|
||||
SOF_PROCESS_SMART_AMP, /**< Smart Amplifier */
|
||||
};
|
||||
|
||||
/* generic "effect", "codec" or proprietary processing component */
|
||||
@ -218,7 +234,7 @@ struct sof_ipc_comp_process {
|
||||
/* reserved for future use */
|
||||
uint32_t reserved[7];
|
||||
|
||||
unsigned char data[0];
|
||||
uint8_t data[0];
|
||||
} __packed;
|
||||
|
||||
/* frees components, buffers and pipelines
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
@ -72,7 +72,7 @@ struct sof_ipc_dma_trace_posn {
|
||||
struct sof_ipc_panic_info {
|
||||
struct sof_ipc_hdr hdr;
|
||||
uint32_t code; /* SOF_IPC_PANIC_ */
|
||||
char filename[SOF_TRACE_FILENAME_SIZE];
|
||||
uint8_t filename[SOF_TRACE_FILENAME_SIZE];
|
||||
uint32_t linenum;
|
||||
} __packed;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
#define SKL_CONTROL_TYPE_BYTE_TLV 0x100
|
||||
#define SKL_CONTROL_TYPE_MIC_SELECT 0x102
|
||||
#define SKL_CONTROL_TYPE_MULTI_IO_SELECT 0x103
|
||||
#define SKL_CONTROL_TYPE_MULTI_IO_SELECT_DMIC 0x104
|
||||
|
||||
#define HDA_SST_CFG_MAX 900 /* size of copier cfg*/
|
||||
#define MAX_IN_QUEUE 8
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
/* SOF ABI version major, minor and patch numbers */
|
||||
#define SOF_ABI_MAJOR 3
|
||||
#define SOF_ABI_MINOR 13
|
||||
#define SOF_ABI_MINOR 16
|
||||
#define SOF_ABI_PATCH 0
|
||||
|
||||
/* SOF ABI version number. Format within 32bit word is MMmmmppp */
|
||||
|
@ -126,4 +126,12 @@
|
||||
#define SOF_TKN_MUTE_LED_USE 1300
|
||||
#define SOF_TKN_MUTE_LED_DIRECTION 1301
|
||||
|
||||
/* ALH */
|
||||
#define SOF_TKN_INTEL_ALH_RATE 1400
|
||||
#define SOF_TKN_INTEL_ALH_CH 1401
|
||||
|
||||
/* HDA */
|
||||
#define SOF_TKN_INTEL_HDA_RATE 1500
|
||||
#define SOF_TKN_INTEL_HDA_CH 1501
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
// Copyright (c) 2015-2019 Intel Corporation
|
||||
|
||||
#include <linux/acpi.h>
|
||||
|
@ -4169,6 +4169,7 @@ HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi),
|
||||
HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI", patch_i915_icl_hdmi),
|
||||
HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi),
|
||||
HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi),
|
||||
HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI", patch_i915_icl_hdmi),
|
||||
HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
|
||||
HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi),
|
||||
HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),
|
||||
|
@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-utils.o soc-dai.o soc-component.o
|
||||
snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o
|
||||
snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o soc-link.o soc-card.o
|
||||
snd-soc-core-$(CONFIG_SND_SOC_COMPRESS) += soc-compress.o
|
||||
|
||||
ifneq ($(CONFIG_SND_SOC_TOPOLOGY),)
|
||||
|
@ -29,10 +29,23 @@ config SND_SOC_AMD_ACP3x
|
||||
|
||||
config SND_SOC_AMD_RV_RT5682_MACH
|
||||
tristate "AMD RV support for RT5682"
|
||||
select SND_SOC_RT5682
|
||||
select SND_SOC_RT5682_I2C
|
||||
select SND_SOC_MAX98357A
|
||||
select SND_SOC_CROS_EC_CODEC
|
||||
select I2C_CROS_EC_TUNNEL
|
||||
depends on SND_SOC_AMD_ACP3x && I2C && CROS_EC
|
||||
help
|
||||
This option enables machine driver for RT5682 and MAX9835.
|
||||
|
||||
config SND_SOC_AMD_RENOIR
|
||||
tristate "AMD Audio Coprocessor - Renoir support"
|
||||
depends on X86 && PCI
|
||||
help
|
||||
This option enables ACP support for Renoir platform
|
||||
|
||||
config SND_SOC_AMD_RENOIR_MACH
|
||||
tristate "AMD Renoir support for DMIC"
|
||||
select SND_SOC_DMIC
|
||||
depends on SND_SOC_AMD_RENOIR
|
||||
help
|
||||
This option enables machine driver for DMIC
|
||||
|
@ -9,3 +9,4 @@ obj-$(CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH) += snd-soc-acp-da7219mx98357-mac
|
||||
obj-$(CONFIG_SND_SOC_AMD_CZ_RT5645_MACH) += snd-soc-acp-rt5645-mach.o
|
||||
obj-$(CONFIG_SND_SOC_AMD_ACP3x) += raven/
|
||||
obj-$(CONFIG_SND_SOC_AMD_RV_RT5682_MACH) += snd-soc-acp-rt5682-mach.o
|
||||
obj-$(CONFIG_SND_SOC_AMD_RENOIR) += renoir/
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#include "acp3x.h"
|
||||
|
||||
#define DRV_NAME "acp3x-i2s"
|
||||
#define DRV_NAME "acp3x_i2s_playcap"
|
||||
|
||||
static int acp3x_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
|
||||
unsigned int fmt)
|
||||
@ -269,7 +269,7 @@ static struct snd_soc_dai_ops acp3x_i2s_dai_ops = {
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver acp3x_dai_component = {
|
||||
.name = "acp3x-i2s",
|
||||
.name = DRV_NAME,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver acp3x_i2s_dai = {
|
||||
@ -348,4 +348,4 @@ module_platform_driver(acp3x_dai_driver);
|
||||
MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com");
|
||||
MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:" DRV_NAME);
|
||||
MODULE_ALIAS("platform:"DRV_NAME);
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#include "acp3x.h"
|
||||
|
||||
#define DRV_NAME "acp3x-i2s-audio"
|
||||
#define DRV_NAME "acp3x_rv_i2s_dma"
|
||||
|
||||
static const struct snd_pcm_hardware acp3x_pcm_hardware_playback = {
|
||||
.info = SNDRV_PCM_INFO_INTERLEAVED |
|
||||
@ -303,7 +303,6 @@ static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_soc_component *component,
|
||||
{
|
||||
struct snd_soc_pcm_runtime *prtd;
|
||||
struct snd_soc_card *card;
|
||||
struct acp3x_platform_info *pinfo;
|
||||
struct i2s_stream_instance *rtd;
|
||||
u32 pos;
|
||||
u32 buffersize;
|
||||
@ -312,13 +311,6 @@ static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_soc_component *component,
|
||||
prtd = substream->private_data;
|
||||
card = prtd->card;
|
||||
rtd = substream->runtime->private_data;
|
||||
pinfo = snd_soc_card_get_drvdata(card);
|
||||
if (pinfo) {
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
rtd->i2s_instance = pinfo->play_i2s_instance;
|
||||
else
|
||||
rtd->i2s_instance = pinfo->cap_i2s_instance;
|
||||
}
|
||||
|
||||
buffersize = frames_to_bytes(substream->runtime,
|
||||
substream->runtime->buffer_size);
|
||||
@ -542,4 +534,4 @@ MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com");
|
||||
MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
|
||||
MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:" DRV_NAME);
|
||||
MODULE_ALIAS("platform:"DRV_NAME);
|
||||
|
7
sound/soc/amd/renoir/Makefile
Normal file
7
sound/soc/amd/renoir/Makefile
Normal 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
|
524
sound/soc/amd/renoir/acp3x-pdm-dma.c
Normal file
524
sound/soc/amd/renoir/acp3x-pdm-dma.c
Normal 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);
|
77
sound/soc/amd/renoir/acp3x-rn.c
Normal file
77
sound/soc/amd/renoir/acp3x-rn.c
Normal 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);
|
344
sound/soc/amd/renoir/rn-pci-acp3x.c
Normal file
344
sound/soc/amd/renoir/rn-pci-acp3x.c
Normal 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");
|
88
sound/soc/amd/renoir/rn_acp3x.h
Normal file
88
sound/soc/amd/renoir/rn_acp3x.h
Normal 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);
|
||||
}
|
349
sound/soc/amd/renoir/rn_chip_offset_byte.h
Normal file
349
sound/soc/amd/renoir/rn_chip_offset_byte.h
Normal 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
|
@ -765,7 +765,7 @@ static int atmel_ssc_suspend(struct snd_soc_component *component)
|
||||
struct atmel_ssc_info *ssc_p;
|
||||
struct platform_device *pdev = to_platform_device(component->dev);
|
||||
|
||||
if (!component->active)
|
||||
if (!snd_soc_component_active(component))
|
||||
return 0;
|
||||
|
||||
ssc_p = &ssc_info[pdev->id];
|
||||
@ -793,7 +793,7 @@ static int atmel_ssc_resume(struct snd_soc_component *component)
|
||||
struct platform_device *pdev = to_platform_device(component->dev);
|
||||
u32 cr;
|
||||
|
||||
if (!component->active)
|
||||
if (!snd_soc_component_active(component))
|
||||
return 0;
|
||||
|
||||
ssc_p = &ssc_info[pdev->id];
|
||||
|
@ -653,7 +653,7 @@ static void bcm2835_i2s_stop(struct bcm2835_i2s_dev *dev,
|
||||
BCM2835_I2S_CS_A_REG, mask, 0);
|
||||
|
||||
/* Stop also the clock when not SND_SOC_DAIFMT_CONT */
|
||||
if (!dai->active && !(dev->fmt & SND_SOC_DAIFMT_CONT))
|
||||
if (!snd_soc_dai_active(dai) && !(dev->fmt & SND_SOC_DAIFMT_CONT))
|
||||
bcm2835_i2s_stop_clock(dev);
|
||||
}
|
||||
|
||||
@ -695,7 +695,7 @@ static int bcm2835_i2s_startup(struct snd_pcm_substream *substream,
|
||||
{
|
||||
struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (dai->active)
|
||||
if (snd_soc_dai_active(dai))
|
||||
return 0;
|
||||
|
||||
/* Should this still be running stop it */
|
||||
@ -723,7 +723,7 @@ static void bcm2835_i2s_shutdown(struct snd_pcm_substream *substream,
|
||||
bcm2835_i2s_stop(dev, substream, dai);
|
||||
|
||||
/* If both streams are stopped, disable module and clock */
|
||||
if (dai->active)
|
||||
if (snd_soc_dai_active(dai))
|
||||
return;
|
||||
|
||||
/* Disable the module */
|
||||
|
@ -1056,7 +1056,7 @@ static int __cygnus_ssp_suspend(struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
|
||||
|
||||
if (!cpu_dai->active)
|
||||
if (!snd_soc_dai_active(cpu_dai))
|
||||
return 0;
|
||||
|
||||
if (!aio->is_slave) {
|
||||
@ -1097,7 +1097,7 @@ static int __cygnus_ssp_resume(struct snd_soc_dai *cpu_dai)
|
||||
struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
|
||||
int error;
|
||||
|
||||
if (!cpu_dai->active)
|
||||
if (!snd_soc_dai_active(cpu_dai))
|
||||
return 0;
|
||||
|
||||
if (!aio->is_slave) {
|
||||
|
@ -368,7 +368,7 @@ static int ep93xx_i2s_suspend(struct snd_soc_component *component)
|
||||
{
|
||||
struct ep93xx_i2s_info *info = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (!component->active)
|
||||
if (!snd_soc_component_active(component))
|
||||
return 0;
|
||||
|
||||
ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK);
|
||||
@ -381,7 +381,7 @@ static int ep93xx_i2s_resume(struct snd_soc_component *component)
|
||||
{
|
||||
struct ep93xx_i2s_info *info = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (!component->active)
|
||||
if (!snd_soc_component_active(component))
|
||||
return 0;
|
||||
|
||||
ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK);
|
||||
|
@ -116,6 +116,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_MAX98926
|
||||
imply SND_SOC_MAX98927
|
||||
imply SND_SOC_MAX98373
|
||||
imply SND_SOC_MAX98390
|
||||
imply SND_SOC_MAX9850
|
||||
imply SND_SOC_MAX9860
|
||||
imply SND_SOC_MAX9759
|
||||
@ -167,7 +168,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_RT5668
|
||||
imply SND_SOC_RT5670
|
||||
imply SND_SOC_RT5677
|
||||
imply SND_SOC_RT5682
|
||||
imply SND_SOC_RT5682_I2C
|
||||
imply SND_SOC_RT5682_SDW
|
||||
imply SND_SOC_RT700_SDW
|
||||
imply SND_SOC_RT711_SDW
|
||||
@ -272,6 +273,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_WM9712
|
||||
imply SND_SOC_WM9713
|
||||
imply SND_SOC_WSA881X
|
||||
imply SND_SOC_ZL38060
|
||||
help
|
||||
Normally ASoC codec drivers are only built if a machine driver which
|
||||
uses them is also built since they are only usable with a machine
|
||||
@ -537,8 +539,7 @@ config SND_SOC_CQ0093VC
|
||||
config SND_SOC_CROS_EC_CODEC
|
||||
tristate "codec driver for ChromeOS EC"
|
||||
depends on CROS_EC
|
||||
select CRYPTO
|
||||
select CRYPTO_SHA256
|
||||
select CRYPTO_LIB_SHA256
|
||||
help
|
||||
If you say yes here you will get support for the
|
||||
ChromeOS Embedded Controller's Audio Codec.
|
||||
@ -681,6 +682,7 @@ config SND_SOC_CX2072X
|
||||
|
||||
config SND_SOC_JZ4740_CODEC
|
||||
depends on MIPS || COMPILE_TEST
|
||||
depends on OF
|
||||
select REGMAP_MMIO
|
||||
tristate "Ingenic JZ4740 internal CODEC"
|
||||
help
|
||||
@ -692,6 +694,7 @@ config SND_SOC_JZ4740_CODEC
|
||||
|
||||
config SND_SOC_JZ4725B_CODEC
|
||||
depends on MIPS || COMPILE_TEST
|
||||
depends on OF
|
||||
select REGMAP
|
||||
tristate "Ingenic JZ4725B internal CODEC"
|
||||
help
|
||||
@ -703,6 +706,7 @@ config SND_SOC_JZ4725B_CODEC
|
||||
|
||||
config SND_SOC_JZ4770_CODEC
|
||||
depends on MIPS || COMPILE_TEST
|
||||
depends on OF
|
||||
select REGMAP
|
||||
tristate "Ingenic JZ4770 internal CODEC"
|
||||
help
|
||||
@ -717,7 +721,7 @@ config SND_SOC_L3
|
||||
|
||||
config SND_SOC_DA7210
|
||||
tristate
|
||||
depends on I2C
|
||||
depends on SND_SOC_I2C_AND_SPI
|
||||
|
||||
config SND_SOC_DA7213
|
||||
tristate "Dialog DA7213 CODEC"
|
||||
@ -867,6 +871,10 @@ config SND_SOC_MAX98373
|
||||
tristate "Maxim Integrated MAX98373 Speaker Amplifier"
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_MAX98390
|
||||
tristate "Maxim Integrated MAX98390 Speaker Amplifier"
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_MAX9850
|
||||
tristate
|
||||
depends on I2C
|
||||
@ -1135,7 +1143,11 @@ config SND_SOC_RT5677_SPI
|
||||
|
||||
config SND_SOC_RT5682
|
||||
tristate
|
||||
depends on I2C || SOUNDWIRE
|
||||
|
||||
config SND_SOC_RT5682_I2C
|
||||
tristate
|
||||
depends on I2C
|
||||
select SND_SOC_RT5682
|
||||
|
||||
config SND_SOC_RT5682_SDW
|
||||
tristate "Realtek RT5682 Codec - SDW"
|
||||
@ -1569,7 +1581,7 @@ config SND_SOC_WM8978
|
||||
|
||||
config SND_SOC_WM8983
|
||||
tristate
|
||||
depends on I2C
|
||||
depends on SND_SOC_I2C_AND_SPI
|
||||
|
||||
config SND_SOC_WM8985
|
||||
tristate "Wolfson Microelectronics WM8985 and WM8758 codec driver"
|
||||
@ -1620,19 +1632,19 @@ config SND_SOC_WM9090
|
||||
|
||||
config SND_SOC_WM9705
|
||||
tristate
|
||||
depends on SND_SOC_AC97_BUS
|
||||
depends on SND_SOC_AC97_BUS || AC97_BUS_NEW
|
||||
select REGMAP_AC97
|
||||
select AC97_BUS_COMPAT if AC97_BUS_NEW
|
||||
|
||||
config SND_SOC_WM9712
|
||||
tristate
|
||||
depends on SND_SOC_AC97_BUS
|
||||
depends on SND_SOC_AC97_BUS || AC97_BUS_NEW
|
||||
select REGMAP_AC97
|
||||
select AC97_BUS_COMPAT if AC97_BUS_NEW
|
||||
|
||||
config SND_SOC_WM9713
|
||||
tristate
|
||||
depends on SND_SOC_AC97_BUS
|
||||
depends on SND_SOC_AC97_BUS || AC97_BUS_NEW
|
||||
select REGMAP_AC97
|
||||
select AC97_BUS_COMPAT if AC97_BUS_NEW
|
||||
|
||||
@ -1645,6 +1657,16 @@ config SND_SOC_WSA881X
|
||||
This enables support for Qualcomm WSA8810/WSA8815 Class-D
|
||||
Smart Speaker Amplifier.
|
||||
|
||||
config SND_SOC_ZL38060
|
||||
tristate "Microsemi ZL38060 Connected Home Audio Processor"
|
||||
depends on SPI_MASTER
|
||||
select GPIOLIB
|
||||
select REGMAP
|
||||
help
|
||||
Support for ZL38060 Connected Home Audio Processor from Microsemi,
|
||||
which consists of a Digital Signal Processor (DSP), several Digital
|
||||
Audio Interfaces (DAIs), analog outputs, and a block of 14 GPIOs.
|
||||
|
||||
config SND_SOC_ZX_AUD96P22
|
||||
tristate "ZTE ZX AUD96P22 CODEC"
|
||||
depends on I2C
|
||||
|
@ -115,6 +115,7 @@ snd-soc-max98925-objs := max98925.o
|
||||
snd-soc-max98926-objs := max98926.o
|
||||
snd-soc-max98927-objs := max98927.o
|
||||
snd-soc-max98373-objs := max98373.o
|
||||
snd-soc-max98390-objs := max98390.o
|
||||
snd-soc-max9850-objs := max9850.o
|
||||
snd-soc-max9860-objs := max9860.o
|
||||
snd-soc-mc13783-objs := mc13783.o
|
||||
@ -178,6 +179,7 @@ snd-soc-rt5677-objs := rt5677.o
|
||||
snd-soc-rt5677-spi-objs := rt5677-spi.o
|
||||
snd-soc-rt5682-objs := rt5682.o
|
||||
snd-soc-rt5682-sdw-objs := rt5682-sdw.o
|
||||
snd-soc-rt5682-i2c-objs := rt5682-i2c.o
|
||||
snd-soc-rt700-objs := rt700.o rt700-sdw.o
|
||||
snd-soc-rt711-objs := rt711.o rt711-sdw.o
|
||||
snd-soc-rt715-objs := rt715.o rt715-sdw.o
|
||||
@ -288,6 +290,7 @@ snd-soc-wm9712-objs := wm9712.o
|
||||
snd-soc-wm9713-objs := wm9713.o
|
||||
snd-soc-wm-hubs-objs := wm_hubs.o
|
||||
snd-soc-wsa881x-objs := wsa881x.o
|
||||
snd-soc-zl38060-objs := zl38060.o
|
||||
snd-soc-zx-aud96p22-objs := zx_aud96p22.o
|
||||
# Amp
|
||||
snd-soc-max9877-objs := max9877.o
|
||||
@ -415,6 +418,7 @@ obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
|
||||
obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
|
||||
obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o
|
||||
obj-$(CONFIG_SND_SOC_MAX98373) += snd-soc-max98373.o
|
||||
obj-$(CONFIG_SND_SOC_MAX98390) += snd-soc-max98390.o
|
||||
obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
|
||||
obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o
|
||||
obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
|
||||
@ -478,6 +482,7 @@ obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o
|
||||
obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o
|
||||
obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o
|
||||
obj-$(CONFIG_SND_SOC_RT5682) += snd-soc-rt5682.o
|
||||
obj-$(CONFIG_SND_SOC_RT5682_I2C) += snd-soc-rt5682-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_RT5682_SDW) += snd-soc-rt5682-sdw.o
|
||||
obj-$(CONFIG_SND_SOC_RT700) += snd-soc-rt700.o
|
||||
obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o
|
||||
@ -588,6 +593,7 @@ obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
|
||||
obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o
|
||||
obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
|
||||
obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o
|
||||
obj-$(CONFIG_SND_SOC_ZL38060) += snd-soc-zl38060.o
|
||||
obj-$(CONFIG_SND_SOC_ZX_AUD96P22) += snd-soc-zx-aud96p22.o
|
||||
|
||||
# Amp
|
||||
|
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* ad1980.c -- ALSA Soc AD1980 codec support
|
||||
*
|
||||
* Copyright: Analog Device Inc.
|
||||
* Copyright: Analog Devices Inc.
|
||||
* Author: Roy Huang <roy.huang@analog.com>
|
||||
* Cliff Cai <cliff.cai@analog.com>
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@
|
||||
/*
|
||||
* ad73311.c -- ALSA Soc AD73311 codec support
|
||||
*
|
||||
* Copyright: Analog Device Inc.
|
||||
* Copyright: Analog Devices Inc.
|
||||
* Author: Cliff Cai <cliff.cai@analog.com>
|
||||
*/
|
||||
|
||||
|
@ -725,7 +725,7 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (!snd_soc_component_is_active(component) || !adav80x->rate)
|
||||
if (!snd_soc_component_active(component) || !adav80x->rate)
|
||||
return 0;
|
||||
|
||||
return snd_pcm_hw_constraint_single(substream->runtime,
|
||||
@ -738,7 +738,7 @@ static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct adav80x *adav80x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (!snd_soc_component_is_active(component))
|
||||
if (!snd_soc_component_active(component))
|
||||
adav80x->rate = 0;
|
||||
}
|
||||
|
||||
|
@ -1926,7 +1926,7 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
|
||||
if (clk_id == dai_priv->clk)
|
||||
return 0;
|
||||
|
||||
if (dai->active) {
|
||||
if (snd_soc_dai_active(dai)) {
|
||||
dev_err(component->dev, "Can't change clock on active DAI %d\n",
|
||||
dai->id);
|
||||
return -EBUSY;
|
||||
|
@ -8,7 +8,6 @@
|
||||
* EC for audio function.
|
||||
*/
|
||||
|
||||
#include <crypto/hash.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/delay.h>
|
||||
@ -107,24 +106,11 @@ error:
|
||||
static int calculate_sha256(struct cros_ec_codec_priv *priv,
|
||||
uint8_t *buf, uint32_t size, uint8_t *digest)
|
||||
{
|
||||
struct crypto_shash *tfm;
|
||||
struct sha256_state sctx;
|
||||
|
||||
tfm = crypto_alloc_shash("sha256", CRYPTO_ALG_TYPE_SHASH, 0);
|
||||
if (IS_ERR(tfm)) {
|
||||
dev_err(priv->dev, "can't alloc shash\n");
|
||||
return PTR_ERR(tfm);
|
||||
}
|
||||
|
||||
{
|
||||
SHASH_DESC_ON_STACK(desc, tfm);
|
||||
|
||||
desc->tfm = tfm;
|
||||
|
||||
crypto_shash_digest(desc, buf, size, digest);
|
||||
shash_desc_zero(desc);
|
||||
}
|
||||
|
||||
crypto_free_shash(tfm);
|
||||
sha256_init(&sctx);
|
||||
sha256_update(&sctx, buf, size);
|
||||
sha256_final(&sctx, digest);
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
|
@ -356,9 +356,9 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
|
||||
*/
|
||||
|
||||
if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||
!dai->stream_active[SNDRV_PCM_STREAM_CAPTURE]) ||
|
||||
!snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE)) ||
|
||||
(substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
|
||||
!dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK])) {
|
||||
!snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK))) {
|
||||
ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
|
||||
CS4271_MODE2_PDN,
|
||||
CS4271_MODE2_PDN);
|
||||
|
@ -1229,11 +1229,10 @@ static struct snd_soc_dai_driver cs47l15_dai[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int cs47l15_open(struct snd_compr_stream *stream)
|
||||
static int cs47l15_open(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = stream->private_data;
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
|
||||
struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component);
|
||||
struct madera_priv *priv = &cs47l15->core;
|
||||
struct madera *madera = priv->madera;
|
||||
@ -1329,7 +1328,7 @@ static unsigned int cs47l15_digital_vu[] = {
|
||||
MADERA_DAC_DIGITAL_VOLUME_5R,
|
||||
};
|
||||
|
||||
static const struct snd_compr_ops cs47l15_compr_ops = {
|
||||
static const struct snd_compress_ops cs47l15_compress_ops = {
|
||||
.open = &cs47l15_open,
|
||||
.free = &wm_adsp_compr_free,
|
||||
.set_params = &wm_adsp_compr_set_params,
|
||||
@ -1345,7 +1344,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l15 = {
|
||||
.set_sysclk = &madera_set_sysclk,
|
||||
.set_pll = &cs47l15_set_fll,
|
||||
.name = DRV_NAME,
|
||||
.compr_ops = &cs47l15_compr_ops,
|
||||
.compress_ops = &cs47l15_compress_ops,
|
||||
.controls = cs47l15_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(cs47l15_snd_controls),
|
||||
.dapm_widgets = cs47l15_dapm_widgets,
|
||||
|
@ -1068,10 +1068,10 @@ static struct snd_soc_dai_driver cs47l24_dai[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int cs47l24_open(struct snd_compr_stream *stream)
|
||||
static int cs47l24_open(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = stream->private_data;
|
||||
struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
|
||||
struct cs47l24_priv *priv = snd_soc_component_get_drvdata(component);
|
||||
struct arizona *arizona = priv->core.arizona;
|
||||
int n_adsp;
|
||||
@ -1178,7 +1178,7 @@ static unsigned int cs47l24_digital_vu[] = {
|
||||
ARIZONA_DAC_DIGITAL_VOLUME_4L,
|
||||
};
|
||||
|
||||
static struct snd_compr_ops cs47l24_compr_ops = {
|
||||
static struct snd_compress_ops cs47l24_compress_ops = {
|
||||
.open = cs47l24_open,
|
||||
.free = wm_adsp_compr_free,
|
||||
.set_params = wm_adsp_compr_set_params,
|
||||
@ -1194,7 +1194,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l24 = {
|
||||
.set_sysclk = arizona_set_sysclk,
|
||||
.set_pll = cs47l24_set_fll,
|
||||
.name = DRV_NAME,
|
||||
.compr_ops = &cs47l24_compr_ops,
|
||||
.compress_ops = &cs47l24_compress_ops,
|
||||
.controls = cs47l24_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(cs47l24_snd_controls),
|
||||
.dapm_widgets = cs47l24_dapm_widgets,
|
||||
|
@ -1504,11 +1504,10 @@ static struct snd_soc_dai_driver cs47l35_dai[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int cs47l35_open(struct snd_compr_stream *stream)
|
||||
static int cs47l35_open(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = stream->private_data;
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
|
||||
struct cs47l35 *cs47l35 = snd_soc_component_get_drvdata(component);
|
||||
struct madera_priv *priv = &cs47l35->core;
|
||||
struct madera *madera = priv->madera;
|
||||
@ -1622,7 +1621,7 @@ static unsigned int cs47l35_digital_vu[] = {
|
||||
MADERA_DAC_DIGITAL_VOLUME_5R,
|
||||
};
|
||||
|
||||
static const struct snd_compr_ops cs47l35_compr_ops = {
|
||||
static const struct snd_compress_ops cs47l35_compress_ops = {
|
||||
.open = &cs47l35_open,
|
||||
.free = &wm_adsp_compr_free,
|
||||
.set_params = &wm_adsp_compr_set_params,
|
||||
@ -1638,7 +1637,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l35 = {
|
||||
.set_sysclk = &madera_set_sysclk,
|
||||
.set_pll = &cs47l35_set_fll,
|
||||
.name = DRV_NAME,
|
||||
.compr_ops = &cs47l35_compr_ops,
|
||||
.compress_ops = &cs47l35_compress_ops,
|
||||
.controls = cs47l35_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(cs47l35_snd_controls),
|
||||
.dapm_widgets = cs47l35_dapm_widgets,
|
||||
|
@ -2447,11 +2447,10 @@ static struct snd_soc_dai_driver cs47l85_dai[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int cs47l85_open(struct snd_compr_stream *stream)
|
||||
static int cs47l85_open(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = stream->private_data;
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
|
||||
struct cs47l85 *cs47l85 = snd_soc_component_get_drvdata(component);
|
||||
struct madera_priv *priv = &cs47l85->core;
|
||||
struct madera *madera = priv->madera;
|
||||
@ -2566,7 +2565,7 @@ static const unsigned int cs47l85_digital_vu[] = {
|
||||
MADERA_DAC_DIGITAL_VOLUME_6R,
|
||||
};
|
||||
|
||||
static const struct snd_compr_ops cs47l85_compr_ops = {
|
||||
static const struct snd_compress_ops cs47l85_compress_ops = {
|
||||
.open = &cs47l85_open,
|
||||
.free = &wm_adsp_compr_free,
|
||||
.set_params = &wm_adsp_compr_set_params,
|
||||
@ -2582,7 +2581,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l85 = {
|
||||
.set_sysclk = &madera_set_sysclk,
|
||||
.set_pll = &cs47l85_set_fll,
|
||||
.name = DRV_NAME,
|
||||
.compr_ops = &cs47l85_compr_ops,
|
||||
.compress_ops = &cs47l85_compress_ops,
|
||||
.controls = cs47l85_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(cs47l85_snd_controls),
|
||||
.dapm_widgets = cs47l85_dapm_widgets,
|
||||
|
@ -2358,11 +2358,10 @@ static struct snd_soc_dai_driver cs47l90_dai[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int cs47l90_open(struct snd_compr_stream *stream)
|
||||
static int cs47l90_open(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = stream->private_data;
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
|
||||
struct cs47l90 *cs47l90 = snd_soc_component_get_drvdata(component);
|
||||
struct madera_priv *priv = &cs47l90->core;
|
||||
struct madera *madera = priv->madera;
|
||||
@ -2473,7 +2472,7 @@ static unsigned int cs47l90_digital_vu[] = {
|
||||
MADERA_DAC_DIGITAL_VOLUME_5R,
|
||||
};
|
||||
|
||||
static const struct snd_compr_ops cs47l90_compr_ops = {
|
||||
static const struct snd_compress_ops cs47l90_compress_ops = {
|
||||
.open = &cs47l90_open,
|
||||
.free = &wm_adsp_compr_free,
|
||||
.set_params = &wm_adsp_compr_set_params,
|
||||
@ -2489,7 +2488,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l90 = {
|
||||
.set_sysclk = &madera_set_sysclk,
|
||||
.set_pll = &cs47l90_set_fll,
|
||||
.name = DRV_NAME,
|
||||
.compr_ops = &cs47l90_compr_ops,
|
||||
.compress_ops = &cs47l90_compress_ops,
|
||||
.controls = cs47l90_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(cs47l90_snd_controls),
|
||||
.dapm_widgets = cs47l90_dapm_widgets,
|
||||
|
@ -1830,11 +1830,10 @@ static struct snd_soc_dai_driver cs47l92_dai[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int cs47l92_open(struct snd_compr_stream *stream)
|
||||
static int cs47l92_open(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *stream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = stream->private_data;
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_rtdcom_lookup(rtd, DRV_NAME);
|
||||
struct cs47l92 *cs47l92 = snd_soc_component_get_drvdata(component);
|
||||
struct madera_priv *priv = &cs47l92->core;
|
||||
struct madera *madera = priv->madera;
|
||||
@ -1933,7 +1932,7 @@ static unsigned int cs47l92_digital_vu[] = {
|
||||
MADERA_DAC_DIGITAL_VOLUME_5R,
|
||||
};
|
||||
|
||||
static const struct snd_compr_ops cs47l92_compr_ops = {
|
||||
static const struct snd_compress_ops cs47l92_compress_ops = {
|
||||
.open = &cs47l92_open,
|
||||
.free = &wm_adsp_compr_free,
|
||||
.set_params = &wm_adsp_compr_set_params,
|
||||
@ -1949,7 +1948,7 @@ static const struct snd_soc_component_driver soc_component_dev_cs47l92 = {
|
||||
.set_sysclk = &madera_set_sysclk,
|
||||
.set_pll = &cs47l92_set_fll,
|
||||
.name = DRV_NAME,
|
||||
.compr_ops = &cs47l92_compr_ops,
|
||||
.compress_ops = &cs47l92_compress_ops,
|
||||
.controls = cs47l92_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(cs47l92_snd_controls),
|
||||
.dapm_widgets = cs47l92_dapm_widgets,
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/tlv.h>
|
||||
@ -806,6 +807,11 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
|
||||
*/
|
||||
|
||||
static const struct snd_soc_dapm_widget da7213_dapm_widgets[] = {
|
||||
/*
|
||||
* Power Supply
|
||||
*/
|
||||
SND_SOC_DAPM_REGULATOR_SUPPLY("VDDMIC", 0, 0),
|
||||
|
||||
/*
|
||||
* Input & Output
|
||||
*/
|
||||
@ -932,6 +938,9 @@ static const struct snd_soc_dapm_route da7213_audio_map[] = {
|
||||
/* Dest Connecting Widget source */
|
||||
|
||||
/* Input path */
|
||||
{"Mic Bias 1", NULL, "VDDMIC"},
|
||||
{"Mic Bias 2", NULL, "VDDMIC"},
|
||||
|
||||
{"MIC1", NULL, "Mic Bias 1"},
|
||||
{"MIC2", NULL, "Mic Bias 2"},
|
||||
|
||||
@ -1334,10 +1343,10 @@ static int da7213_mute(struct snd_soc_dai *dai, int mute)
|
||||
#define DA7213_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
|
||||
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
||||
static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
||||
int clk_id, unsigned int freq, int dir)
|
||||
static int da7213_set_component_sysclk(struct snd_soc_component *component,
|
||||
int clk_id, int source,
|
||||
unsigned int freq, int dir)
|
||||
{
|
||||
struct snd_soc_component *component = codec_dai->component;
|
||||
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
|
||||
int ret = 0;
|
||||
|
||||
@ -1345,7 +1354,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
||||
return 0;
|
||||
|
||||
if (((freq < 5000000) && (freq != 32768)) || (freq > 54000000)) {
|
||||
dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
|
||||
dev_err(component->dev, "Unsupported MCLK value %d\n",
|
||||
freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1361,7 +1370,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
||||
DA7213_PLL_MCLK_SQR_EN);
|
||||
break;
|
||||
default:
|
||||
dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
|
||||
dev_err(component->dev, "Unknown clock source %d\n", clk_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1371,7 +1380,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
||||
freq = clk_round_rate(da7213->mclk, freq);
|
||||
ret = clk_set_rate(da7213->mclk, freq);
|
||||
if (ret) {
|
||||
dev_err(codec_dai->dev, "Failed to set clock rate %d\n",
|
||||
dev_err(component->dev, "Failed to set clock rate %d\n",
|
||||
freq);
|
||||
return ret;
|
||||
}
|
||||
@ -1383,10 +1392,10 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
||||
}
|
||||
|
||||
/* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */
|
||||
static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
|
||||
int source, unsigned int fref, unsigned int fout)
|
||||
static int da7213_set_component_pll(struct snd_soc_component *component,
|
||||
int pll_id, int source,
|
||||
unsigned int fref, unsigned int fout)
|
||||
{
|
||||
struct snd_soc_component *component = codec_dai->component;
|
||||
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
u8 pll_ctrl, indiv_bits, indiv;
|
||||
@ -1498,8 +1507,6 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
|
||||
static const struct snd_soc_dai_ops da7213_dai_ops = {
|
||||
.hw_params = da7213_hw_params,
|
||||
.set_fmt = da7213_set_dai_fmt,
|
||||
.set_sysclk = da7213_set_dai_sysclk,
|
||||
.set_pll = da7213_set_dai_pll,
|
||||
.digital_mute = da7213_mute,
|
||||
};
|
||||
|
||||
@ -1571,6 +1578,7 @@ static int da7213_set_bias_level(struct snd_soc_component *component,
|
||||
#if defined(CONFIG_OF)
|
||||
/* DT */
|
||||
static const struct of_device_id da7213_of_match[] = {
|
||||
{ .compatible = "dlg,da7212", },
|
||||
{ .compatible = "dlg,da7213", },
|
||||
{ }
|
||||
};
|
||||
@ -1690,6 +1698,8 @@ static int da7213_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
pm_runtime_get_sync(component->dev);
|
||||
|
||||
/* Default to using ALC auto offset calibration mode. */
|
||||
snd_soc_component_update_bits(component, DA7213_ALC_CTRL1,
|
||||
DA7213_ALC_CALIB_MODE_MAN, 0);
|
||||
@ -1810,6 +1820,8 @@ static int da7213_probe(struct snd_soc_component *component)
|
||||
DA7213_DMIC_CLK_RATE_MASK, dmic_cfg);
|
||||
}
|
||||
|
||||
pm_runtime_put_sync(component->dev);
|
||||
|
||||
/* Check if MCLK provided */
|
||||
da7213->mclk = devm_clk_get(component->dev, "mclk");
|
||||
if (IS_ERR(da7213->mclk)) {
|
||||
@ -1831,6 +1843,8 @@ static const struct snd_soc_component_driver soc_component_dev_da7213 = {
|
||||
.num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets),
|
||||
.dapm_routes = da7213_audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(da7213_audio_map),
|
||||
.set_sysclk = da7213_set_component_sysclk,
|
||||
.set_pll = da7213_set_component_pll,
|
||||
.idle_bias_on = 1,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
@ -1847,11 +1861,22 @@ static const struct regmap_config da7213_regmap_config = {
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static void da7213_power_off(void *data)
|
||||
{
|
||||
struct da7213_priv *da7213 = data;
|
||||
regulator_bulk_disable(DA7213_NUM_SUPPLIES, da7213->supplies);
|
||||
}
|
||||
|
||||
static const char *da7213_supply_names[DA7213_NUM_SUPPLIES] = {
|
||||
[DA7213_SUPPLY_VDDA] = "VDDA",
|
||||
[DA7213_SUPPLY_VDDIO] = "VDDIO",
|
||||
};
|
||||
|
||||
static int da7213_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct da7213_priv *da7213;
|
||||
int ret;
|
||||
int i, ret;
|
||||
|
||||
da7213 = devm_kzalloc(&i2c->dev, sizeof(*da7213), GFP_KERNEL);
|
||||
if (!da7213)
|
||||
@ -1859,6 +1884,25 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
|
||||
|
||||
i2c_set_clientdata(i2c, da7213);
|
||||
|
||||
/* Get required supplies */
|
||||
for (i = 0; i < DA7213_NUM_SUPPLIES; ++i)
|
||||
da7213->supplies[i].supply = da7213_supply_names[i];
|
||||
|
||||
ret = devm_regulator_bulk_get(&i2c->dev, DA7213_NUM_SUPPLIES,
|
||||
da7213->supplies);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "Failed to get supplies: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regulator_bulk_enable(DA7213_NUM_SUPPLIES, da7213->supplies);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(&i2c->dev, da7213_power_off, da7213);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
da7213->regmap = devm_regmap_init_i2c(i2c, &da7213_regmap_config);
|
||||
if (IS_ERR(da7213->regmap)) {
|
||||
ret = PTR_ERR(da7213->regmap);
|
||||
@ -1866,6 +1910,11 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
|
||||
return ret;
|
||||
}
|
||||
|
||||
pm_runtime_set_autosuspend_delay(&i2c->dev, 100);
|
||||
pm_runtime_use_autosuspend(&i2c->dev);
|
||||
pm_runtime_set_active(&i2c->dev);
|
||||
pm_runtime_enable(&i2c->dev);
|
||||
|
||||
ret = devm_snd_soc_register_component(&i2c->dev,
|
||||
&soc_component_dev_da7213, &da7213_dai, 1);
|
||||
if (ret < 0) {
|
||||
@ -1875,6 +1924,34 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __maybe_unused da7213_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct da7213_priv *da7213 = dev_get_drvdata(dev);
|
||||
|
||||
regcache_cache_only(da7213->regmap, true);
|
||||
regcache_mark_dirty(da7213->regmap);
|
||||
regulator_bulk_disable(DA7213_NUM_SUPPLIES, da7213->supplies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused da7213_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct da7213_priv *da7213 = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = regulator_bulk_enable(DA7213_NUM_SUPPLIES, da7213->supplies);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
regcache_cache_only(da7213->regmap, false);
|
||||
regcache_sync(da7213->regmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops da7213_pm = {
|
||||
SET_RUNTIME_PM_OPS(da7213_runtime_suspend, da7213_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static const struct i2c_device_id da7213_i2c_id[] = {
|
||||
{ "da7213", 0 },
|
||||
{ }
|
||||
@ -1887,6 +1964,7 @@ static struct i2c_driver da7213_i2c_driver = {
|
||||
.name = "da7213",
|
||||
.of_match_table = of_match_ptr(da7213_of_match),
|
||||
.acpi_match_table = ACPI_PTR(da7213_acpi_match),
|
||||
.pm = &da7213_pm,
|
||||
},
|
||||
.probe = da7213_i2c_probe,
|
||||
.id_table = da7213_i2c_id,
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <sound/da7213.h>
|
||||
|
||||
/*
|
||||
@ -521,9 +522,17 @@ enum da7213_sys_clk {
|
||||
DA7213_SYSCLK_PLL_32KHZ
|
||||
};
|
||||
|
||||
/* Regulators */
|
||||
enum da7213_supplies {
|
||||
DA7213_SUPPLY_VDDA = 0,
|
||||
DA7213_SUPPLY_VDDIO,
|
||||
DA7213_NUM_SUPPLIES,
|
||||
};
|
||||
|
||||
/* Codec private data */
|
||||
struct da7213_priv {
|
||||
struct regmap *regmap;
|
||||
struct regulator_bulk_data supplies[DA7213_NUM_SUPPLIES];
|
||||
struct clk *mclk;
|
||||
unsigned int mclk_rate;
|
||||
int clk_src;
|
||||
|
@ -59,14 +59,14 @@ static int dmic_aif_event(struct snd_soc_dapm_widget *w,
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
if (dmic->gpio_en)
|
||||
gpiod_set_value(dmic->gpio_en, 1);
|
||||
gpiod_set_value_cansleep(dmic->gpio_en, 1);
|
||||
|
||||
if (dmic->wakeup_delay)
|
||||
msleep(dmic->wakeup_delay);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
if (dmic->gpio_en)
|
||||
gpiod_set_value(dmic->gpio_en, 0);
|
||||
gpiod_set_value_cansleep(dmic->gpio_en, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -574,19 +574,17 @@ static int jz4725b_codec_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id jz4725b_codec_of_matches[] = {
|
||||
{ .compatible = "ingenic,jz4725b-codec", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, jz4725b_codec_of_matches);
|
||||
#endif
|
||||
|
||||
static struct platform_driver jz4725b_codec_driver = {
|
||||
.probe = jz4725b_codec_probe,
|
||||
.driver = {
|
||||
.name = "jz4725b-codec",
|
||||
.of_match_table = of_match_ptr(jz4725b_codec_of_matches),
|
||||
.of_match_table = jz4725b_codec_of_matches,
|
||||
},
|
||||
};
|
||||
module_platform_driver(jz4725b_codec_driver);
|
||||
|
@ -344,19 +344,17 @@ static int jz4740_codec_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id jz4740_codec_of_matches[] = {
|
||||
{ .compatible = "ingenic,jz4740-codec", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, jz4740_codec_of_matches);
|
||||
#endif
|
||||
|
||||
static struct platform_driver jz4740_codec_driver = {
|
||||
.probe = jz4740_codec_probe,
|
||||
.driver = {
|
||||
.name = "jz4740-codec",
|
||||
.of_match_table = of_match_ptr(jz4740_codec_of_matches),
|
||||
.of_match_table = jz4740_codec_of_matches,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -937,7 +937,7 @@ static struct platform_driver jz4770_codec_driver = {
|
||||
.probe = jz4770_codec_probe,
|
||||
.driver = {
|
||||
.name = "jz4770-codec",
|
||||
.of_match_table = of_match_ptr(jz4770_codec_of_matches),
|
||||
.of_match_table = jz4770_codec_of_matches,
|
||||
},
|
||||
};
|
||||
module_platform_driver(jz4770_codec_driver);
|
||||
|
@ -3279,7 +3279,7 @@ static int madera_dai_set_sysclk(struct snd_soc_dai *dai,
|
||||
if (is_sync == madera_is_syncclk(dai_priv->clk))
|
||||
return 0;
|
||||
|
||||
if (dai->active) {
|
||||
if (snd_soc_dai_active(dai)) {
|
||||
dev_err(component->dev, "Can't change clock on active DAI %d\n",
|
||||
dai->id);
|
||||
return -EBUSY;
|
||||
|
@ -2039,7 +2039,7 @@ static int max98090_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
if (!max98090->master && dai->active == 1)
|
||||
if (!max98090->master && snd_soc_dai_active(dai) == 1)
|
||||
queue_delayed_work(system_power_efficient_wq,
|
||||
&max98090->pll_det_enable_work,
|
||||
msecs_to_jiffies(10));
|
||||
@ -2047,7 +2047,7 @@ static int max98090_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
if (!max98090->master && dai->active == 1)
|
||||
if (!max98090->master && snd_soc_dai_active(dai) == 1)
|
||||
schedule_work(&max98090->pll_det_disable_work);
|
||||
break;
|
||||
default:
|
||||
@ -2109,7 +2109,7 @@ static void max98090_pll_work(struct max98090_priv *max98090)
|
||||
unsigned int pll;
|
||||
int i;
|
||||
|
||||
if (!snd_soc_component_is_active(component))
|
||||
if (!snd_soc_component_active(component))
|
||||
return;
|
||||
|
||||
dev_info_ratelimited(component->dev, "PLL unlocked\n");
|
||||
|
1040
sound/soc/codecs/max98390.c
Normal file
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
663
sound/soc/codecs/max98390.h
Normal 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
|
@ -23,8 +23,21 @@ static const char *const max9867_spmode[] = {
|
||||
};
|
||||
static const char *const max9867_filter_text[] = {"IIR", "FIR"};
|
||||
|
||||
static const char *const max9867_adc_dac_filter_text[] = {
|
||||
"Disabled",
|
||||
"Elliptical/16/256",
|
||||
"Butterworth/16/500",
|
||||
"Elliptical/8/256",
|
||||
"Butterworth/8/500",
|
||||
"Butterworth/8-24"
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(max9867_filter, MAX9867_CODECFLTR, 7,
|
||||
max9867_filter_text);
|
||||
static SOC_ENUM_SINGLE_DECL(max9867_dac_filter, MAX9867_CODECFLTR, 0,
|
||||
max9867_adc_dac_filter_text);
|
||||
static SOC_ENUM_SINGLE_DECL(max9867_adc_filter, MAX9867_CODECFLTR, 4,
|
||||
max9867_adc_dac_filter_text);
|
||||
static SOC_ENUM_SINGLE_DECL(max9867_spkmode, MAX9867_MODECONFIG, 0,
|
||||
max9867_spmode);
|
||||
static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max9867_master_tlv,
|
||||
@ -64,6 +77,9 @@ static const struct snd_kcontrol_new max9867_snd_controls[] = {
|
||||
SOC_SINGLE("Volume Smoothing Switch", MAX9867_MODECONFIG, 6, 1, 0),
|
||||
SOC_SINGLE("Line ZC Switch", MAX9867_MODECONFIG, 5, 1, 0),
|
||||
SOC_ENUM("DSP Filter", max9867_filter),
|
||||
SOC_ENUM("ADC Filter", max9867_adc_filter),
|
||||
SOC_ENUM("DAC Filter", max9867_dac_filter),
|
||||
SOC_SINGLE("Mono Playback Switch", MAX9867_IFC1B, 3, 1, 0),
|
||||
};
|
||||
|
||||
/* Input mixer */
|
||||
@ -88,20 +104,38 @@ static const struct snd_kcontrol_new max9867_line_out_control =
|
||||
SOC_DAPM_DOUBLE_R("Switch",
|
||||
MAX9867_LEFTVOL, MAX9867_RIGHTVOL, 6, 1, 1);
|
||||
|
||||
/* DMIC mux */
|
||||
static const char *const dmic_mux_text[] = {
|
||||
"ADC", "DMIC"
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(left_dmic_mux_enum,
|
||||
MAX9867_MICCONFIG, 5, dmic_mux_text);
|
||||
static SOC_ENUM_SINGLE_DECL(right_dmic_mux_enum,
|
||||
MAX9867_MICCONFIG, 4, dmic_mux_text);
|
||||
static const struct snd_kcontrol_new max9867_left_dmic_mux =
|
||||
SOC_DAPM_ENUM("DMICL Mux", left_dmic_mux_enum);
|
||||
static const struct snd_kcontrol_new max9867_right_dmic_mux =
|
||||
SOC_DAPM_ENUM("DMICR Mux", right_dmic_mux_enum);
|
||||
|
||||
static const struct snd_soc_dapm_widget max9867_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_INPUT("MICL"),
|
||||
SND_SOC_DAPM_INPUT("MICR"),
|
||||
SND_SOC_DAPM_INPUT("DMICL"),
|
||||
SND_SOC_DAPM_INPUT("DMICR"),
|
||||
SND_SOC_DAPM_INPUT("LINL"),
|
||||
SND_SOC_DAPM_INPUT("LINR"),
|
||||
|
||||
SND_SOC_DAPM_PGA("Left Line Input", MAX9867_PWRMAN, 6, 0, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("Right Line Input", MAX9867_PWRMAN, 5, 0, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("Left Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
SND_SOC_DAPM_PGA("Right Line Input", SND_SOC_NOPM, 0, 0, NULL, 0),
|
||||
SND_SOC_DAPM_MIXER_NAMED_CTL("Input Mixer", SND_SOC_NOPM, 0, 0,
|
||||
max9867_input_mixer_controls,
|
||||
ARRAY_SIZE(max9867_input_mixer_controls)),
|
||||
SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", MAX9867_PWRMAN, 1, 0),
|
||||
SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", MAX9867_PWRMAN, 0, 0),
|
||||
SND_SOC_DAPM_MUX("DMICL Mux", SND_SOC_NOPM, 0, 0,
|
||||
&max9867_left_dmic_mux),
|
||||
SND_SOC_DAPM_MUX("DMICR Mux", SND_SOC_NOPM, 0, 0,
|
||||
&max9867_right_dmic_mux),
|
||||
SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", SND_SOC_NOPM, 0, 0),
|
||||
|
||||
SND_SOC_DAPM_MIXER("Digital", SND_SOC_NOPM, 0, 0,
|
||||
max9867_sidetone_mixer_controls,
|
||||
@ -109,8 +143,8 @@ static const struct snd_soc_dapm_widget max9867_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_MIXER_NAMED_CTL("Output Mixer", SND_SOC_NOPM, 0, 0,
|
||||
max9867_output_mixer_controls,
|
||||
ARRAY_SIZE(max9867_output_mixer_controls)),
|
||||
SND_SOC_DAPM_DAC("DACL", "HiFi Playback", MAX9867_PWRMAN, 3, 0),
|
||||
SND_SOC_DAPM_DAC("DACR", "HiFi Playback", MAX9867_PWRMAN, 2, 0),
|
||||
SND_SOC_DAPM_DAC("DACL", "HiFi Playback", SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_DAC("DACR", "HiFi Playback", SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_SWITCH("Master Playback", SND_SOC_NOPM, 0, 0,
|
||||
&max9867_line_out_control),
|
||||
SND_SOC_DAPM_OUTPUT("LOUT"),
|
||||
@ -124,8 +158,12 @@ static const struct snd_soc_dapm_route max9867_audio_map[] = {
|
||||
{"Input Mixer", "Mic Capture Switch", "MICR"},
|
||||
{"Input Mixer", "Line Capture Switch", "Left Line Input"},
|
||||
{"Input Mixer", "Line Capture Switch", "Right Line Input"},
|
||||
{"ADCL", NULL, "Input Mixer"},
|
||||
{"ADCR", NULL, "Input Mixer"},
|
||||
{"DMICL Mux", "DMIC", "DMICL"},
|
||||
{"DMICR Mux", "DMIC", "DMICR"},
|
||||
{"DMICL Mux", "ADC", "Input Mixer"},
|
||||
{"DMICR Mux", "ADC", "Input Mixer"},
|
||||
{"ADCL", NULL, "DMICL Mux"},
|
||||
{"ADCR", NULL, "DMICR Mux"},
|
||||
|
||||
{"Digital", "Sidetone Switch", "ADCL"},
|
||||
{"Digital", "Sidetone Switch", "ADCR"},
|
||||
@ -346,7 +384,8 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
|
||||
}
|
||||
|
||||
regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A);
|
||||
regmap_write(max9867->regmap, MAX9867_IFC1B, iface1B);
|
||||
regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
|
||||
MAX9867_IFC1B_BCLK_MASK, iface1B);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -413,15 +452,14 @@ static int max9867_set_bias_level(struct snd_soc_component *component,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
|
||||
MAX9867_SHTDOWN, MAX9867_SHTDOWN);
|
||||
err = regmap_write(max9867->regmap,
|
||||
MAX9867_PWRMAN, 0xff);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
case SND_SOC_BIAS_OFF:
|
||||
err = regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
|
||||
MAX9867_SHTDOWN, 0);
|
||||
err = regmap_write(max9867->regmap, MAX9867_PWRMAN, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -463,35 +501,10 @@ static bool max9867_volatile_register(struct device *dev, unsigned int reg)
|
||||
}
|
||||
}
|
||||
|
||||
static const struct reg_default max9867_reg[] = {
|
||||
{ 0x04, 0x00 },
|
||||
{ 0x05, 0x00 },
|
||||
{ 0x06, 0x00 },
|
||||
{ 0x07, 0x00 },
|
||||
{ 0x08, 0x00 },
|
||||
{ 0x09, 0x00 },
|
||||
{ 0x0A, 0x00 },
|
||||
{ 0x0B, 0x00 },
|
||||
{ 0x0C, 0x00 },
|
||||
{ 0x0D, 0x00 },
|
||||
{ 0x0E, 0x40 },
|
||||
{ 0x0F, 0x40 },
|
||||
{ 0x10, 0x00 },
|
||||
{ 0x11, 0x00 },
|
||||
{ 0x12, 0x00 },
|
||||
{ 0x13, 0x00 },
|
||||
{ 0x14, 0x00 },
|
||||
{ 0x15, 0x00 },
|
||||
{ 0x16, 0x00 },
|
||||
{ 0x17, 0x00 },
|
||||
};
|
||||
|
||||
static const struct regmap_config max9867_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = MAX9867_REVISION,
|
||||
.reg_defaults = max9867_reg,
|
||||
.num_reg_defaults = ARRAY_SIZE(max9867_reg),
|
||||
.volatile_reg = max9867_volatile_register,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
@ -58,7 +58,6 @@
|
||||
#define MAX9867_MICCONFIG 0x15
|
||||
#define MAX9867_MODECONFIG 0x16
|
||||
#define MAX9867_PWRMAN 0x17
|
||||
#define MAX9867_SHTDOWN 0x80
|
||||
#define MAX9867_REVISION 0xff
|
||||
|
||||
#define MAX9867_CACHEREGNUM 10
|
||||
|
@ -355,6 +355,8 @@ static const struct snd_kcontrol_new nau8810_snd_controls[] = {
|
||||
|
||||
/* Speaker Output Mixer */
|
||||
static const struct snd_kcontrol_new nau8810_speaker_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("AUX Bypass Switch", NAU8810_REG_SPKMIX,
|
||||
NAU8810_AUXSPK_SFT, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_SPKMIX,
|
||||
NAU8810_BYPSPK_SFT, 1, 0),
|
||||
SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_SPKMIX,
|
||||
@ -363,6 +365,8 @@ static const struct snd_kcontrol_new nau8810_speaker_mixer_controls[] = {
|
||||
|
||||
/* Mono Output Mixer */
|
||||
static const struct snd_kcontrol_new nau8810_mono_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("AUX Bypass Switch", NAU8810_REG_MONOMIX,
|
||||
NAU8810_AUXMOUT_SFT, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line Bypass Switch", NAU8810_REG_MONOMIX,
|
||||
NAU8810_BYPMOUT_SFT, 1, 0),
|
||||
SOC_DAPM_SINGLE("PCM Playback Switch", NAU8810_REG_MONOMIX,
|
||||
@ -371,6 +375,8 @@ static const struct snd_kcontrol_new nau8810_mono_mixer_controls[] = {
|
||||
|
||||
/* PGA Mute */
|
||||
static const struct snd_kcontrol_new nau8810_pgaboost_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("AUX PGA Switch", NAU8810_REG_ADCBOOST,
|
||||
NAU8810_AUXBSTGAIN_SFT, 0x7, 0),
|
||||
SOC_DAPM_SINGLE("PGA Mute Switch", NAU8810_REG_PGAGAIN,
|
||||
NAU8810_PGAMT_SFT, 1, 1),
|
||||
SOC_DAPM_SINGLE("PMIC PGA Switch", NAU8810_REG_ADCBOOST,
|
||||
@ -379,6 +385,8 @@ static const struct snd_kcontrol_new nau8810_pgaboost_mixer_controls[] = {
|
||||
|
||||
/* Input PGA */
|
||||
static const struct snd_kcontrol_new nau8810_inpga[] = {
|
||||
SOC_DAPM_SINGLE("AUX Switch", NAU8810_REG_INPUT_SIGNAL,
|
||||
NAU8810_AUXPGA_SFT, 1, 0),
|
||||
SOC_DAPM_SINGLE("MicN Switch", NAU8810_REG_INPUT_SIGNAL,
|
||||
NAU8810_NMICPGA_SFT, 1, 0),
|
||||
SOC_DAPM_SINGLE("MicP Switch", NAU8810_REG_INPUT_SIGNAL,
|
||||
@ -401,6 +409,23 @@ static int check_mclk_select_pll(struct snd_soc_dapm_widget *source,
|
||||
return (value & NAU8810_CLKM_MASK);
|
||||
}
|
||||
|
||||
static int check_mic_enabled(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_dapm_to_component(source->dapm);
|
||||
struct nau8810 *nau8810 = snd_soc_component_get_drvdata(component);
|
||||
unsigned int value;
|
||||
|
||||
regmap_read(nau8810->regmap, NAU8810_REG_INPUT_SIGNAL, &value);
|
||||
if (value & NAU8810_PMICPGA_EN || value & NAU8810_NMICPGA_EN)
|
||||
return 1;
|
||||
regmap_read(nau8810->regmap, NAU8810_REG_ADCBOOST, &value);
|
||||
if (value & NAU8810_PMICBSTGAIN_MASK)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_MIXER("Speaker Mixer", NAU8810_REG_POWER3,
|
||||
NAU8810_SPKMX_EN_SFT, 0, &nau8810_speaker_mixer_controls[0],
|
||||
@ -425,6 +450,8 @@ static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_MIXER("Input Boost Stage", NAU8810_REG_POWER2,
|
||||
NAU8810_BST_EN_SFT, 0, nau8810_pgaboost_mixer_controls,
|
||||
ARRAY_SIZE(nau8810_pgaboost_mixer_controls)),
|
||||
SND_SOC_DAPM_PGA("AUX Input", NAU8810_REG_POWER1,
|
||||
NAU8810_AUX_EN_SFT, 0, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_SUPPLY("Mic Bias", NAU8810_REG_POWER1,
|
||||
NAU8810_MICBIAS_EN_SFT, 0, NULL, 0),
|
||||
@ -434,6 +461,7 @@ static const struct snd_soc_dapm_widget nau8810_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_SWITCH("Digital Loopback", SND_SOC_NOPM, 0, 0,
|
||||
&nau8810_loopback),
|
||||
|
||||
SND_SOC_DAPM_INPUT("AUX"),
|
||||
SND_SOC_DAPM_INPUT("MICN"),
|
||||
SND_SOC_DAPM_INPUT("MICP"),
|
||||
SND_SOC_DAPM_OUTPUT("MONOOUT"),
|
||||
@ -445,10 +473,12 @@ static const struct snd_soc_dapm_route nau8810_dapm_routes[] = {
|
||||
{"DAC", NULL, "PLL", check_mclk_select_pll},
|
||||
|
||||
/* Mono output mixer */
|
||||
{"Mono Mixer", "AUX Bypass Switch", "AUX Input"},
|
||||
{"Mono Mixer", "PCM Playback Switch", "DAC"},
|
||||
{"Mono Mixer", "Line Bypass Switch", "Input Boost Stage"},
|
||||
|
||||
/* Speaker output mixer */
|
||||
{"Speaker Mixer", "AUX Bypass Switch", "AUX Input"},
|
||||
{"Speaker Mixer", "PCM Playback Switch", "DAC"},
|
||||
{"Speaker Mixer", "Line Bypass Switch", "Input Boost Stage"},
|
||||
|
||||
@ -463,13 +493,16 @@ static const struct snd_soc_dapm_route nau8810_dapm_routes[] = {
|
||||
/* Input Boost Stage */
|
||||
{"ADC", NULL, "Input Boost Stage"},
|
||||
{"ADC", NULL, "PLL", check_mclk_select_pll},
|
||||
{"Input Boost Stage", "AUX PGA Switch", "AUX Input"},
|
||||
{"Input Boost Stage", "PGA Mute Switch", "Input PGA"},
|
||||
{"Input Boost Stage", "PMIC PGA Switch", "MICP"},
|
||||
|
||||
/* Input PGA */
|
||||
{"Input PGA", NULL, "Mic Bias"},
|
||||
{"Input PGA", NULL, "Mic Bias", check_mic_enabled},
|
||||
{"Input PGA", "AUX Switch", "AUX Input"},
|
||||
{"Input PGA", "MicN Switch", "MICN"},
|
||||
{"Input PGA", "MicP Switch", "MICP"},
|
||||
{"AUX Input", NULL, "AUX"},
|
||||
|
||||
/* Digital Looptack */
|
||||
{"Digital Loopback", "Switch", "ADC"},
|
||||
@ -862,6 +895,8 @@ static int nau8810_i2c_probe(struct i2c_client *i2c,
|
||||
|
||||
static const struct i2c_device_id nau8810_i2c_id[] = {
|
||||
{ "nau8810", 0 },
|
||||
{ "nau8812", 0 },
|
||||
{ "nau8814", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, nau8810_i2c_id);
|
||||
@ -869,6 +904,8 @@ MODULE_DEVICE_TABLE(i2c, nau8810_i2c_id);
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id nau8810_of_match[] = {
|
||||
{ .compatible = "nuvoton,nau8810", },
|
||||
{ .compatible = "nuvoton,nau8812", },
|
||||
{ .compatible = "nuvoton,nau8814", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, nau8810_of_match);
|
||||
|
@ -69,6 +69,7 @@
|
||||
|
||||
/* NAU8810_REG_POWER1 (0x1) */
|
||||
#define NAU8810_DCBUF_EN (0x1 << 8)
|
||||
#define NAU8810_AUX_EN_SFT 6
|
||||
#define NAU8810_PLL_EN_SFT 5
|
||||
#define NAU8810_MICBIAS_EN_SFT 4
|
||||
#define NAU8810_ABIAS_EN (0x1 << 3)
|
||||
@ -228,7 +229,10 @@
|
||||
|
||||
/* NAU8810_REG_INPUT_SIGNAL (0x2C) */
|
||||
#define NAU8810_PMICPGA_SFT 0
|
||||
#define NAU8810_PMICPGA_EN (0x1 << NAU8810_PMICPGA_SFT)
|
||||
#define NAU8810_NMICPGA_SFT 1
|
||||
#define NAU8810_NMICPGA_EN (0x1 << NAU8810_NMICPGA_SFT)
|
||||
#define NAU8810_AUXPGA_SFT 2
|
||||
|
||||
/* NAU8810_REG_PGAGAIN (0x2D) */
|
||||
#define NAU8810_PGAGAIN_SFT 0
|
||||
@ -236,12 +240,15 @@
|
||||
#define NAU8810_PGAZC_SFT 7
|
||||
|
||||
/* NAU8810_REG_ADCBOOST (0x2F) */
|
||||
#define NAU8810_AUXBSTGAIN_SFT 0
|
||||
#define NAU8810_PMICBSTGAIN_SFT 4
|
||||
#define NAU8810_PMICBSTGAIN_MASK (0x7 << NAU8810_PMICBSTGAIN_SFT)
|
||||
#define NAU8810_PGABST_SFT 8
|
||||
|
||||
/* NAU8810_REG_SPKMIX (0x32) */
|
||||
#define NAU8810_DACSPK_SFT 0
|
||||
#define NAU8810_BYPSPK_SFT 1
|
||||
#define NAU8810_AUXSPK_SFT 5
|
||||
|
||||
/* NAU8810_REG_SPKGAIN (0x36) */
|
||||
#define NAU8810_SPKGAIN_SFT 0
|
||||
@ -251,6 +258,7 @@
|
||||
/* NAU8810_REG_MONOMIX (0x38) */
|
||||
#define NAU8810_DACMOUT_SFT 0
|
||||
#define NAU8810_BYPMOUT_SFT 1
|
||||
#define NAU8810_AUXMOUT_SFT 2
|
||||
#define NAU8810_MOUTMXMT_SFT 6
|
||||
|
||||
|
||||
|
@ -97,12 +97,13 @@ struct pll_calc_map {
|
||||
int n;
|
||||
int m;
|
||||
bool m_bp;
|
||||
bool k_bp;
|
||||
};
|
||||
|
||||
static const struct pll_calc_map pll_preset_table[] = {
|
||||
{19200000, 4096000, 23, 14, 1, false},
|
||||
{19200000, 24576000, 3, 30, 3, false},
|
||||
{3840000, 24576000, 3, 30, 0, true},
|
||||
{19200000, 4096000, 23, 14, 1, false, false},
|
||||
{19200000, 24576000, 3, 30, 3, false, false},
|
||||
{3840000, 24576000, 3, 30, 0, true, false},
|
||||
};
|
||||
|
||||
static unsigned int find_best_div(unsigned int in,
|
||||
@ -128,7 +129,7 @@ static unsigned int find_best_div(unsigned int in,
|
||||
* rl6231_pll_calc - Calcualte PLL M/N/K code.
|
||||
* @freq_in: external clock provided to codec.
|
||||
* @freq_out: target clock which codec works on.
|
||||
* @pll_code: Pointer to structure with M, N, K and bypass flag.
|
||||
* @pll_code: Pointer to structure with M, N, K, m_bypass and k_bypass flag.
|
||||
*
|
||||
* Calcualte M/N/K code to configure PLL for codec.
|
||||
*
|
||||
@ -143,7 +144,7 @@ int rl6231_pll_calc(const unsigned int freq_in,
|
||||
unsigned int red, pll_out, in_t, out_t, div, div_t;
|
||||
unsigned int red_t = abs(freq_out - freq_in);
|
||||
unsigned int f_in, f_out, f_max;
|
||||
bool bypass = false;
|
||||
bool m_bypass = false, k_bypass = false;
|
||||
|
||||
if (RL6231_PLL_INP_MAX < freq_in || RL6231_PLL_INP_MIN > freq_in)
|
||||
return -EINVAL;
|
||||
@ -154,7 +155,8 @@ int rl6231_pll_calc(const unsigned int freq_in,
|
||||
k = pll_preset_table[i].k;
|
||||
m = pll_preset_table[i].m;
|
||||
n = pll_preset_table[i].n;
|
||||
bypass = pll_preset_table[i].m_bp;
|
||||
m_bypass = pll_preset_table[i].m_bp;
|
||||
k_bypass = pll_preset_table[i].k_bp;
|
||||
pr_debug("Use preset PLL parameter table\n");
|
||||
goto code_find;
|
||||
}
|
||||
@ -172,12 +174,14 @@ int rl6231_pll_calc(const unsigned int freq_in,
|
||||
f_in = freq_in / div;
|
||||
f_out = freq_out / div;
|
||||
k = min_k;
|
||||
if (min_k < -1)
|
||||
min_k = -1;
|
||||
for (k_t = min_k; k_t <= max_k; k_t++) {
|
||||
for (n_t = 0; n_t <= max_n; n_t++) {
|
||||
in_t = f_in * (n_t + 2);
|
||||
pll_out = f_out * (k_t + 2);
|
||||
if (in_t == pll_out) {
|
||||
bypass = true;
|
||||
m_bypass = true;
|
||||
n = n_t;
|
||||
k = k_t;
|
||||
goto code_find;
|
||||
@ -185,7 +189,7 @@ int rl6231_pll_calc(const unsigned int freq_in,
|
||||
out_t = in_t / (k_t + 2);
|
||||
red = abs(f_out - out_t);
|
||||
if (red < red_t) {
|
||||
bypass = true;
|
||||
m_bypass = true;
|
||||
n = n_t;
|
||||
m = 0;
|
||||
k = k_t;
|
||||
@ -197,7 +201,7 @@ int rl6231_pll_calc(const unsigned int freq_in,
|
||||
out_t = in_t / ((m_t + 2) * (k_t + 2));
|
||||
red = abs(f_out - out_t);
|
||||
if (red < red_t) {
|
||||
bypass = false;
|
||||
m_bypass = false;
|
||||
n = n_t;
|
||||
m = m_t;
|
||||
k = k_t;
|
||||
@ -211,8 +215,13 @@ int rl6231_pll_calc(const unsigned int freq_in,
|
||||
pr_debug("Only get approximation about PLL\n");
|
||||
|
||||
code_find:
|
||||
if (k == -1) {
|
||||
k_bypass = true;
|
||||
k = 0;
|
||||
}
|
||||
|
||||
pll_code->m_bp = bypass;
|
||||
pll_code->m_bp = m_bypass;
|
||||
pll_code->k_bp = k_bypass;
|
||||
pll_code->m_code = m;
|
||||
pll_code->n_code = n;
|
||||
pll_code->k_code = k;
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
struct rl6231_pll_code {
|
||||
bool m_bp; /* Indicates bypass m code or not. */
|
||||
bool k_bp; /* Indicates bypass k code or not. */
|
||||
int m_code;
|
||||
int n_code;
|
||||
int k_code;
|
||||
|
@ -475,7 +475,7 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,
|
||||
snd_soc_component_write(component,
|
||||
RT1015_CLSD_INTERNAL9, 0x0140);
|
||||
snd_soc_component_write(component,
|
||||
RT1015_GAT_BOOST, 0x00fe);
|
||||
RT1015_GAT_BOOST, 0x0efe);
|
||||
snd_soc_component_write(component,
|
||||
RT1015_PWR_STATE_CTRL, 0x000d);
|
||||
msleep(500);
|
||||
@ -780,6 +780,14 @@ static int rt1015_set_component_pll(struct snd_soc_component *component,
|
||||
freq_out == rt1015->pll_out)
|
||||
return 0;
|
||||
|
||||
if (source == RT1015_PLL_S_BCLK) {
|
||||
if (rt1015->bclk_ratio == 0) {
|
||||
dev_err(component->dev,
|
||||
"Can not support bclk ratio as 0.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (source) {
|
||||
case RT1015_PLL_S_MCLK:
|
||||
snd_soc_component_update_bits(component, RT1015_CLK2,
|
||||
@ -819,12 +827,30 @@ static int rt1015_set_component_pll(struct snd_soc_component *component,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt1015_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
dev_dbg(component->dev, "%s ratio=%d\n", __func__, ratio);
|
||||
|
||||
rt1015->bclk_ratio = ratio;
|
||||
|
||||
if (ratio == 50) {
|
||||
dev_dbg(component->dev, "Unsupport bclk ratio\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt1015_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct rt1015_priv *rt1015 =
|
||||
snd_soc_component_get_drvdata(component);
|
||||
|
||||
rt1015->component = component;
|
||||
rt1015->bclk_ratio = 0;
|
||||
snd_soc_component_write(component, RT1015_BAT_RPO_STEP1, 0x061c);
|
||||
|
||||
return 0;
|
||||
@ -844,6 +870,7 @@ static void rt1015_remove(struct snd_soc_component *component)
|
||||
static struct snd_soc_dai_ops rt1015_aif_dai_ops = {
|
||||
.hw_params = rt1015_hw_params,
|
||||
.set_fmt = rt1015_set_dai_fmt,
|
||||
.set_bclk_ratio = rt1015_set_bclk_ratio,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver rt1015_dai[] = {
|
||||
|
@ -362,6 +362,7 @@ struct rt1015_priv {
|
||||
int sysclk_src;
|
||||
int lrck;
|
||||
int bclk;
|
||||
int bclk_ratio;
|
||||
int id;
|
||||
int pll_src;
|
||||
int pll_in;
|
||||
|
695
sound/soc/codecs/rt1016.c
Normal file
695
sound/soc/codecs/rt1016.c
Normal 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
232
sound/soc/codecs/rt1016.h
Normal 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__ */
|
@ -178,10 +178,6 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
if (rt1308->hw_init)
|
||||
return 0;
|
||||
|
||||
ret = rt1308_read_prop(slave);
|
||||
if (ret < 0)
|
||||
goto _io_init_err_;
|
||||
|
||||
if (rt1308->first_hw_init) {
|
||||
regcache_cache_only(rt1308->regmap, false);
|
||||
regcache_cache_bypass(rt1308->regmap, true);
|
||||
@ -235,9 +231,9 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
efuse_c_btl_r = tmp;
|
||||
regmap_read(rt1308->regmap, 0xc872, &tmp);
|
||||
efuse_c_btl_r = efuse_c_btl_r | (tmp << 8);
|
||||
dev_info(&slave->dev, "%s m_btl_l=0x%x, m_btl_r=0x%x\n", __func__,
|
||||
dev_dbg(&slave->dev, "%s m_btl_l=0x%x, m_btl_r=0x%x\n", __func__,
|
||||
efuse_m_btl_l, efuse_m_btl_r);
|
||||
dev_info(&slave->dev, "%s c_btl_l=0x%x, c_btl_r=0x%x\n", __func__,
|
||||
dev_dbg(&slave->dev, "%s c_btl_l=0x%x, c_btl_r=0x%x\n", __func__,
|
||||
efuse_c_btl_l, efuse_c_btl_r);
|
||||
|
||||
/* initial settings */
|
||||
@ -282,7 +278,6 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
|
||||
dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);
|
||||
|
||||
_io_init_err_:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -482,6 +477,9 @@ static int rt1308_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
|
||||
{
|
||||
struct sdw_stream_data *stream;
|
||||
|
||||
if (!sdw_stream)
|
||||
return 0;
|
||||
|
||||
stream = kzalloc(sizeof(*stream), GFP_KERNEL);
|
||||
if (!stream)
|
||||
return -ENOMEM;
|
||||
@ -684,9 +682,6 @@ static int rt1308_sdw_probe(struct sdw_slave *slave,
|
||||
{
|
||||
struct regmap *regmap;
|
||||
|
||||
/* Assign ops */
|
||||
slave->ops = &rt1308_slave_ops;
|
||||
|
||||
/* Regmap Initialization */
|
||||
regmap = devm_regmap_init_sdw(slave, &rt1308_sdw_regmap);
|
||||
if (!regmap)
|
||||
|
@ -605,7 +605,8 @@ static int rt5677_spi_probe(struct spi_device *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_component,
|
||||
&rt5677_spi_dai, 1);
|
||||
if (ret < 0)
|
||||
dev_err(&spi->dev, "Failed to register component.\n");
|
||||
@ -613,12 +614,6 @@ static int rt5677_spi_probe(struct spi_device *spi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rt5677_spi_remove(struct spi_device *spi)
|
||||
{
|
||||
snd_soc_unregister_component(&spi->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id rt5677_spi_acpi_id[] = {
|
||||
{ "RT5677AA", 0 },
|
||||
{ }
|
||||
@ -631,7 +626,6 @@ static struct spi_driver rt5677_spi_driver = {
|
||||
.acpi_match_table = ACPI_PTR(rt5677_spi_acpi_id),
|
||||
},
|
||||
.probe = rt5677_spi_probe,
|
||||
.remove = rt5677_spi_remove,
|
||||
};
|
||||
module_spi_driver(rt5677_spi_driver);
|
||||
|
||||
|
306
sound/soc/codecs/rt5682-i2c.c
Normal file
306
sound/soc/codecs/rt5682-i2c.c
Normal 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
Loading…
Reference in New Issue
Block a user