Merge branch 'asoc-5.3' into asoc-next
This commit is contained in:
commit
043b35f281
312 changed files with 26362 additions and 4794 deletions
|
@ -11,7 +11,7 @@ Required properties:
|
|||
- clock-names: must contain "mclk", which is the DCMI peripherial clock
|
||||
- pinctrl: the pincontrol settings to configure muxing properly
|
||||
for pins that connect to DCMI device.
|
||||
See Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt.
|
||||
See Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml.
|
||||
- dmas: phandle to DMA controller node,
|
||||
see Documentation/devicetree/bindings/dma/stm32-dma.txt
|
||||
- dma-names: must contain "tx", which is the transmit channel from DCMI to DMA
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/allwinner,sun4i-a10-i2s.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A10 I2S Controller Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <maxime.ripard@bootlin.com>
|
||||
|
||||
properties:
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: allwinner,sun4i-a10-i2s
|
||||
- const: allwinner,sun6i-a31-i2s
|
||||
- const: allwinner,sun8i-a83t-i2s
|
||||
- const: allwinner,sun8i-h3-i2s
|
||||
- const: allwinner,sun50i-a64-codec-i2s
|
||||
- items:
|
||||
- const: allwinner,sun50i-a64-i2s
|
||||
- const: allwinner,sun8i-h3-i2s
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Bus Clock
|
||||
- description: Module Clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: apb
|
||||
- const: mod
|
||||
|
||||
# Even though it only applies to subschemas under the conditionals,
|
||||
# not listing them here will trigger a warning because of the
|
||||
# additionalsProperties set to false.
|
||||
dmas: true
|
||||
dma-names: true
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun6i-a31-i2s
|
||||
- allwinner,sun8i-a83t-i2s
|
||||
- allwinner,sun8i-h3-i2s
|
||||
- allwinner,sun50i-a64-codec-i2s
|
||||
|
||||
then:
|
||||
required:
|
||||
- resets
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: allwinner,sun8i-a83t-i2s
|
||||
|
||||
then:
|
||||
properties:
|
||||
dmas:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
- description: RX DMA Channel
|
||||
- description: TX DMA Channel
|
||||
description:
|
||||
Some controllers cannot receive but can only transmit
|
||||
data. In such a case, the RX DMA channel is to be omitted.
|
||||
|
||||
dma-names:
|
||||
oneOf:
|
||||
- items:
|
||||
- const: rx
|
||||
- const: tx
|
||||
- const: tx
|
||||
description:
|
||||
Some controllers cannot receive but can only transmit
|
||||
data. In such a case, the RX name is to be omitted.
|
||||
|
||||
else:
|
||||
properties:
|
||||
dmas:
|
||||
items:
|
||||
- description: RX DMA Channel
|
||||
- description: TX DMA Channel
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: rx
|
||||
- const: tx
|
||||
|
||||
required:
|
||||
- "#sound-dai-cells"
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- dmas
|
||||
- dma-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2s0: i2s@1c22400 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun4i-a10-i2s";
|
||||
reg = <0x01c22400 0x400>;
|
||||
interrupts = <0 16 4>;
|
||||
clocks = <&apb0_gates 3>, <&i2s0_clk>;
|
||||
clock-names = "apb", "mod";
|
||||
dmas = <&dma 0 3>, <&dma 0 3>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
||||
|
||||
...
|
|
@ -0,0 +1,120 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/allwinner,sun4i-a10-spdif.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A10 S/PDIF Controller Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Liam Girdwood <lgirdwood@gmail.com>
|
||||
- Mark Brown <broonie@kernel.org>
|
||||
- Maxime Ripard <maxime.ripard@bootlin.com>
|
||||
|
||||
properties:
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: allwinner,sun4i-a10-spdif
|
||||
- const: allwinner,sun6i-a31-spdif
|
||||
- const: allwinner,sun8i-h3-spdif
|
||||
- const: allwinner,sun50i-h6-spdif
|
||||
- items:
|
||||
- const: allwinner,sun8i-a83t-spdif
|
||||
- const: allwinner,sun8i-h3-spdif
|
||||
- items:
|
||||
- const: allwinner,sun50i-a64-spdif
|
||||
- const: allwinner,sun8i-h3-spdif
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Bus Clock
|
||||
- description: Module Clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: apb
|
||||
- const: spdif
|
||||
|
||||
# Even though it only applies to subschemas under the conditionals,
|
||||
# not listing them here will trigger a warning because of the
|
||||
# additionalsProperties set to false.
|
||||
dmas: true
|
||||
dma-names: true
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun6i-a31-spdif
|
||||
- allwinner,sun8i-h3-spdif
|
||||
|
||||
then:
|
||||
required:
|
||||
- resets
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: allwinner,sun8i-h3-spdif
|
||||
|
||||
then:
|
||||
properties:
|
||||
dmas:
|
||||
description: TX DMA Channel
|
||||
|
||||
dma-names:
|
||||
const: tx
|
||||
|
||||
else:
|
||||
properties:
|
||||
dmas:
|
||||
items:
|
||||
- description: RX DMA Channel
|
||||
- description: TX DMA Channel
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: rx
|
||||
- const: tx
|
||||
|
||||
required:
|
||||
- "#sound-dai-cells"
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- dmas
|
||||
- dma-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
spdif: spdif@1c21000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun4i-a10-spdif";
|
||||
reg = <0x01c21000 0x40>;
|
||||
interrupts = <13>;
|
||||
clocks = <&apb0_gates 1>, <&spdif_clk>;
|
||||
clock-names = "apb", "spdif";
|
||||
dmas = <&dma 0 2>, <&dma 0 2>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
||||
|
||||
...
|
|
@ -15,11 +15,15 @@ Required properties:
|
|||
* "lrclk" : sample clock
|
||||
* "lrclk_sel": sample clock input multiplexer
|
||||
|
||||
Example of TDMOUT_A on the A113 SoC:
|
||||
Optional property:
|
||||
- resets: phandle to the dedicated reset line of the tdm formatter.
|
||||
|
||||
Example of TDMOUT_A on the S905X2 SoC:
|
||||
|
||||
tdmout_a: audio-controller@500 {
|
||||
compatible = "amlogic,axg-tdmout";
|
||||
reg = <0x0 0x500 0x0 0x40>;
|
||||
resets = <&clkc_audio AUD_RESET_TDMOUT_A>;
|
||||
clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
|
||||
<&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
|
||||
<&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
* Amlogic HDMI Tx control glue
|
||||
|
||||
Required properties:
|
||||
- compatible: "amlogic,g12a-tohdmitx"
|
||||
- reg: physical base address of the controller and length of memory
|
||||
mapped region.
|
||||
- #sound-dai-cells: should be 1.
|
||||
|
||||
Example on the S905X2 SoC:
|
||||
|
||||
tohdmitx: audio-controller@744 {
|
||||
compatible = "amlogic,g12a-tohdmitx";
|
||||
reg = <0x0 0x744 0x0 0x4>;
|
||||
#sound-dai-cells = <1>;
|
||||
};
|
||||
|
||||
Example of an 'amlogic,axg-sound-card':
|
||||
|
||||
sound {
|
||||
compatible = "amlogic,axg-sound-card";
|
||||
|
||||
[...]
|
||||
|
||||
dai-link-x {
|
||||
sound-dai = <&tdmif_a>;
|
||||
dai-format = "i2s";
|
||||
dai-tdm-slot-tx-mask-0 = <1 1>;
|
||||
|
||||
codec-0 {
|
||||
sound-dai = <&tohdmitx TOHDMITX_I2S_IN_A>;
|
||||
};
|
||||
|
||||
codec-1 {
|
||||
sound-dai = <&external_dac>;
|
||||
};
|
||||
};
|
||||
|
||||
dai-link-y {
|
||||
sound-dai = <&tdmif_c>;
|
||||
dai-format = "i2s";
|
||||
dai-tdm-slot-tx-mask-0 = <1 1>;
|
||||
|
||||
codec {
|
||||
sound-dai = <&tohdmitx TOHDMITX_I2S_IN_C>;
|
||||
};
|
||||
};
|
||||
|
||||
dai-link-z {
|
||||
sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
|
||||
|
||||
codec {
|
||||
sound-dai = <&hdmi_tx>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -14,6 +14,11 @@ Required properties:
|
|||
- VA-supply, VD-supply, VLS-supply, VLC-supply: power supplies for the device,
|
||||
as covered in Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
|
||||
Optional properties:
|
||||
|
||||
- reset-gpios : a GPIO spec to define which pin is connected to the chip's
|
||||
!RESET pin
|
||||
|
||||
Example:
|
||||
|
||||
cs42888: codec@48 {
|
||||
|
@ -25,4 +30,5 @@ cs42888: codec@48 {
|
|||
VD-supply = <®_audio>;
|
||||
VLS-supply = <®_audio>;
|
||||
VLC-supply = <®_audio>;
|
||||
reset-gpios = <&pca9557_b 1 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
|
|
@ -44,6 +44,9 @@ Optional properties:
|
|||
please refer to pinctrl-bindings.txt
|
||||
- fck_parent : Should contain a valid clock name which will be used as parent
|
||||
for the McASP fck
|
||||
- auxclk-fs-ratio: When McASP is bus master indicates the ratio between AUCLK
|
||||
and FS rate if applicable:
|
||||
AUCLK rate = auxclk-fs-ratio * FS rate
|
||||
|
||||
Optional GPIO support:
|
||||
If any McASP pin need to be used as GPIO then the McASP node must have:
|
||||
|
|
67
Documentation/devicetree/bindings/sound/madera.txt
Normal file
67
Documentation/devicetree/bindings/sound/madera.txt
Normal file
|
@ -0,0 +1,67 @@
|
|||
Cirrus Logic Madera class audio codecs
|
||||
|
||||
This describes audio configuration bindings for these codecs.
|
||||
|
||||
See also the core bindings for the parent MFD driver:
|
||||
See Documentation/devicetree/bindings/mfd/madera.txt
|
||||
|
||||
and defines for values used in these bindings:
|
||||
include/dt-bindings/sound/madera.h
|
||||
|
||||
These properties are all contained in the parent MFD node.
|
||||
|
||||
Optional properties:
|
||||
- cirrus,dmic-ref : Indicates how the MICBIAS pins have been externally
|
||||
connected to DMICs on each input, one cell per input.
|
||||
<IN1 IN2 IN3 ...>
|
||||
A value of 0 indicates MICVDD and is the default, other values depend on the
|
||||
codec:
|
||||
For CS47L35 one of the CS47L35_DMIC_REF_xxx values
|
||||
For all other codecs one of the MADERA_DMIC_REF_xxx values
|
||||
Also see the datasheet for a description of the INn_DMIC_SUP field.
|
||||
|
||||
- cirrus,inmode : A list of input mode settings for each input. A maximum of
|
||||
16 cells, with four cells per input in the order INnAL, INnAR INnBL INnBR.
|
||||
For non-muxed inputs the first two cells for that input set the mode for
|
||||
the left and right channel and the second two cells must be 0.
|
||||
For muxed inputs the first two cells for that input set the mode of the
|
||||
left and right A inputs and the second two cells set the mode of the left
|
||||
and right B inputs.
|
||||
Valid mode values are one of the MADERA_INMODE_xxx. If the array is shorter
|
||||
than the number of inputs the unspecified inputs default to
|
||||
MADERA_INMODE_DIFF.
|
||||
|
||||
- cirrus,out-mono : Mono bit for each output, maximum of six cells if the
|
||||
array is shorter outputs will be set to stereo.
|
||||
|
||||
- cirrus,max-channels-clocked : Maximum number of channels that I2S clocks
|
||||
will be generated for. Useful when clock master for systems where the I2S
|
||||
bus has multiple data lines.
|
||||
One cell for each AIF, use a value of zero for AIFs that should be handled
|
||||
normally.
|
||||
|
||||
- cirrus,pdm-fmt : PDM speaker data format, must contain 2 cells
|
||||
(OUT5 and OUT6). See the PDM_SPKn_FMT field in the datasheet for a
|
||||
description of this value.
|
||||
The second cell is ignored for codecs that do not have OUT6.
|
||||
|
||||
- cirrus,pdm-mute : PDM mute format, must contain 2 cells
|
||||
(OUT5 and OUT6). See the PDM_SPKn_CTRL_1 register in the datasheet for a
|
||||
description of this value.
|
||||
The second cell is ignored for codecs that do not have OUT6.
|
||||
|
||||
Example:
|
||||
|
||||
cs47l35@0 {
|
||||
compatible = "cirrus,cs47l35";
|
||||
|
||||
cirrus,dmic-ref = <0 0 CS47L35_DMIC_REF_MICBIAS1B 0>;
|
||||
cirrus,inmode = <
|
||||
MADERA_INMODE_DMIC MADERA_INMODE_DMIC /* IN1A digital */
|
||||
MADERA_INMODE_SE MADERA_INMODE_SE /* IN1B single-ended */
|
||||
MADERA_INMODE_DIFF MADERA_INMODE_DIFF /* IN2 differential */
|
||||
0 0 /* not used on this codec */
|
||||
>;
|
||||
cirrus,out-mono = <0 0 0 0 0 0>;
|
||||
cirrus,max-channels-clocked = <2 0 0>;
|
||||
};
|
|
@ -9,6 +9,10 @@ Optional properties:
|
|||
- sdmode-gpios : GPIO specifier for the chip's SD_MODE pin.
|
||||
If this option is not specified then driver does not manage
|
||||
the pin state (e.g. chip is always on).
|
||||
- sdmode-delay : specify delay time for SD_MODE pin.
|
||||
If this option is specified, which means it's required i2s clocks
|
||||
ready before SD_MODE is unmuted in order to avoid the speaker pop noise.
|
||||
It's observed that 5ms is sufficient.
|
||||
|
||||
Example:
|
||||
|
||||
|
|
32
Documentation/devicetree/bindings/sound/rt1011.txt
Normal file
32
Documentation/devicetree/bindings/sound/rt1011.txt
Normal file
|
@ -0,0 +1,32 @@
|
|||
RT1011 Mono Class D Audio Amplifier
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "realtek,rt1011".
|
||||
|
||||
- reg : The I2C address of the device. This I2C address decide by
|
||||
two input pins (ASEL1 and ASEL2).
|
||||
-------------------------------------
|
||||
| ASEL2 | ASEL1 | Address |
|
||||
-------------------------------------
|
||||
| 0 | 0 | 0x38 |
|
||||
-------------------------------------
|
||||
| 0 | 1 | 0x39 |
|
||||
-------------------------------------
|
||||
| 1 | 0 | 0x3a |
|
||||
-------------------------------------
|
||||
| 1 | 1 | 0x3b |
|
||||
-------------------------------------
|
||||
|
||||
Pins on the device (for linking into audio routes) for RT1011:
|
||||
|
||||
* SPO
|
||||
|
||||
Example:
|
||||
|
||||
rt1011: codec@38 {
|
||||
compatible = "realtek,rt1011";
|
||||
reg = <0x38>;
|
||||
};
|
17
Documentation/devicetree/bindings/sound/rt1308.txt
Executable file
17
Documentation/devicetree/bindings/sound/rt1308.txt
Executable file
|
@ -0,0 +1,17 @@
|
|||
RT1308 audio Amplifier
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "realtek,rt1308".
|
||||
|
||||
- reg : The I2C address of the device.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
rt1308: rt1308@10 {
|
||||
compatible = "realtek,rt1308";
|
||||
reg = <0x10>;
|
||||
};
|
|
@ -18,7 +18,7 @@ Required properties:
|
|||
See Documentation/devicetree/bindings/dma/stm32-dma.txt.
|
||||
- dma-names: Identifier for each DMA request line. Must be "tx" and "rx".
|
||||
- pinctrl-names: should contain only value "default"
|
||||
- pinctrl-0: see Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt
|
||||
- pinctrl-0: see Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml
|
||||
|
||||
Optional properties:
|
||||
- resets: Reference to a reset controller asserting the reset controller
|
||||
|
|
|
@ -41,7 +41,7 @@ SAI subnodes required properties:
|
|||
"tx": if sai sub-block is configured as playback DAI
|
||||
"rx": if sai sub-block is configured as capture DAI
|
||||
- pinctrl-names: should contain only value "default"
|
||||
- pinctrl-0: see Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt
|
||||
- pinctrl-0: see Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml
|
||||
|
||||
SAI subnodes Optional properties:
|
||||
- st,sync: specify synchronization mode.
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
* Allwinner A10 I2S controller
|
||||
|
||||
The I2S bus (Inter-IC sound bus) is a serial link for digital
|
||||
audio data transfer between devices in the system.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: should be one of the following:
|
||||
- "allwinner,sun4i-a10-i2s"
|
||||
- "allwinner,sun6i-a31-i2s"
|
||||
- "allwinner,sun8i-a83t-i2s"
|
||||
- "allwinner,sun8i-h3-i2s"
|
||||
- "allwinner,sun50i-a64-codec-i2s"
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
- interrupts: should contain the I2S interrupt.
|
||||
- dmas: DMA specifiers for tx and rx dma. See the DMA client binding,
|
||||
Documentation/devicetree/bindings/dma/dma.txt
|
||||
- dma-names: should include "tx" and "rx".
|
||||
- clocks: a list of phandle + clock-specifer pairs, one for each entry in clock-names.
|
||||
- clock-names: should contain the following:
|
||||
- "apb" : clock for the I2S bus interface
|
||||
- "mod" : module clock for the I2S controller
|
||||
- #sound-dai-cells : Must be equal to 0
|
||||
|
||||
Required properties for the following compatibles:
|
||||
- "allwinner,sun6i-a31-i2s"
|
||||
- "allwinner,sun8i-a83t-i2s"
|
||||
- "allwinner,sun8i-h3-i2s"
|
||||
- "allwinner,sun50i-a64-codec-i2s"
|
||||
- resets: phandle to the reset line for this codec
|
||||
|
||||
Example:
|
||||
|
||||
i2s0: i2s@1c22400 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun4i-a10-i2s";
|
||||
reg = <0x01c22400 0x400>;
|
||||
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&apb0_gates 3>, <&i2s0_clk>;
|
||||
clock-names = "apb", "mod";
|
||||
dmas = <&dma SUN4I_DMA_NORMAL 3>,
|
||||
<&dma SUN4I_DMA_NORMAL 3>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
|
@ -1,42 +0,0 @@
|
|||
Allwinner Sony/Philips Digital Interface Format (S/PDIF) Controller
|
||||
|
||||
The Allwinner S/PDIF audio block is a transceiver that allows the
|
||||
processor to receive and transmit digital audio via an coaxial cable or
|
||||
a fibre cable.
|
||||
For now only playback is supported.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be one of the following:
|
||||
- "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC
|
||||
- "allwinner,sun6i-a31-spdif": for the Allwinner A31 SoC
|
||||
- "allwinner,sun8i-h3-spdif": for the Allwinner H3 SoC
|
||||
|
||||
- reg : Offset and length of the register set for the device.
|
||||
|
||||
- interrupts : Contains the spdif interrupt.
|
||||
|
||||
- dmas : Generic dma devicetree binding as described in
|
||||
Documentation/devicetree/bindings/dma/dma.txt.
|
||||
|
||||
- dma-names : Two dmas have to be defined, "tx" and "rx".
|
||||
|
||||
- clocks : Contains an entry for each entry in clock-names.
|
||||
|
||||
- clock-names : Includes the following entries:
|
||||
"apb" clock for the spdif bus.
|
||||
"spdif" clock for spdif controller.
|
||||
|
||||
- resets : reset specifier for the ahb reset (A31 and newer only)
|
||||
|
||||
Example:
|
||||
|
||||
spdif: spdif@1c21000 {
|
||||
compatible = "allwinner,sun4i-a10-spdif";
|
||||
reg = <0x01c21000 0x40>;
|
||||
interrupts = <13>;
|
||||
clocks = <&apb0_gates 1>, <&spdif_clk>;
|
||||
clock-names = "apb", "spdif";
|
||||
dmas = <&dma 0 2>, <&dma 0 2>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
|
@ -1290,7 +1290,7 @@ ARM PRIMECELL SSP PL022 SPI DRIVER
|
|||
M: Linus Walleij <linus.walleij@linaro.org>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/spi/spi_pl022.txt
|
||||
F: Documentation/devicetree/bindings/spi/spi-pl022.yaml
|
||||
F: drivers/spi/spi-pl022.c
|
||||
|
||||
ARM PRIMECELL UART PL010 AND PL011 DRIVERS
|
||||
|
@ -3929,13 +3929,18 @@ W: https://github.com/CirrusLogic/linux-drivers/wiki
|
|||
S: Supported
|
||||
F: Documentation/devicetree/bindings/mfd/madera.txt
|
||||
F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
|
||||
F: Documentation/devicetree/bindings/sound/madera.txt
|
||||
F: include/dt-bindings/sound/madera*
|
||||
F: include/linux/irqchip/irq-madera*
|
||||
F: include/linux/mfd/madera/*
|
||||
F: include/sound/madera*
|
||||
F: drivers/gpio/gpio-madera*
|
||||
F: drivers/irqchip/irq-madera*
|
||||
F: drivers/mfd/madera*
|
||||
F: drivers/mfd/cs47l*
|
||||
F: drivers/pinctrl/cirrus/*
|
||||
F: sound/soc/codecs/cs47l*
|
||||
F: sound/soc/codecs/madera*
|
||||
|
||||
CLANG-FORMAT FILE
|
||||
M: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
struct vc4_hdmi_audio {
|
||||
struct snd_soc_card card;
|
||||
struct snd_soc_dai_link link;
|
||||
struct snd_soc_dai_link_component cpu;
|
||||
struct snd_soc_dai_link_component codec;
|
||||
struct snd_soc_dai_link_component platform;
|
||||
int samplerate;
|
||||
int channels;
|
||||
struct snd_dmaengine_dai_dma_data dma_data;
|
||||
|
@ -1085,12 +1088,20 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *hdmi)
|
|||
return ret;
|
||||
}
|
||||
|
||||
dai_link->cpus = &hdmi->audio.cpu;
|
||||
dai_link->codecs = &hdmi->audio.codec;
|
||||
dai_link->platforms = &hdmi->audio.platform;
|
||||
|
||||
dai_link->num_cpus = 1;
|
||||
dai_link->num_codecs = 1;
|
||||
dai_link->num_platforms = 1;
|
||||
|
||||
dai_link->name = "MAI";
|
||||
dai_link->stream_name = "MAI PCM";
|
||||
dai_link->codec_dai_name = vc4_hdmi_audio_codec_dai_drv.name;
|
||||
dai_link->cpu_dai_name = dev_name(dev);
|
||||
dai_link->codec_name = dev_name(dev);
|
||||
dai_link->platform_name = dev_name(dev);
|
||||
dai_link->codecs->dai_name = vc4_hdmi_audio_codec_dai_drv.name;
|
||||
dai_link->cpus->dai_name = dev_name(dev);
|
||||
dai_link->codecs->name = dev_name(dev);
|
||||
dai_link->platforms->name = dev_name(dev);
|
||||
|
||||
card->dai_link = dai_link;
|
||||
card->num_links = 1;
|
||||
|
|
25
include/dt-bindings/sound/madera.h
Normal file
25
include/dt-bindings/sound/madera.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Device Tree defines for Madera codecs
|
||||
*
|
||||
* Copyright (C) 2016-2017 Cirrus Logic, Inc. and
|
||||
* Cirrus Logic International Semiconductor Ltd.
|
||||
*/
|
||||
|
||||
#ifndef DT_BINDINGS_SOUND_MADERA_H
|
||||
#define DT_BINDINGS_SOUND_MADERA_H
|
||||
|
||||
#define MADERA_INMODE_DIFF 0
|
||||
#define MADERA_INMODE_SE 1
|
||||
#define MADERA_INMODE_DMIC 2
|
||||
|
||||
#define MADERA_DMIC_REF_MICVDD 0
|
||||
#define MADERA_DMIC_REF_MICBIAS1 1
|
||||
#define MADERA_DMIC_REF_MICBIAS2 2
|
||||
#define MADERA_DMIC_REF_MICBIAS3 3
|
||||
|
||||
#define CS47L35_DMIC_REF_MICBIAS1B 1
|
||||
#define CS47L35_DMIC_REF_MICBIAS2A 2
|
||||
#define CS47L35_DMIC_REF_MICBIAS2B 3
|
||||
|
||||
#endif
|
13
include/dt-bindings/sound/meson-g12a-tohdmitx.h
Normal file
13
include/dt-bindings/sound/meson-g12a-tohdmitx.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DT_MESON_G12A_TOHDMITX_H
|
||||
#define __DT_MESON_G12A_TOHDMITX_H
|
||||
|
||||
#define TOHDMITX_I2S_IN_A 0
|
||||
#define TOHDMITX_I2S_IN_B 1
|
||||
#define TOHDMITX_I2S_IN_C 2
|
||||
#define TOHDMITX_I2S_OUT 3
|
||||
#define TOHDMITX_SPDIF_IN_A 4
|
||||
#define TOHDMITX_SPDIF_IN_B 5
|
||||
#define TOHDMITX_SPDIF_OUT 6
|
||||
|
||||
#endif /* __DT_MESON_G12A_TOHDMITX_H */
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/regulator/arizona-ldo1.h>
|
||||
#include <linux/regulator/arizona-micsupp.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <sound/madera-pdata.h>
|
||||
|
||||
#define MADERA_MAX_MICBIAS 4
|
||||
#define MADERA_MAX_CHILD_MICBIAS 4
|
||||
|
@ -39,6 +40,7 @@ struct madera_codec_pdata;
|
|||
* @gpsw: General purpose switch mode setting. Depends on the external
|
||||
* hardware connected to the switch. (See the SW1_MODE field
|
||||
* in the datasheet for the available values for your codec)
|
||||
* @codec: Substruct of pdata for the ASoC codec driver
|
||||
*/
|
||||
struct madera_pdata {
|
||||
struct gpio_desc *reset;
|
||||
|
@ -53,6 +55,8 @@ struct madera_pdata {
|
|||
int n_gpio_configs;
|
||||
|
||||
u32 gpsw[MADERA_MAX_GPSW];
|
||||
|
||||
struct madera_codec_pdata codec;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
#include <sound/hda_verbs.h>
|
||||
#include <sound/hda_regmap.h>
|
||||
|
||||
#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
|
||||
#define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348)
|
||||
|
||||
/*
|
||||
* Structures
|
||||
*/
|
||||
|
|
59
include/sound/madera-pdata.h
Normal file
59
include/sound/madera-pdata.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Platform data for Madera codec driver
|
||||
*
|
||||
* Copyright (C) 2016-2019 Cirrus Logic, Inc. and
|
||||
* Cirrus Logic International Semiconductor Ltd.
|
||||
*/
|
||||
|
||||
#ifndef MADERA_CODEC_PDATA_H
|
||||
#define MADERA_CODEC_PDATA_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#define MADERA_MAX_INPUT 6
|
||||
#define MADERA_MAX_MUXED_CHANNELS 4
|
||||
#define MADERA_MAX_OUTPUT 6
|
||||
#define MADERA_MAX_AIF 4
|
||||
#define MADERA_MAX_PDM_SPK 2
|
||||
#define MADERA_MAX_DSP 7
|
||||
|
||||
/**
|
||||
* struct madera_codec_pdata
|
||||
*
|
||||
* @max_channels_clocked: Maximum number of channels that I2S clocks will be
|
||||
* generated for. Useful when clock master for systems
|
||||
* where the I2S bus has multiple data lines.
|
||||
* @dmic_ref: Indicates how the MICBIAS pins have been externally
|
||||
* connected to DMICs on each input. A value of 0
|
||||
* indicates MICVDD and is the default. Other values are:
|
||||
* For CS47L35 one of the CS47L35_DMIC_REF_xxx values
|
||||
* For all other codecs one of the MADERA_DMIC_REF_xxx
|
||||
* Also see the datasheet for a description of the
|
||||
* INn_DMIC_SUP field.
|
||||
* @inmode: Mode for the ADC inputs. One of the MADERA_INMODE_xxx
|
||||
* values. Two-dimensional array
|
||||
* [input_number][channel number], with four slots per
|
||||
* input in the order
|
||||
* [n][0]=INnAL [n][1]=INnAR [n][2]=INnBL [n][3]=INnBR
|
||||
* @out_mono: For each output set the value to TRUE to indicate that
|
||||
* the output is mono. [0]=OUT1, [1]=OUT2, ...
|
||||
* @pdm_fmt: PDM speaker data format. See the PDM_SPKn_FMT field in
|
||||
* the datasheet for a description of this value.
|
||||
* @pdm_mute: PDM mute format. See the PDM_SPKn_CTRL_1 register
|
||||
* in the datasheet for a description of this value.
|
||||
*/
|
||||
struct madera_codec_pdata {
|
||||
u32 max_channels_clocked[MADERA_MAX_AIF];
|
||||
|
||||
u32 dmic_ref[MADERA_MAX_INPUT];
|
||||
|
||||
u32 inmode[MADERA_MAX_INPUT][MADERA_MAX_MUXED_CHANNELS];
|
||||
|
||||
bool out_mono[MADERA_MAX_OUTPUT];
|
||||
|
||||
u32 pdm_fmt[MADERA_MAX_PDM_SPK];
|
||||
u32 pdm_mute[MADERA_MAX_PDM_SPK];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -42,6 +42,7 @@ struct asoc_simple_priv {
|
|||
struct simple_dai_props {
|
||||
struct asoc_simple_dai *cpu_dai;
|
||||
struct asoc_simple_dai *codec_dai;
|
||||
struct snd_soc_dai_link_component cpus; /* single cpu */
|
||||
struct snd_soc_dai_link_component codecs; /* single codec */
|
||||
struct snd_soc_dai_link_component platforms;
|
||||
struct asoc_simple_data adata;
|
||||
|
@ -80,16 +81,12 @@ int asoc_simple_parse_card_name(struct snd_soc_card *card,
|
|||
char *prefix);
|
||||
|
||||
#define asoc_simple_parse_clk_cpu(dev, node, dai_link, simple_dai) \
|
||||
asoc_simple_parse_clk(dev, node, dai_link->cpu_of_node, simple_dai, \
|
||||
dai_link->cpu_dai_name, NULL)
|
||||
asoc_simple_parse_clk(dev, node, simple_dai, dai_link->cpus)
|
||||
#define asoc_simple_parse_clk_codec(dev, node, dai_link, simple_dai) \
|
||||
asoc_simple_parse_clk(dev, node, dai_link->codec_of_node, simple_dai,\
|
||||
dai_link->codec_dai_name, dai_link->codecs)
|
||||
asoc_simple_parse_clk(dev, node, simple_dai, dai_link->codecs)
|
||||
int asoc_simple_parse_clk(struct device *dev,
|
||||
struct device_node *node,
|
||||
struct device_node *dai_of_node,
|
||||
struct asoc_simple_dai *simple_dai,
|
||||
const char *dai_name,
|
||||
struct snd_soc_dai_link_component *dlc);
|
||||
int asoc_simple_startup(struct snd_pcm_substream *substream);
|
||||
void asoc_simple_shutdown(struct snd_pcm_substream *substream);
|
||||
|
@ -100,16 +97,11 @@ int asoc_simple_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
|||
struct snd_pcm_hw_params *params);
|
||||
|
||||
#define asoc_simple_parse_cpu(node, dai_link, is_single_link) \
|
||||
asoc_simple_parse_dai(node, NULL, \
|
||||
&dai_link->cpu_of_node, \
|
||||
&dai_link->cpu_dai_name, is_single_link)
|
||||
asoc_simple_parse_dai(node, dai_link->cpus, is_single_link)
|
||||
#define asoc_simple_parse_codec(node, dai_link) \
|
||||
asoc_simple_parse_dai(node, dai_link->codecs, \
|
||||
&dai_link->codec_of_node, \
|
||||
&dai_link->codec_dai_name, NULL)
|
||||
asoc_simple_parse_dai(node, dai_link->codecs, NULL)
|
||||
#define asoc_simple_parse_platform(node, dai_link) \
|
||||
asoc_simple_parse_dai(node, dai_link->platforms, \
|
||||
&dai_link->platform_of_node, NULL, NULL)
|
||||
asoc_simple_parse_dai(node, dai_link->platforms, NULL)
|
||||
|
||||
#define asoc_simple_parse_tdm(np, dai) \
|
||||
snd_soc_of_parse_tdm_slot(np, &(dai)->tx_slot_mask, \
|
||||
|
|
|
@ -900,17 +900,6 @@ struct snd_soc_dai_link {
|
|||
const char *name; /* Codec name */
|
||||
const char *stream_name; /* Stream name */
|
||||
|
||||
/*
|
||||
* cpu_name
|
||||
* cpu_of_node
|
||||
* cpu_dai_name
|
||||
*
|
||||
* These are legacy style, and will be replaced to
|
||||
* modern style (= snd_soc_dai_link_component) in the future,
|
||||
* but, not yet supported so far.
|
||||
* If modern style was supported for CPU, all driver will switch
|
||||
* to use it, and, legacy style code will be removed from ALSA SoC.
|
||||
*/
|
||||
/*
|
||||
* You MAY specify the link's CPU-side device, either by device name,
|
||||
* or by DT/OF node, but not both. If this information is omitted,
|
||||
|
@ -918,57 +907,27 @@ struct snd_soc_dai_link {
|
|||
* must be globally unique. These fields are currently typically used
|
||||
* only for codec to codec links, or systems using device tree.
|
||||
*/
|
||||
const char *cpu_name;
|
||||
struct device_node *cpu_of_node;
|
||||
/*
|
||||
* You MAY specify the DAI name of the CPU DAI. If this information is
|
||||
* omitted, the CPU-side DAI is matched using .cpu_name/.cpu_of_node
|
||||
* only, which only works well when that device exposes a single DAI.
|
||||
*/
|
||||
const char *cpu_dai_name;
|
||||
struct snd_soc_dai_link_component *cpus;
|
||||
unsigned int num_cpus;
|
||||
|
||||
/*
|
||||
* codec_name
|
||||
* codec_of_node
|
||||
* codec_dai_name
|
||||
*
|
||||
* These are legacy style, it will be converted to modern style
|
||||
* (= snd_soc_dai_link_component) automatically in soc-core
|
||||
* if driver is using legacy style.
|
||||
* Driver shouldn't use both legacy and modern style in the same time.
|
||||
* If modern style was supported for CPU, all driver will switch
|
||||
* to use it, and, legacy style code will be removed from ALSA SoC.
|
||||
*/
|
||||
/*
|
||||
* You MUST specify the link's codec, either by device name, or by
|
||||
* DT/OF node, but not both.
|
||||
*/
|
||||
const char *codec_name;
|
||||
struct device_node *codec_of_node;
|
||||
/* You MUST specify the DAI name within the codec */
|
||||
const char *codec_dai_name;
|
||||
|
||||
struct snd_soc_dai_link_component *codecs;
|
||||
unsigned int num_codecs;
|
||||
|
||||
/*
|
||||
* platform_name
|
||||
* platform_of_node
|
||||
*
|
||||
* These are legacy style, it will be converted to modern style
|
||||
* (= snd_soc_dai_link_component) automatically in soc-core
|
||||
* if driver is using legacy style.
|
||||
* Driver shouldn't use both legacy and modern style in the same time.
|
||||
* If modern style was supported for CPU, all driver will switch
|
||||
* to use it, and, legacy style code will be removed from ALSA SoC.
|
||||
*/
|
||||
/*
|
||||
* You MAY specify the link's platform/PCM/DMA driver, either by
|
||||
* device name, or by DT/OF node, but not both. Some forms of link
|
||||
* do not need a platform.
|
||||
* do not need a platform. In such case, platforms are not mandatory.
|
||||
*/
|
||||
const char *platform_name;
|
||||
struct device_node *platform_of_node;
|
||||
struct snd_soc_dai_link_component *platforms;
|
||||
unsigned int num_platforms;
|
||||
|
||||
|
@ -1030,12 +989,6 @@ struct snd_soc_dai_link {
|
|||
/* Do not create a PCM for this DAI link (Backend link) */
|
||||
unsigned int ignore:1;
|
||||
|
||||
/*
|
||||
* This driver uses legacy platform naming. Set by the core, machine
|
||||
* drivers should not modify this value.
|
||||
*/
|
||||
unsigned int legacy_platform:1;
|
||||
|
||||
struct list_head list; /* DAI link list of the soc card */
|
||||
struct snd_soc_dobj dobj; /* For topology */
|
||||
};
|
||||
|
@ -1044,6 +997,100 @@ struct snd_soc_dai_link {
|
|||
((i) < link->num_codecs) && ((codec) = &link->codecs[i]); \
|
||||
(i)++)
|
||||
|
||||
#define for_each_link_platforms(link, i, platform) \
|
||||
for ((i) = 0; \
|
||||
((i) < link->num_platforms) && \
|
||||
((platform) = &link->platforms[i]); \
|
||||
(i)++)
|
||||
|
||||
/*
|
||||
* Sample 1 : Single CPU/Codec/Platform
|
||||
*
|
||||
* SND_SOC_DAILINK_DEFS(test,
|
||||
* DAILINK_COMP_ARRAY(COMP_CPU("cpu_dai")),
|
||||
* DAILINK_COMP_ARRAY(COMP_CODEC("codec", "codec_dai")),
|
||||
* DAILINK_COMP_ARRAY(COMP_PLATFORM("platform")));
|
||||
*
|
||||
* struct snd_soc_dai_link link = {
|
||||
* ...
|
||||
* SND_SOC_DAILINK_REG(test),
|
||||
* };
|
||||
*
|
||||
* Sample 2 : Multi CPU/Codec, no Platform
|
||||
*
|
||||
* SND_SOC_DAILINK_DEFS(test,
|
||||
* DAILINK_COMP_ARRAY(COMP_CPU("cpu_dai1"),
|
||||
* COMP_CPU("cpu_dai2")),
|
||||
* DAILINK_COMP_ARRAY(COMP_CODEC("codec1", "codec_dai1"),
|
||||
* COMP_CODEC("codec2", "codec_dai2")));
|
||||
*
|
||||
* struct snd_soc_dai_link link = {
|
||||
* ...
|
||||
* SND_SOC_DAILINK_REG(test),
|
||||
* };
|
||||
*
|
||||
* Sample 3 : Define each CPU/Codec/Platform manually
|
||||
*
|
||||
* SND_SOC_DAILINK_DEF(test_cpu,
|
||||
* DAILINK_COMP_ARRAY(COMP_CPU("cpu_dai1"),
|
||||
* COMP_CPU("cpu_dai2")));
|
||||
* SND_SOC_DAILINK_DEF(test_codec,
|
||||
* DAILINK_COMP_ARRAY(COMP_CODEC("codec1", "codec_dai1"),
|
||||
* COMP_CODEC("codec2", "codec_dai2")));
|
||||
* SND_SOC_DAILINK_DEF(test_platform,
|
||||
* DAILINK_COMP_ARRAY(COMP_PLATFORM("platform")));
|
||||
*
|
||||
* struct snd_soc_dai_link link = {
|
||||
* ...
|
||||
* SND_SOC_DAILINK_REG(test_cpu,
|
||||
* test_codec,
|
||||
* test_platform),
|
||||
* };
|
||||
*
|
||||
* Sample 4 : Sample3 without platform
|
||||
*
|
||||
* struct snd_soc_dai_link link = {
|
||||
* ...
|
||||
* SND_SOC_DAILINK_REG(test_cpu,
|
||||
* test_codec);
|
||||
* };
|
||||
*/
|
||||
|
||||
#define SND_SOC_DAILINK_REG1(name) SND_SOC_DAILINK_REG3(name##_cpus, name##_codecs, name##_platforms)
|
||||
#define SND_SOC_DAILINK_REG2(cpu, codec) SND_SOC_DAILINK_REG3(cpu, codec, null_dailink_component)
|
||||
#define SND_SOC_DAILINK_REG3(cpu, codec, platform) \
|
||||
.cpus = cpu, \
|
||||
.num_cpus = ARRAY_SIZE(cpu), \
|
||||
.codecs = codec, \
|
||||
.num_codecs = ARRAY_SIZE(codec), \
|
||||
.platforms = platform, \
|
||||
.num_platforms = ARRAY_SIZE(platform)
|
||||
|
||||
#define SND_SOC_DAILINK_REGx(_1, _2, _3, func, ...) func
|
||||
#define SND_SOC_DAILINK_REG(...) \
|
||||
SND_SOC_DAILINK_REGx(__VA_ARGS__, \
|
||||
SND_SOC_DAILINK_REG3, \
|
||||
SND_SOC_DAILINK_REG2, \
|
||||
SND_SOC_DAILINK_REG1)(__VA_ARGS__)
|
||||
|
||||
#define SND_SOC_DAILINK_DEF(name, def...) \
|
||||
static struct snd_soc_dai_link_component name[] = { def }
|
||||
|
||||
#define SND_SOC_DAILINK_DEFS(name, cpu, codec, platform...) \
|
||||
SND_SOC_DAILINK_DEF(name##_cpus, cpu); \
|
||||
SND_SOC_DAILINK_DEF(name##_codecs, codec); \
|
||||
SND_SOC_DAILINK_DEF(name##_platforms, platform)
|
||||
|
||||
#define DAILINK_COMP_ARRAY(param...) param
|
||||
#define COMP_EMPTY() { }
|
||||
#define COMP_CPU(_dai) { .dai_name = _dai, }
|
||||
#define COMP_CODEC(_name, _dai) { .name = _name, .dai_name = _dai, }
|
||||
#define COMP_PLATFORM(_name) { .name = _name }
|
||||
#define COMP_DUMMY() { .name = "snd-soc-dummy", .dai_name = "snd-soc-dummy-dai", }
|
||||
|
||||
extern struct snd_soc_dai_link_component null_dailink_component[0];
|
||||
|
||||
|
||||
struct snd_soc_codec_conf {
|
||||
/*
|
||||
* specify device either by device name, or by
|
||||
|
@ -1189,7 +1236,7 @@ struct snd_soc_card {
|
|||
(i)++)
|
||||
|
||||
#define for_each_card_links(card, link) \
|
||||
list_for_each_entry(dai_link, &(card)->dai_link_list, list)
|
||||
list_for_each_entry(link, &(card)->dai_link_list, list)
|
||||
#define for_each_card_links_safe(card, link, _link) \
|
||||
list_for_each_entry_safe(link, _link, &(card)->dai_link_list, list)
|
||||
|
||||
|
@ -1214,7 +1261,6 @@ struct snd_soc_pcm_runtime {
|
|||
|
||||
/* Dynamic PCM BE runtime data */
|
||||
struct snd_soc_dpcm_runtime dpcm[2];
|
||||
int fe_compr;
|
||||
|
||||
long pmdown_time;
|
||||
|
||||
|
@ -1239,6 +1285,7 @@ struct snd_soc_pcm_runtime {
|
|||
/* bit field */
|
||||
unsigned int dev_registered:1;
|
||||
unsigned int pop_wait:1;
|
||||
unsigned int fe_compr:1; /* for Dynamic PCM */
|
||||
};
|
||||
#define for_each_rtd_codec_dai(rtd, i, dai)\
|
||||
for ((i) = 0; \
|
||||
|
@ -1607,15 +1654,11 @@ int snd_soc_fixup_dai_links_platform_name(struct snd_soc_card *card,
|
|||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
if (dai_link->platforms)
|
||||
/* only single platform is supported for now */
|
||||
dai_link->platforms->name = name;
|
||||
else
|
||||
/*
|
||||
* legacy mode, this case will be removed when all
|
||||
* derivers are switched to modern style dai_link.
|
||||
*/
|
||||
dai_link->platform_name = name;
|
||||
if (!dai_link->platforms)
|
||||
return -EINVAL;
|
||||
|
||||
/* only single platform is supported for now */
|
||||
dai_link->platforms->name = name;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -167,9 +167,10 @@ struct sof_ipc_dai_dmic_params {
|
|||
|
||||
uint32_t wake_up_time; /**< Time from clock start to data (us) */
|
||||
uint32_t min_clock_on_time; /**< Min. time that clk is kept on (us) */
|
||||
uint32_t unmute_ramp_time; /**< Length of logarithmic gain ramp (ms) */
|
||||
|
||||
/* reserved for future use */
|
||||
uint32_t reserved[6];
|
||||
uint32_t reserved[5];
|
||||
|
||||
/**< variable number of pdm controller config */
|
||||
struct sof_ipc_dai_dmic_pdm_ctrl pdm[0];
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#define SOF_IPC_GLB_DAI_MSG SOF_GLB_TYPE(0x8U)
|
||||
#define SOF_IPC_GLB_TRACE_MSG SOF_GLB_TYPE(0x9U)
|
||||
#define SOF_IPC_GLB_GDB_DEBUG SOF_GLB_TYPE(0xAU)
|
||||
#define SOF_IPC_GLB_TEST_MSG SOF_GLB_TYPE(0xBU)
|
||||
|
||||
/*
|
||||
* DSP Command Message Types
|
||||
|
@ -99,9 +100,13 @@
|
|||
#define SOF_IPC_STREAM_VORBIS_PARAMS SOF_CMD_TYPE(0x010)
|
||||
#define SOF_IPC_STREAM_VORBIS_FREE SOF_CMD_TYPE(0x011)
|
||||
|
||||
/* trace and debug */
|
||||
/* trace */
|
||||
#define SOF_IPC_TRACE_DMA_PARAMS SOF_CMD_TYPE(0x001)
|
||||
#define SOF_IPC_TRACE_DMA_POSITION SOF_CMD_TYPE(0x002)
|
||||
#define SOF_IPC_TRACE_DMA_PARAMS_EXT SOF_CMD_TYPE(0x003)
|
||||
|
||||
/* debug */
|
||||
#define SOF_IPC_TEST_IPC_FLOOD SOF_CMD_TYPE(0x001)
|
||||
|
||||
/* Get message component id */
|
||||
#define SOF_IPC_MESSAGE_ID(x) ((x) & 0xffff)
|
||||
|
|
|
@ -35,6 +35,7 @@ enum sof_comp_type {
|
|||
SOF_COMP_KEYWORD_DETECT,
|
||||
SOF_COMP_KPB, /* A key phrase buffer component */
|
||||
SOF_COMP_SELECTOR, /**< channel selector component */
|
||||
SOF_COMP_DEMUX,
|
||||
/* 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 */
|
||||
|
@ -83,9 +84,9 @@ struct sof_ipc_buffer {
|
|||
struct sof_ipc_comp_config {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
uint32_t periods_sink; /**< 0 means variable */
|
||||
uint32_t periods_source; /**< 0 means variable */
|
||||
uint32_t periods_source;/**< 0 means variable */
|
||||
uint32_t reserved1; /**< reserved */
|
||||
uint32_t frame_fmt; /**< SOF_IPC_FRAME_ */
|
||||
uint32_t frame_fmt; /**< SOF_IPC_FRAME_ */
|
||||
uint32_t xrun_action;
|
||||
|
||||
/* reserved for future use */
|
||||
|
@ -175,6 +176,8 @@ enum sof_ipc_process_type {
|
|||
SOF_PROCESS_KEYWORD_DETECT, /**< Keyword Detection */
|
||||
SOF_PROCESS_KPB, /**< KeyPhrase Buffer Manager */
|
||||
SOF_PROCESS_CHAN_SELECTOR, /**< Channel Selector */
|
||||
SOF_PROCESS_MUX,
|
||||
SOF_PROCESS_DEMUX,
|
||||
};
|
||||
|
||||
/* generic "effect", "codec" or proprietary processing component */
|
||||
|
|
|
@ -19,12 +19,22 @@
|
|||
#define SOF_TRACE_FILENAME_SIZE 32
|
||||
|
||||
/* DMA for Trace params info - SOF_IPC_DEBUG_DMA_PARAMS */
|
||||
/* Deprecated - use sof_ipc_dma_trace_params_ext */
|
||||
struct sof_ipc_dma_trace_params {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
struct sof_ipc_host_buffer buffer;
|
||||
uint32_t stream_tag;
|
||||
} __packed;
|
||||
|
||||
/* DMA for Trace params info - SOF_IPC_DEBUG_DMA_PARAMS_EXT */
|
||||
struct sof_ipc_dma_trace_params_ext {
|
||||
struct sof_ipc_cmd_hdr hdr;
|
||||
struct sof_ipc_host_buffer buffer;
|
||||
uint32_t stream_tag;
|
||||
uint64_t timestamp_ns; /* in nanosecond */
|
||||
uint32_t reserved[8];
|
||||
} __packed;
|
||||
|
||||
/* DMA for Trace params info - SOF_IPC_DEBUG_DMA_PARAMS */
|
||||
struct sof_ipc_dma_trace_posn {
|
||||
struct sof_ipc_reply rhdr;
|
||||
|
@ -56,7 +66,9 @@ struct sof_ipc_dma_trace_posn {
|
|||
#define SOF_IPC_PANIC_WFI (SOF_IPC_PANIC_MAGIC | 0xa)
|
||||
#define SOF_IPC_PANIC_ASSERT (SOF_IPC_PANIC_MAGIC | 0xb)
|
||||
|
||||
/* panic info include filename and line number */
|
||||
/* panic info include filename and line number
|
||||
* filename array will not include null terminator if fully filled
|
||||
*/
|
||||
struct sof_ipc_panic_info {
|
||||
struct sof_ipc_hdr hdr;
|
||||
uint32_t code; /* SOF_IPC_PANIC_ */
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
/* SOF ABI version major, minor and patch numbers */
|
||||
#define SOF_ABI_MAJOR 3
|
||||
#define SOF_ABI_MINOR 6
|
||||
#define SOF_ABI_MINOR 8
|
||||
#define SOF_ABI_PATCH 0
|
||||
|
||||
/* SOF ABI version number. Format within 32bit word is MMmmmppp */
|
||||
|
|
|
@ -1,172 +0,0 @@
|
|||
/* 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) 2018 Intel Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDE_UAPI_SOUND_SOF_USER_EQ_H__
|
||||
#define __INCLUDE_UAPI_SOUND_SOF_USER_EQ_H__
|
||||
|
||||
/* FIR EQ type */
|
||||
|
||||
#define SOF_EQ_FIR_IDX_SWITCH 0
|
||||
|
||||
#define SOF_EQ_FIR_MAX_SIZE 4096 /* Max size allowed for coef data in bytes */
|
||||
|
||||
#define SOF_EQ_FIR_MAX_LENGTH 192 /* Max length for individual filter */
|
||||
|
||||
#define SOF_EQ_FIR_MAX_RESPONSES 8 /* A blob can define max 8 FIR EQs */
|
||||
|
||||
/*
|
||||
* eq_fir_configuration data structure contains this information
|
||||
* uint32_t size
|
||||
* This is the number of bytes need to store the received EQ
|
||||
* configuration.
|
||||
* uint16_t channels_in_config
|
||||
* This describes the number of channels in this EQ config data. It
|
||||
* can be different from PLATFORM_MAX_CHANNELS.
|
||||
* uint16_t number_of_responses
|
||||
* 0=no responses, 1=one response defined, 2=two responses defined, etc.
|
||||
* int16_t data[]
|
||||
* assign_response[channels_in_config]
|
||||
* 0 = use first response, 1 = use 2nd response, etc.
|
||||
* E.g. {0, 0, 0, 0, 1, 1, 1, 1} would apply to channels 0-3 the
|
||||
* same first defined response and for to channels 4-7 the second.
|
||||
* coef_data[]
|
||||
* Repeated data
|
||||
* { filter_length, output_shift, h[] }
|
||||
* for every EQ response defined where vector h has filter_length
|
||||
* number of coefficients. Coefficients in h[] are in Q1.15 format.
|
||||
* E.g. 16384 (Q1.15) = 0.5. The shifts are number of right shifts.
|
||||
*
|
||||
* NOTE: The channels_in_config must be even to have coef_data aligned to
|
||||
* 32 bit word in RAM. Therefore a mono EQ assign must be duplicated to 2ch
|
||||
* even if it would never used. Similarly a 5ch EQ assign must be increased
|
||||
* to 6ch. EQ init will return an error if this is not met.
|
||||
*
|
||||
* NOTE: The filter_length must be multiple of four. Therefore the filter must
|
||||
* be padded from the end with zeros have this condition met.
|
||||
*/
|
||||
|
||||
struct sof_eq_fir_config {
|
||||
uint32_t size;
|
||||
uint16_t channels_in_config;
|
||||
uint16_t number_of_responses;
|
||||
|
||||
/* reserved */
|
||||
uint32_t reserved[4];
|
||||
|
||||
int16_t data[];
|
||||
} __packed;
|
||||
|
||||
struct sof_eq_fir_coef_data {
|
||||
int16_t length; /* Number of FIR taps */
|
||||
int16_t out_shift; /* Amount of right shifts at output */
|
||||
|
||||
/* reserved */
|
||||
uint32_t reserved[4];
|
||||
|
||||
int16_t coef[]; /* FIR coefficients */
|
||||
} __packed;
|
||||
|
||||
/* In the struct above there's two 16 bit words (length, shift) and four
|
||||
* reserved 32 bit words before the actual FIR coefficients. This information
|
||||
* is used in parsing of the configuration blob.
|
||||
*/
|
||||
#define SOF_EQ_FIR_COEF_NHEADER \
|
||||
(sizeof(struct sof_eq_fir_coef_data) / sizeof(int16_t))
|
||||
|
||||
/* IIR EQ type */
|
||||
|
||||
#define SOF_EQ_IIR_IDX_SWITCH 0
|
||||
|
||||
#define SOF_EQ_IIR_MAX_SIZE 1024 /* Max size allowed for coef data in bytes */
|
||||
|
||||
#define SOF_EQ_IIR_MAX_RESPONSES 8 /* A blob can define max 8 IIR EQs */
|
||||
|
||||
/* eq_iir_configuration
|
||||
* uint32_t channels_in_config
|
||||
* This describes the number of channels in this EQ config data. It
|
||||
* can be different from PLATFORM_MAX_CHANNELS.
|
||||
* uint32_t number_of_responses_defined
|
||||
* 0=no responses, 1=one response defined, 2=two responses defined, etc.
|
||||
* int32_t data[]
|
||||
* Data consist of two parts. First is the response assign vector that
|
||||
* has length of channels_in_config. The latter part is coefficient
|
||||
* data.
|
||||
* uint32_t assign_response[channels_in_config]
|
||||
* -1 = not defined, 0 = use first response, 1 = use 2nd, etc.
|
||||
* E.g. {0, 0, 0, 0, -1, -1, -1, -1} would apply to channels 0-3 the
|
||||
* same first defined response and leave channels 4-7 unequalized.
|
||||
* coefficient_data[]
|
||||
* <1st EQ>
|
||||
* uint32_t num_biquads
|
||||
* uint32_t num_biquads_in_series
|
||||
* <1st biquad>
|
||||
* int32_t coef_a2 Q2.30 format
|
||||
* int32_t coef_a1 Q2.30 format
|
||||
* int32_t coef_b2 Q2.30 format
|
||||
* int32_t coef_b1 Q2.30 format
|
||||
* int32_t coef_b0 Q2.30 format
|
||||
* int32_t output_shift number of shifts right, shift left is negative
|
||||
* int32_t output_gain Q2.14 format
|
||||
* <2nd biquad>
|
||||
* ...
|
||||
* <2nd EQ>
|
||||
*
|
||||
* Note: A flat response biquad can be made with a section set to
|
||||
* b0 = 1.0, gain = 1.0, and other parameters set to 0
|
||||
* {0, 0, 0, 0, 1073741824, 0, 16484}
|
||||
*/
|
||||
|
||||
struct sof_eq_iir_config {
|
||||
uint32_t size;
|
||||
uint32_t channels_in_config;
|
||||
uint32_t number_of_responses;
|
||||
|
||||
/* reserved */
|
||||
uint32_t reserved[4];
|
||||
|
||||
int32_t data[]; /* eq_assign[channels], eq 0, eq 1, ... */
|
||||
} __packed;
|
||||
|
||||
struct sof_eq_iir_header_df2t {
|
||||
uint32_t num_sections;
|
||||
uint32_t num_sections_in_series;
|
||||
|
||||
/* reserved */
|
||||
uint32_t reserved[4];
|
||||
|
||||
int32_t biquads[]; /* Repeated biquad coefficients */
|
||||
} __packed;
|
||||
|
||||
struct sof_eq_iir_biquad_df2t {
|
||||
int32_t a2; /* Q2.30 */
|
||||
int32_t a1; /* Q2.30 */
|
||||
int32_t b2; /* Q2.30 */
|
||||
int32_t b1; /* Q2.30 */
|
||||
int32_t b0; /* Q2.30 */
|
||||
int32_t output_shift; /* Number of right shifts */
|
||||
int32_t output_gain; /* Q2.14 */
|
||||
} __packed;
|
||||
|
||||
/* A full 22th order equalizer with 11 biquads cover octave bands 1-11 in
|
||||
* in the 0 - 20 kHz bandwidth.
|
||||
*/
|
||||
#define SOF_EQ_IIR_DF2T_BIQUADS_MAX 11
|
||||
|
||||
/* The number of int32_t words in sof_eq_iir_header_df2t:
|
||||
* num_sections, num_sections_in_series, reserved[4]
|
||||
*/
|
||||
#define SOF_EQ_IIR_NHEADER_DF2T \
|
||||
(sizeof(struct sof_eq_iir_header_df2t) / sizeof(int32_t))
|
||||
|
||||
/* The number of int32_t words in sof_eq_iir_biquad_df2t:
|
||||
* a2, a1, b2, b1, b0, output_shift, output_gain
|
||||
*/
|
||||
#define SOF_EQ_IIR_NBIQUAD_DF2T \
|
||||
(sizeof(struct sof_eq_iir_biquad_df2t) / sizeof(int32_t))
|
||||
|
||||
#endif
|
|
@ -1,188 +0,0 @@
|
|||
/* 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) 2018 Intel Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDE_UAPI_SOUND_SOF_USER_MANIFEST_H__
|
||||
#define __INCLUDE_UAPI_SOUND_SOF_USER_MANIFEST_H__
|
||||
|
||||
/* start offset for base FW module */
|
||||
#define SOF_MAN_ELF_TEXT_OFFSET 0x2000
|
||||
|
||||
/* FW Extended Manifest Header id = $AE1 */
|
||||
#define SOF_MAN_EXT_HEADER_MAGIC 0x31454124
|
||||
|
||||
/* module type load type */
|
||||
#define SOF_MAN_MOD_TYPE_BUILTIN 0
|
||||
#define SOF_MAN_MOD_TYPE_MODULE 1
|
||||
|
||||
struct sof_man_module_type {
|
||||
uint32_t load_type:4; /* SOF_MAN_MOD_TYPE_ */
|
||||
uint32_t auto_start:1;
|
||||
uint32_t domain_ll:1;
|
||||
uint32_t domain_dp:1;
|
||||
uint32_t rsvd_:25;
|
||||
};
|
||||
|
||||
/* segment flags.type */
|
||||
#define SOF_MAN_SEGMENT_TEXT 0
|
||||
#define SOF_MAN_SEGMENT_RODATA 1
|
||||
#define SOF_MAN_SEGMENT_DATA 1
|
||||
#define SOF_MAN_SEGMENT_BSS 2
|
||||
#define SOF_MAN_SEGMENT_EMPTY 15
|
||||
|
||||
union sof_man_segment_flags {
|
||||
uint32_t ul;
|
||||
struct {
|
||||
uint32_t contents:1;
|
||||
uint32_t alloc:1;
|
||||
uint32_t load:1;
|
||||
uint32_t readonly:1;
|
||||
uint32_t code:1;
|
||||
uint32_t data:1;
|
||||
uint32_t _rsvd0:2;
|
||||
uint32_t type:4; /* MAN_SEGMENT_ */
|
||||
uint32_t _rsvd1:4;
|
||||
uint32_t length:16; /* of segment in pages */
|
||||
} r;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Module segment descriptor. Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_segment_desc {
|
||||
union sof_man_segment_flags flags;
|
||||
uint32_t v_base_addr;
|
||||
uint32_t file_offset;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* The firmware binary can be split into several modules.
|
||||
*/
|
||||
|
||||
#define SOF_MAN_MOD_ID_LEN 4
|
||||
#define SOF_MAN_MOD_NAME_LEN 8
|
||||
#define SOF_MAN_MOD_SHA256_LEN 32
|
||||
#define SOF_MAN_MOD_ID {'$', 'A', 'M', 'E'}
|
||||
|
||||
/*
|
||||
* Each module has an entry in the FW header. Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_module {
|
||||
uint8_t struct_id[SOF_MAN_MOD_ID_LEN]; /* SOF_MAN_MOD_ID */
|
||||
uint8_t name[SOF_MAN_MOD_NAME_LEN];
|
||||
uint8_t uuid[16];
|
||||
struct sof_man_module_type type;
|
||||
uint8_t hash[SOF_MAN_MOD_SHA256_LEN];
|
||||
uint32_t entry_point;
|
||||
uint16_t cfg_offset;
|
||||
uint16_t cfg_count;
|
||||
uint32_t affinity_mask;
|
||||
uint16_t instance_max_count; /* max number of instances */
|
||||
uint16_t instance_bss_size; /* instance (pages) */
|
||||
struct sof_man_segment_desc segment[3];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Each module has a configuration in the FW header. Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_mod_config {
|
||||
uint32_t par[4]; /* module parameters */
|
||||
uint32_t is_pages; /* actual size of instance .bss (pages) */
|
||||
uint32_t cps; /* cycles per second */
|
||||
uint32_t ibs; /* input buffer size (bytes) */
|
||||
uint32_t obs; /* output buffer size (bytes) */
|
||||
uint32_t module_flags; /* flags, reserved for future use */
|
||||
uint32_t cpc; /* cycles per single run */
|
||||
uint32_t obls; /* output block size, reserved for future use */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* FW Manifest Header
|
||||
*/
|
||||
|
||||
#define SOF_MAN_FW_HDR_FW_NAME_LEN 8
|
||||
#define SOF_MAN_FW_HDR_ID {'$', 'A', 'M', '1'}
|
||||
#define SOF_MAN_FW_HDR_NAME "ADSPFW"
|
||||
#define SOF_MAN_FW_HDR_FLAGS 0x0
|
||||
#define SOF_MAN_FW_HDR_FEATURES 0xff
|
||||
|
||||
/*
|
||||
* The firmware has a standard header that is checked by the ROM on firmware
|
||||
* loading. preload_page_count is used by DMA code loader and is entire
|
||||
* image size on CNL. i.e. CNL: total size of the binary’s .text and .rodata
|
||||
* Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_fw_header {
|
||||
uint8_t header_id[4];
|
||||
uint32_t header_len;
|
||||
uint8_t name[SOF_MAN_FW_HDR_FW_NAME_LEN];
|
||||
/* number of pages of preloaded image loaded by driver */
|
||||
uint32_t preload_page_count;
|
||||
uint32_t fw_image_flags;
|
||||
uint32_t feature_mask;
|
||||
uint16_t major_version;
|
||||
uint16_t minor_version;
|
||||
uint16_t hotfix_version;
|
||||
uint16_t build_version;
|
||||
uint32_t num_module_entries;
|
||||
uint32_t hw_buf_base_addr;
|
||||
uint32_t hw_buf_length;
|
||||
/* target address for binary loading as offset in IMR - must be == base offset */
|
||||
uint32_t load_offset;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Firmware manifest descriptor. This can contain N modules and N module
|
||||
* configs. Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_fw_desc {
|
||||
struct sof_man_fw_header header;
|
||||
|
||||
/* Warning - hack for module arrays. For some unknown reason the we
|
||||
* have a variable size array of struct man_module followed by a
|
||||
* variable size array of struct mod_config. These should have been
|
||||
* merged into a variable array of a parent structure. We have to hack
|
||||
* around this in many places....
|
||||
*
|
||||
* struct sof_man_module man_module[];
|
||||
* struct sof_man_mod_config mod_config[];
|
||||
*/
|
||||
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Component Descriptor. Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_component_desc {
|
||||
uint32_t reserved[2]; /* all 0 */
|
||||
uint32_t version;
|
||||
uint8_t hash[SOF_MAN_MOD_SHA256_LEN];
|
||||
uint32_t base_offset;
|
||||
uint32_t limit_offset;
|
||||
uint32_t attributes[4];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Audio DSP extended metadata. Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_adsp_meta_file_ext {
|
||||
uint32_t ext_type; /* always 17 for ADSP extension */
|
||||
uint32_t ext_len;
|
||||
uint32_t imr_type;
|
||||
uint8_t reserved[16]; /* all 0 */
|
||||
struct sof_man_component_desc comp_desc[1];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Module Manifest for rimage module metadata. Not used by ROM.
|
||||
*/
|
||||
struct sof_man_module_manifest {
|
||||
struct sof_man_module module;
|
||||
uint32_t text_size;
|
||||
} __packed;
|
||||
|
||||
#endif
|
|
@ -85,6 +85,7 @@
|
|||
#define SOF_TKN_INTEL_DMIC_NUM_PDM_ACTIVE 605
|
||||
#define SOF_TKN_INTEL_DMIC_SAMPLE_RATE 608
|
||||
#define SOF_TKN_INTEL_DMIC_FIFO_WORD_LENGTH 609
|
||||
#define SOF_TKN_INTEL_DMIC_UNMUTE_RAMP_TIME_MS 610
|
||||
|
||||
/* DMIC PDM */
|
||||
#define SOF_TKN_INTEL_DMIC_PDM_CTRL_ID 700
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/* 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) 2018 Intel Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDE_UAPI_SOUND_SOF_USER_TONE_H__
|
||||
#define __INCLUDE_UAPI_SOUND_SOF_USER_TONE_H__
|
||||
|
||||
#define SOF_TONE_IDX_FREQUENCY 0
|
||||
#define SOF_TONE_IDX_AMPLITUDE 1
|
||||
#define SOF_TONE_IDX_FREQ_MULT 2
|
||||
#define SOF_TONE_IDX_AMPL_MULT 3
|
||||
#define SOF_TONE_IDX_LENGTH 4
|
||||
#define SOF_TONE_IDX_PERIOD 5
|
||||
#define SOF_TONE_IDX_REPEATS 6
|
||||
#define SOF_TONE_IDX_LIN_RAMP_STEP 7
|
||||
|
||||
#endif
|
|
@ -1,66 +0,0 @@
|
|||
/* 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) 2018 Intel Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDE_UAPI_SOUND_SOF_USER_TRACE_H__
|
||||
#define __INCLUDE_UAPI_SOUND_SOF_USER_TRACE_H__
|
||||
|
||||
/*
|
||||
* Host system time.
|
||||
*
|
||||
* This property is used by the driver to pass down information about
|
||||
* current system time. It is expressed in us.
|
||||
* FW translates timestamps (in log entries, probe pockets) to this time
|
||||
* domain.
|
||||
*
|
||||
* (cavs: SystemTime).
|
||||
*/
|
||||
struct system_time {
|
||||
uint32_t val_l; /* Lower dword of current host time value */
|
||||
uint32_t val_u; /* Upper dword of current host time value */
|
||||
} __packed;
|
||||
|
||||
#define LOG_ENABLE 1 /* Enable logging */
|
||||
#define LOG_DISABLE 0 /* Disable logging */
|
||||
|
||||
#define LOG_LEVEL_CRITICAL 1 /* (FDK fatal) */
|
||||
#define LOG_LEVEL_VERBOSE 2
|
||||
|
||||
/*
|
||||
* Layout of a log fifo.
|
||||
*/
|
||||
struct log_buffer_layout {
|
||||
uint32_t read_ptr; /*read pointer */
|
||||
uint32_t write_ptr; /* write pointer */
|
||||
uint32_t buffer[0]; /* buffer */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Log buffer status reported by FW.
|
||||
*/
|
||||
struct log_buffer_status {
|
||||
uint32_t core_id; /* ID of core that logged to other half */
|
||||
} __packed;
|
||||
|
||||
#define TRACE_ID_LENGTH 12
|
||||
|
||||
/*
|
||||
* Log entry header.
|
||||
*
|
||||
* The header is followed by an array of arguments (uint32_t[]).
|
||||
* Number of arguments is specified by the params_num field of log_entry
|
||||
*/
|
||||
struct log_entry_header {
|
||||
uint32_t id_0 : TRACE_ID_LENGTH; /* e.g. Pipeline ID */
|
||||
uint32_t id_1 : TRACE_ID_LENGTH; /* e.g. Component ID */
|
||||
uint32_t core_id : 8; /* Reporting core's id */
|
||||
|
||||
uint64_t timestamp; /* Timestamp (in dsp ticks) */
|
||||
uint32_t log_entry_address; /* Address of log entry in ELF */
|
||||
} __packed;
|
||||
|
||||
#endif
|
|
@ -85,7 +85,6 @@ int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
|
|||
const struct hdac_ext_bus_ops *ext_ops)
|
||||
{
|
||||
int ret;
|
||||
static int idx;
|
||||
|
||||
/* check if io ops are provided, if not load the defaults */
|
||||
if (io_ops == NULL)
|
||||
|
@ -96,7 +95,12 @@ int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
|
|||
return ret;
|
||||
|
||||
bus->ext_ops = ext_ops;
|
||||
bus->idx = idx++;
|
||||
/* FIXME:
|
||||
* Currently only one bus is supported, if there is device with more
|
||||
* buses, bus->idx should be greater than 0, but there needs to be a
|
||||
* reliable way to always assign same number.
|
||||
*/
|
||||
bus->idx = 0;
|
||||
bus->cmd_dma_state = true;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -298,69 +298,71 @@ static const struct snd_soc_ops cz_dmic1_cap_ops = {
|
|||
.hw_params = cz_da7219_params,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEF(designware1,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.1.auto")));
|
||||
SND_SOC_DAILINK_DEF(designware2,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.2.auto")));
|
||||
SND_SOC_DAILINK_DEF(designware3,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.3.auto")));
|
||||
|
||||
SND_SOC_DAILINK_DEF(dlgs,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00", "da7219-hifi")));
|
||||
SND_SOC_DAILINK_DEF(mx,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", "HiFi")));
|
||||
SND_SOC_DAILINK_DEF(adau,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("ADAU7002:00", "adau7002-hifi")));
|
||||
|
||||
SND_SOC_DAILINK_DEF(platform,
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_audio_dma.0.auto")));
|
||||
|
||||
static struct snd_soc_dai_link cz_dai_7219_98357[] = {
|
||||
{
|
||||
.name = "amd-da7219-play",
|
||||
.stream_name = "Playback",
|
||||
.platform_name = "acp_audio_dma.0.auto",
|
||||
.cpu_dai_name = "designware-i2s.1.auto",
|
||||
.codec_dai_name = "da7219-hifi",
|
||||
.codec_name = "i2c-DLGS7219:00",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
|
||||
| SND_SOC_DAIFMT_CBM_CFM,
|
||||
.init = cz_da7219_init,
|
||||
.dpcm_playback = 1,
|
||||
.ops = &cz_da7219_play_ops,
|
||||
SND_SOC_DAILINK_REG(designware1, dlgs, platform),
|
||||
},
|
||||
{
|
||||
.name = "amd-da7219-cap",
|
||||
.stream_name = "Capture",
|
||||
.platform_name = "acp_audio_dma.0.auto",
|
||||
.cpu_dai_name = "designware-i2s.2.auto",
|
||||
.codec_dai_name = "da7219-hifi",
|
||||
.codec_name = "i2c-DLGS7219:00",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
|
||||
| SND_SOC_DAIFMT_CBM_CFM,
|
||||
.dpcm_capture = 1,
|
||||
.ops = &cz_da7219_cap_ops,
|
||||
SND_SOC_DAILINK_REG(designware2, dlgs, platform),
|
||||
},
|
||||
{
|
||||
.name = "amd-max98357-play",
|
||||
.stream_name = "HiFi Playback",
|
||||
.platform_name = "acp_audio_dma.0.auto",
|
||||
.cpu_dai_name = "designware-i2s.3.auto",
|
||||
.codec_dai_name = "HiFi",
|
||||
.codec_name = "MX98357A:00",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
|
||||
| SND_SOC_DAIFMT_CBM_CFM,
|
||||
.dpcm_playback = 1,
|
||||
.ops = &cz_max_play_ops,
|
||||
SND_SOC_DAILINK_REG(designware3, mx, platform),
|
||||
},
|
||||
{
|
||||
/* C panel DMIC */
|
||||
.name = "dmic0",
|
||||
.stream_name = "DMIC0 Capture",
|
||||
.platform_name = "acp_audio_dma.0.auto",
|
||||
.cpu_dai_name = "designware-i2s.3.auto",
|
||||
.codec_dai_name = "adau7002-hifi",
|
||||
.codec_name = "ADAU7002:00",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
|
||||
| SND_SOC_DAIFMT_CBM_CFM,
|
||||
.dpcm_capture = 1,
|
||||
.ops = &cz_dmic0_cap_ops,
|
||||
SND_SOC_DAILINK_REG(designware3, adau, platform),
|
||||
},
|
||||
{
|
||||
/* A/B panel DMIC */
|
||||
.name = "dmic1",
|
||||
.stream_name = "DMIC1 Capture",
|
||||
.platform_name = "acp_audio_dma.0.auto",
|
||||
.cpu_dai_name = "designware-i2s.2.auto",
|
||||
.codec_dai_name = "adau7002-hifi",
|
||||
.codec_name = "ADAU7002:00",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
|
||||
| SND_SOC_DAIFMT_CBM_CFM,
|
||||
.dpcm_capture = 1,
|
||||
.ops = &cz_dmic1_cap_ops,
|
||||
SND_SOC_DAILINK_REG(designware2, adau, platform),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -95,29 +95,34 @@ static struct snd_soc_ops cz_aif1_ops = {
|
|||
.hw_params = cz_aif1_hw_params,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEF(designware1,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.1.auto")));
|
||||
SND_SOC_DAILINK_DEF(designware2,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.2.auto")));
|
||||
|
||||
SND_SOC_DAILINK_DEF(codec,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5650:00", "rt5645-aif1")));
|
||||
|
||||
SND_SOC_DAILINK_DEF(platform,
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_audio_dma.0.auto")));
|
||||
|
||||
static struct snd_soc_dai_link cz_dai_rt5650[] = {
|
||||
{
|
||||
.name = "amd-rt5645-play",
|
||||
.stream_name = "RT5645_AIF1",
|
||||
.platform_name = "acp_audio_dma.0.auto",
|
||||
.cpu_dai_name = "designware-i2s.1.auto",
|
||||
.codec_dai_name = "rt5645-aif1",
|
||||
.codec_name = "i2c-10EC5650:00",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
|
||||
| SND_SOC_DAIFMT_CBM_CFM,
|
||||
.init = cz_init,
|
||||
.ops = &cz_aif1_ops,
|
||||
SND_SOC_DAILINK_REG(designware1, codec, platform),
|
||||
},
|
||||
{
|
||||
.name = "amd-rt5645-cap",
|
||||
.stream_name = "RT5645_AIF1",
|
||||
.platform_name = "acp_audio_dma.0.auto",
|
||||
.cpu_dai_name = "designware-i2s.2.auto",
|
||||
.codec_dai_name = "rt5645-aif1",
|
||||
.codec_name = "i2c-10EC5650:00",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
|
||||
| SND_SOC_DAIFMT_CBM_CFM,
|
||||
.ops = &cz_aif1_ops,
|
||||
SND_SOC_DAILINK_REG(designware2, codec, platform),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ struct i2s_stream_instance {
|
|||
u16 channels;
|
||||
u32 xfer_resolution;
|
||||
struct page *pg;
|
||||
u64 bytescount;
|
||||
void __iomem *acp3x_base;
|
||||
};
|
||||
|
||||
|
@ -317,6 +318,24 @@ static int acp3x_dma_open(struct snd_pcm_substream *substream)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static u64 acp_get_byte_count(struct i2s_stream_instance *rtd, int direction)
|
||||
{
|
||||
u64 byte_count;
|
||||
|
||||
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
byte_count = rv_readl(rtd->acp3x_base +
|
||||
mmACP_BT_TX_LINEARPOSITIONCNTR_HIGH);
|
||||
byte_count |= rv_readl(rtd->acp3x_base +
|
||||
mmACP_BT_TX_LINEARPOSITIONCNTR_LOW);
|
||||
} else {
|
||||
byte_count = rv_readl(rtd->acp3x_base +
|
||||
mmACP_BT_RX_LINEARPOSITIONCNTR_HIGH);
|
||||
byte_count |= rv_readl(rtd->acp3x_base +
|
||||
mmACP_BT_RX_LINEARPOSITIONCNTR_LOW);
|
||||
}
|
||||
return byte_count;
|
||||
}
|
||||
|
||||
static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
|
@ -350,18 +369,17 @@ static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
|
|||
static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_pcm_substream *substream)
|
||||
{
|
||||
u32 pos = 0;
|
||||
struct i2s_stream_instance *rtd = substream->runtime->private_data;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
pos = rv_readl(rtd->acp3x_base +
|
||||
mmACP_BT_TX_LINKPOSITIONCNTR);
|
||||
else
|
||||
pos = rv_readl(rtd->acp3x_base +
|
||||
mmACP_BT_RX_LINKPOSITIONCNTR);
|
||||
|
||||
if (pos >= MAX_BUFFER)
|
||||
pos = 0;
|
||||
u32 buffersize = 0;
|
||||
u64 bytescount = 0;
|
||||
struct i2s_stream_instance *rtd =
|
||||
substream->runtime->private_data;
|
||||
|
||||
buffersize = frames_to_bytes(substream->runtime,
|
||||
substream->runtime->buffer_size);
|
||||
bytescount = acp_get_byte_count(rtd, substream->stream);
|
||||
if (bytescount > rtd->bytescount)
|
||||
bytescount -= rtd->bytescount;
|
||||
pos = do_div(bytescount, buffersize);
|
||||
return bytes_to_frames(substream->runtime, pos);
|
||||
}
|
||||
|
||||
|
@ -521,6 +539,7 @@ static int acp3x_dai_i2s_trigger(struct snd_pcm_substream *substream,
|
|||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
rtd->bytescount = acp_get_byte_count(rtd, substream->stream);
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
rv_writel(period_bytes, rtd->acp3x_base +
|
||||
mmACP_BT_TX_INTR_WATERMARK_SIZE);
|
||||
|
|
|
@ -497,17 +497,30 @@ static int atmel_classd_asoc_card_init(struct device *dev,
|
|||
{
|
||||
struct snd_soc_dai_link *dai_link;
|
||||
struct atmel_classd *dd = snd_soc_card_get_drvdata(card);
|
||||
struct snd_soc_dai_link_component *comp;
|
||||
|
||||
dai_link = devm_kzalloc(dev, sizeof(*dai_link), GFP_KERNEL);
|
||||
if (!dai_link)
|
||||
return -ENOMEM;
|
||||
|
||||
comp = devm_kzalloc(dev, 3 * sizeof(*comp), GFP_KERNEL);
|
||||
if (!comp)
|
||||
return -ENOMEM;
|
||||
|
||||
dai_link->cpus = &comp[0];
|
||||
dai_link->codecs = &comp[1];
|
||||
dai_link->platforms = &comp[2];
|
||||
|
||||
dai_link->num_cpus = 1;
|
||||
dai_link->num_codecs = 1;
|
||||
dai_link->num_platforms = 1;
|
||||
|
||||
dai_link->name = "CLASSD";
|
||||
dai_link->stream_name = "CLASSD PCM";
|
||||
dai_link->codec_dai_name = ATMEL_CLASSD_CODEC_DAI_NAME;
|
||||
dai_link->cpu_dai_name = dev_name(dev);
|
||||
dai_link->codec_name = dev_name(dev);
|
||||
dai_link->platform_name = dev_name(dev);
|
||||
dai_link->codecs->dai_name = ATMEL_CLASSD_CODEC_DAI_NAME;
|
||||
dai_link->cpus->dai_name = dev_name(dev);
|
||||
dai_link->codecs->name = dev_name(dev);
|
||||
dai_link->platforms->name = dev_name(dev);
|
||||
|
||||
card->dai_link = dai_link;
|
||||
card->num_links = 1;
|
||||
|
|
|
@ -111,16 +111,11 @@ static const struct snd_dmaengine_pcm_config atmel_dmaengine_pcm_config = {
|
|||
|
||||
int atmel_pcm_dma_platform_register(struct device *dev)
|
||||
{
|
||||
return snd_dmaengine_pcm_register(dev, &atmel_dmaengine_pcm_config, 0);
|
||||
return devm_snd_dmaengine_pcm_register(dev,
|
||||
&atmel_dmaengine_pcm_config, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(atmel_pcm_dma_platform_register);
|
||||
|
||||
void atmel_pcm_dma_platform_unregister(struct device *dev)
|
||||
{
|
||||
snd_dmaengine_pcm_unregister(dev);
|
||||
}
|
||||
EXPORT_SYMBOL(atmel_pcm_dma_platform_unregister);
|
||||
|
||||
MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>");
|
||||
MODULE_DESCRIPTION("Atmel DMA based PCM module");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -393,11 +393,6 @@ int atmel_pcm_pdc_platform_register(struct device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL(atmel_pcm_pdc_platform_register);
|
||||
|
||||
void atmel_pcm_pdc_platform_unregister(struct device *dev)
|
||||
{
|
||||
}
|
||||
EXPORT_SYMBOL(atmel_pcm_pdc_platform_unregister);
|
||||
|
||||
MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
|
||||
MODULE_DESCRIPTION("Atmel PCM module");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -72,28 +72,20 @@ struct atmel_pcm_dma_params {
|
|||
|
||||
#if IS_ENABLED(CONFIG_SND_ATMEL_SOC_PDC)
|
||||
int atmel_pcm_pdc_platform_register(struct device *dev);
|
||||
void atmel_pcm_pdc_platform_unregister(struct device *dev);
|
||||
#else
|
||||
static inline int atmel_pcm_pdc_platform_register(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void atmel_pcm_pdc_platform_unregister(struct device *dev)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_ATMEL_SOC_DMA)
|
||||
int atmel_pcm_dma_platform_register(struct device *dev);
|
||||
void atmel_pcm_dma_platform_unregister(struct device *dev);
|
||||
#else
|
||||
static inline int atmel_pcm_dma_platform_register(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void atmel_pcm_dma_platform_unregister(struct device *dev)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ATMEL_PCM_H */
|
||||
|
|
|
@ -508,17 +508,30 @@ static int atmel_pdmic_asoc_card_init(struct device *dev,
|
|||
{
|
||||
struct snd_soc_dai_link *dai_link;
|
||||
struct atmel_pdmic *dd = snd_soc_card_get_drvdata(card);
|
||||
struct snd_soc_dai_link_component *comp;
|
||||
|
||||
dai_link = devm_kzalloc(dev, sizeof(*dai_link), GFP_KERNEL);
|
||||
if (!dai_link)
|
||||
return -ENOMEM;
|
||||
|
||||
comp = devm_kzalloc(dev, 3 * sizeof(*comp), GFP_KERNEL);
|
||||
if (!comp)
|
||||
return -ENOMEM;
|
||||
|
||||
dai_link->cpus = &comp[0];
|
||||
dai_link->codecs = &comp[1];
|
||||
dai_link->platforms = &comp[2];
|
||||
|
||||
dai_link->num_cpus = 1;
|
||||
dai_link->num_codecs = 1;
|
||||
dai_link->num_platforms = 1;
|
||||
|
||||
dai_link->name = "PDMIC";
|
||||
dai_link->stream_name = "PDMIC PCM";
|
||||
dai_link->codec_dai_name = ATMEL_PDMIC_CODEC_DAI_NAME;
|
||||
dai_link->cpu_dai_name = dev_name(dev);
|
||||
dai_link->codec_name = dev_name(dev);
|
||||
dai_link->platform_name = dev_name(dev);
|
||||
dai_link->codecs->dai_name = ATMEL_PDMIC_CODEC_DAI_NAME;
|
||||
dai_link->cpus->dai_name = dev_name(dev);
|
||||
dai_link->codecs->name = dev_name(dev);
|
||||
dai_link->platforms->name = dev_name(dev);
|
||||
|
||||
card->dai_link = dai_link;
|
||||
card->num_links = 1;
|
||||
|
|
|
@ -1012,16 +1012,6 @@ static int asoc_ssc_init(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void asoc_ssc_exit(struct device *dev)
|
||||
{
|
||||
struct ssc_device *ssc = dev_get_drvdata(dev);
|
||||
|
||||
if (ssc->pdata->use_dma)
|
||||
atmel_pcm_dma_platform_unregister(dev);
|
||||
else
|
||||
atmel_pcm_pdc_platform_unregister(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* atmel_ssc_set_audio - Allocate the specified SSC for audio use.
|
||||
*/
|
||||
|
@ -1050,7 +1040,6 @@ void atmel_ssc_put_audio(int ssc_id)
|
|||
{
|
||||
struct ssc_device *ssc = ssc_info[ssc_id].ssc;
|
||||
|
||||
asoc_ssc_exit(&ssc->pdev->dev);
|
||||
ssc_free(ssc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(atmel_ssc_put_audio);
|
||||
|
|
|
@ -56,14 +56,19 @@ static const struct snd_soc_ops atmel_asoc_wm8904_ops = {
|
|||
.hw_params = atmel_asoc_wm8904_hw_params,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(pcm,
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8904-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
|
||||
static struct snd_soc_dai_link atmel_asoc_wm8904_dailink = {
|
||||
.name = "WM8904",
|
||||
.stream_name = "WM8904 PCM",
|
||||
.codec_dai_name = "wm8904-hifi",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S
|
||||
| SND_SOC_DAIFMT_NB_NF
|
||||
| SND_SOC_DAIFMT_CBM_CFM,
|
||||
.ops = &atmel_asoc_wm8904_ops,
|
||||
SND_SOC_DAILINK_REG(pcm),
|
||||
};
|
||||
|
||||
static struct snd_soc_card atmel_asoc_wm8904_card = {
|
||||
|
@ -107,8 +112,8 @@ static int atmel_asoc_wm8904_dt_init(struct platform_device *pdev)
|
|||
ret = -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
dailink->cpu_of_node = cpu_np;
|
||||
dailink->platform_of_node = cpu_np;
|
||||
dailink->cpus->of_node = cpu_np;
|
||||
dailink->platforms->of_node = cpu_np;
|
||||
of_node_put(cpu_np);
|
||||
|
||||
codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
|
||||
|
@ -117,7 +122,7 @@ static int atmel_asoc_wm8904_dt_init(struct platform_device *pdev)
|
|||
ret = -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
dailink->codec_of_node = codec_np;
|
||||
dailink->codecs->of_node = codec_np;
|
||||
of_node_put(codec_np);
|
||||
|
||||
return 0;
|
||||
|
@ -136,7 +141,7 @@ static int atmel_asoc_wm8904_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
id = of_alias_get_id((struct device_node *)dailink->cpu_of_node, "ssc");
|
||||
id = of_alias_get_id((struct device_node *)dailink->cpus->of_node, "ssc");
|
||||
ret = atmel_ssc_set_audio(id);
|
||||
if (ret != 0) {
|
||||
dev_err(&pdev->dev, "failed to set SSC %d for audio\n", id);
|
||||
|
@ -162,7 +167,7 @@ static int atmel_asoc_wm8904_remove(struct platform_device *pdev)
|
|||
struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;
|
||||
int id;
|
||||
|
||||
id = of_alias_get_id((struct device_node *)dailink->cpu_of_node, "ssc");
|
||||
id = of_alias_get_id((struct device_node *)dailink->cpus->of_node, "ssc");
|
||||
|
||||
snd_soc_unregister_card(card);
|
||||
atmel_ssc_put_audio(id);
|
||||
|
|
|
@ -63,6 +63,7 @@ static struct snd_soc_card snd_proto = {
|
|||
static int snd_proto_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_dai_link *dai;
|
||||
struct snd_soc_dai_link_component *comp;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device_node *codec_np, *cpu_np;
|
||||
struct device_node *bitclkmaster = NULL;
|
||||
|
@ -84,12 +85,24 @@ static int snd_proto_probe(struct platform_device *pdev)
|
|||
if (!dai)
|
||||
return -ENOMEM;
|
||||
|
||||
/* for cpus/codecs/platforms */
|
||||
comp = devm_kzalloc(&pdev->dev, 3 * sizeof(*comp), GFP_KERNEL);
|
||||
if (!comp)
|
||||
return -ENOMEM;
|
||||
|
||||
snd_proto.dai_link = dai;
|
||||
snd_proto.num_links = 1;
|
||||
|
||||
dai->cpus = &comp[0];
|
||||
dai->num_cpus = 1;
|
||||
dai->codecs = &comp[1];
|
||||
dai->num_codecs = 1;
|
||||
dai->platforms = &comp[2];
|
||||
dai->num_platforms = 1;
|
||||
|
||||
dai->name = "WM8731";
|
||||
dai->stream_name = "WM8731 HiFi";
|
||||
dai->codec_dai_name = "wm8731-hifi";
|
||||
dai->codecs->dai_name = "wm8731-hifi";
|
||||
dai->init = &snd_proto_init;
|
||||
|
||||
codec_np = of_parse_phandle(np, "audio-codec", 0);
|
||||
|
@ -97,15 +110,15 @@ static int snd_proto_probe(struct platform_device *pdev)
|
|||
dev_err(&pdev->dev, "audio-codec node missing\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dai->codec_of_node = codec_np;
|
||||
dai->codecs->of_node = codec_np;
|
||||
|
||||
cpu_np = of_parse_phandle(np, "i2s-controller", 0);
|
||||
if (!cpu_np) {
|
||||
dev_err(&pdev->dev, "i2s-controller missing\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dai->cpu_of_node = cpu_np;
|
||||
dai->platform_of_node = cpu_np;
|
||||
dai->cpus->of_node = cpu_np;
|
||||
dai->platforms->of_node = cpu_np;
|
||||
|
||||
dai_fmt = snd_soc_of_parse_daifmt(np, NULL,
|
||||
&bitclkmaster, &framemaster);
|
||||
|
|
|
@ -116,16 +116,18 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
SND_SOC_DAILINK_DEFS(pcm,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("at91rm9200_ssc.0")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm8731.0-001b", "wm8731-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("at91rm9200_ssc.0")));
|
||||
|
||||
static struct snd_soc_dai_link at91sam9g20ek_dai = {
|
||||
.name = "WM8731",
|
||||
.stream_name = "WM8731 PCM",
|
||||
.cpu_dai_name = "at91rm9200_ssc.0",
|
||||
.codec_dai_name = "wm8731-hifi",
|
||||
.init = at91sam9g20ek_wm8731_init,
|
||||
.platform_name = "at91rm9200_ssc.0",
|
||||
.codec_name = "wm8731.0-001b",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM,
|
||||
SND_SOC_DAILINK_REG(pcm),
|
||||
};
|
||||
|
||||
static struct snd_soc_card snd_soc_at91sam9g20ek = {
|
||||
|
@ -198,24 +200,24 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
|
|||
goto err;
|
||||
|
||||
/* Parse codec info */
|
||||
at91sam9g20ek_dai.codec_name = NULL;
|
||||
at91sam9g20ek_dai.codecs->name = NULL;
|
||||
codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
|
||||
if (!codec_np) {
|
||||
dev_err(&pdev->dev, "codec info missing\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
at91sam9g20ek_dai.codec_of_node = codec_np;
|
||||
at91sam9g20ek_dai.codecs->of_node = codec_np;
|
||||
|
||||
/* Parse dai and platform info */
|
||||
at91sam9g20ek_dai.cpu_dai_name = NULL;
|
||||
at91sam9g20ek_dai.platform_name = NULL;
|
||||
at91sam9g20ek_dai.cpus->dai_name = NULL;
|
||||
at91sam9g20ek_dai.platforms->name = NULL;
|
||||
cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
|
||||
if (!cpu_np) {
|
||||
dev_err(&pdev->dev, "dai and pcm info missing\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
at91sam9g20ek_dai.cpu_of_node = cpu_np;
|
||||
at91sam9g20ek_dai.platform_of_node = cpu_np;
|
||||
at91sam9g20ek_dai.cpus->of_node = cpu_np;
|
||||
at91sam9g20ek_dai.platforms->of_node = cpu_np;
|
||||
|
||||
of_node_put(codec_np);
|
||||
of_node_put(cpu_np);
|
||||
|
|
|
@ -77,6 +77,7 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
|
|||
struct snd_soc_card *card;
|
||||
struct snd_soc_dai_link *dai;
|
||||
struct sam9x5_drvdata *priv;
|
||||
struct snd_soc_dai_link_component *comp;
|
||||
int ret;
|
||||
|
||||
if (!np) {
|
||||
|
@ -87,7 +88,8 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
|
|||
card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL);
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
dai = devm_kzalloc(&pdev->dev, sizeof(*dai), GFP_KERNEL);
|
||||
if (!dai || !card || !priv) {
|
||||
comp = devm_kzalloc(&pdev->dev, 3 * sizeof(*comp), GFP_KERNEL);
|
||||
if (!dai || !card || !priv || !comp) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
@ -100,9 +102,17 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
|
|||
card->num_links = 1;
|
||||
card->dapm_widgets = sam9x5_dapm_widgets;
|
||||
card->num_dapm_widgets = ARRAY_SIZE(sam9x5_dapm_widgets);
|
||||
|
||||
dai->cpus = &comp[0];
|
||||
dai->num_cpus = 1;
|
||||
dai->codecs = &comp[1];
|
||||
dai->num_codecs = 1;
|
||||
dai->platforms = &comp[2];
|
||||
dai->num_platforms = 1;
|
||||
|
||||
dai->name = "WM8731";
|
||||
dai->stream_name = "WM8731 PCM";
|
||||
dai->codec_dai_name = "wm8731-hifi";
|
||||
dai->codecs->dai_name = "wm8731-hifi";
|
||||
dai->init = sam9x5_wm8731_init;
|
||||
dai->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF
|
||||
| SND_SOC_DAIFMT_CBM_CFM;
|
||||
|
@ -126,7 +136,7 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
|
|||
goto out;
|
||||
}
|
||||
|
||||
dai->codec_of_node = codec_np;
|
||||
dai->codecs->of_node = codec_np;
|
||||
|
||||
cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
|
||||
if (!cpu_np) {
|
||||
|
@ -134,8 +144,8 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
|
|||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
dai->cpu_of_node = cpu_np;
|
||||
dai->platform_of_node = cpu_np;
|
||||
dai->cpus->of_node = cpu_np;
|
||||
dai->platforms->of_node = cpu_np;
|
||||
|
||||
priv->ssc_id = of_alias_get_id(cpu_np, "ssc");
|
||||
|
||||
|
|
|
@ -294,13 +294,18 @@ static const struct snd_soc_dapm_route tse850_intercon[] = {
|
|||
{ "DAC", NULL, "OUTL" },
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(pcm,
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "pcm512x-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
|
||||
static struct snd_soc_dai_link tse850_dailink = {
|
||||
.name = "TSE-850",
|
||||
.stream_name = "TSE-850-PCM",
|
||||
.codec_dai_name = "pcm512x-hifi",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S
|
||||
| SND_SOC_DAIFMT_NB_NF
|
||||
| SND_SOC_DAIFMT_CBM_CFS,
|
||||
SND_SOC_DAILINK_REG(pcm),
|
||||
};
|
||||
|
||||
static struct snd_soc_card tse850_card = {
|
||||
|
@ -331,8 +336,8 @@ static int tse850_dt_init(struct platform_device *pdev)
|
|||
dev_err(&pdev->dev, "failed to get cpu dai\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dailink->cpu_of_node = cpu_np;
|
||||
dailink->platform_of_node = cpu_np;
|
||||
dailink->cpus->of_node = cpu_np;
|
||||
dailink->platforms->of_node = cpu_np;
|
||||
of_node_put(cpu_np);
|
||||
|
||||
codec_np = of_parse_phandle(np, "axentia,audio-codec", 0);
|
||||
|
@ -340,7 +345,7 @@ static int tse850_dt_init(struct platform_device *pdev)
|
|||
dev_err(&pdev->dev, "failed to get codec info\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
dailink->codec_of_node = codec_np;
|
||||
dailink->codecs->of_node = codec_np;
|
||||
of_node_put(codec_np);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -19,13 +19,15 @@
|
|||
|
||||
#include "psc.h"
|
||||
|
||||
SND_SOC_DAILINK_DEFS(hifi,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("alchemy-ac97c")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("ac97-codec", "ac97-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("alchemy-pcm-dma.0")));
|
||||
|
||||
static struct snd_soc_dai_link db1000_ac97_dai = {
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
.codec_dai_name = "ac97-hifi",
|
||||
.cpu_dai_name = "alchemy-ac97c",
|
||||
.platform_name = "alchemy-pcm-dma.0",
|
||||
.codec_name = "ac97-codec",
|
||||
SND_SOC_DAILINK_REG(hifi),
|
||||
};
|
||||
|
||||
static struct snd_soc_card db1000_ac97 = {
|
||||
|
|
|
@ -47,13 +47,15 @@ static const struct platform_device_id db1200_pids[] = {
|
|||
|
||||
/*------------------------- AC97 PART ---------------------------*/
|
||||
|
||||
SND_SOC_DAILINK_DEFS(db1200_ac97,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("au1xpsc_ac97.1")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("ac97-codec.1", "ac97-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("au1xpsc-pcm.1")));
|
||||
|
||||
static struct snd_soc_dai_link db1200_ac97_dai = {
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
.codec_dai_name = "ac97-hifi",
|
||||
.cpu_dai_name = "au1xpsc_ac97.1",
|
||||
.platform_name = "au1xpsc-pcm.1",
|
||||
.codec_name = "ac97-codec.1",
|
||||
SND_SOC_DAILINK_REG(db1200_ac97),
|
||||
};
|
||||
|
||||
static struct snd_soc_card db1200_ac97_machine = {
|
||||
|
@ -63,13 +65,15 @@ static struct snd_soc_card db1200_ac97_machine = {
|
|||
.num_links = 1,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(db1300_ac97,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("au1xpsc_ac97.1")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec.1", "wm9712-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("au1xpsc-pcm.1")));
|
||||
|
||||
static struct snd_soc_dai_link db1300_ac97_dai = {
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
.codec_dai_name = "wm9712-hifi",
|
||||
.cpu_dai_name = "au1xpsc_ac97.1",
|
||||
.platform_name = "au1xpsc-pcm.1",
|
||||
.codec_name = "wm9712-codec.1",
|
||||
SND_SOC_DAILINK_REG(db1300_ac97),
|
||||
};
|
||||
|
||||
static struct snd_soc_card db1300_ac97_machine = {
|
||||
|
@ -104,16 +108,18 @@ static const struct snd_soc_ops db1200_i2s_wm8731_ops = {
|
|||
.startup = db1200_i2s_startup,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(db1200_i2s,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("au1xpsc_i2s.1")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm8731.0-001b", "wm8731-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("au1xpsc-pcm.1")));
|
||||
|
||||
static struct snd_soc_dai_link db1200_i2s_dai = {
|
||||
.name = "WM8731",
|
||||
.stream_name = "WM8731 PCM",
|
||||
.codec_dai_name = "wm8731-hifi",
|
||||
.cpu_dai_name = "au1xpsc_i2s.1",
|
||||
.platform_name = "au1xpsc-pcm.1",
|
||||
.codec_name = "wm8731.0-001b",
|
||||
.dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM,
|
||||
.ops = &db1200_i2s_wm8731_ops,
|
||||
SND_SOC_DAILINK_REG(db1200_i2s),
|
||||
};
|
||||
|
||||
static struct snd_soc_card db1200_i2s_machine = {
|
||||
|
@ -123,16 +129,18 @@ static struct snd_soc_card db1200_i2s_machine = {
|
|||
.num_links = 1,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(db1300_i2s,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("au1xpsc_i2s.2")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm8731.0-001b", "wm8731-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("au1xpsc-pcm.2")));
|
||||
|
||||
static struct snd_soc_dai_link db1300_i2s_dai = {
|
||||
.name = "WM8731",
|
||||
.stream_name = "WM8731 PCM",
|
||||
.codec_dai_name = "wm8731-hifi",
|
||||
.cpu_dai_name = "au1xpsc_i2s.2",
|
||||
.platform_name = "au1xpsc-pcm.2",
|
||||
.codec_name = "wm8731.0-001b",
|
||||
.dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM,
|
||||
.ops = &db1200_i2s_wm8731_ops,
|
||||
SND_SOC_DAILINK_REG(db1300_i2s),
|
||||
};
|
||||
|
||||
static struct snd_soc_card db1300_i2s_machine = {
|
||||
|
@ -142,16 +150,18 @@ static struct snd_soc_card db1300_i2s_machine = {
|
|||
.num_links = 1,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(db1550_i2s,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("au1xpsc_i2s.3")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("wm8731.0-001b", "wm8731-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("au1xpsc-pcm.3")));
|
||||
|
||||
static struct snd_soc_dai_link db1550_i2s_dai = {
|
||||
.name = "WM8731",
|
||||
.stream_name = "WM8731 PCM",
|
||||
.codec_dai_name = "wm8731-hifi",
|
||||
.cpu_dai_name = "au1xpsc_i2s.3",
|
||||
.platform_name = "au1xpsc-pcm.3",
|
||||
.codec_name = "wm8731.0-001b",
|
||||
.dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM,
|
||||
.ops = &db1200_i2s_wm8731_ops,
|
||||
SND_SOC_DAILINK_REG(db1550_i2s),
|
||||
};
|
||||
|
||||
static struct snd_soc_card db1550_i2s_machine = {
|
||||
|
|
|
@ -340,16 +340,14 @@ static int au1xpsc_i2s_drvprobe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, wd);
|
||||
|
||||
return snd_soc_register_component(&pdev->dev, &au1xpsc_i2s_component,
|
||||
&wd->dai_drv, 1);
|
||||
return devm_snd_soc_register_component(&pdev->dev,
|
||||
&au1xpsc_i2s_component, &wd->dai_drv, 1);
|
||||
}
|
||||
|
||||
static int au1xpsc_i2s_drvremove(struct platform_device *pdev)
|
||||
{
|
||||
struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
|
||||
|
||||
snd_soc_unregister_component(&pdev->dev);
|
||||
|
||||
__raw_writel(0, I2S_CFG(wd));
|
||||
wmb(); /* drain writebuffer */
|
||||
__raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
|
||||
|
|
|
@ -51,16 +51,18 @@ static const struct snd_soc_ops edb93xx_ops = {
|
|||
.hw_params = edb93xx_hw_params,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(hifi,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("ep93xx-i2s")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("spi0.0", "cs4271-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("ep93xx-i2s")));
|
||||
|
||||
static struct snd_soc_dai_link edb93xx_dai = {
|
||||
.name = "CS4271",
|
||||
.stream_name = "CS4271 HiFi",
|
||||
.platform_name = "ep93xx-i2s",
|
||||
.cpu_dai_name = "ep93xx-i2s",
|
||||
.codec_name = "spi0.0",
|
||||
.codec_dai_name = "cs4271-hifi",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
.ops = &edb93xx_ops,
|
||||
SND_SOC_DAILINK_REG(hifi),
|
||||
};
|
||||
|
||||
static struct snd_soc_card snd_soc_edb93xx = {
|
||||
|
|
|
@ -473,19 +473,17 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
|
|||
|
||||
dev_set_drvdata(&pdev->dev, info);
|
||||
|
||||
err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component,
|
||||
err = devm_snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component,
|
||||
&ep93xx_i2s_dai, 1);
|
||||
if (err)
|
||||
goto fail_put_lrclk;
|
||||
|
||||
err = devm_ep93xx_pcm_platform_register(&pdev->dev);
|
||||
if (err)
|
||||
goto fail_unregister;
|
||||
goto fail_put_lrclk;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_unregister:
|
||||
snd_soc_unregister_component(&pdev->dev);
|
||||
fail_put_lrclk:
|
||||
clk_put(info->lrclk);
|
||||
fail_put_sclk:
|
||||
|
@ -500,7 +498,6 @@ static int ep93xx_i2s_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
snd_soc_unregister_component(&pdev->dev);
|
||||
clk_put(info->lrclk);
|
||||
clk_put(info->sclk);
|
||||
clk_put(info->mclk);
|
||||
|
|
|
@ -18,13 +18,15 @@
|
|||
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
SND_SOC_DAILINK_DEFS(hifi,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("ep93xx-ac97")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("ac97-codec", "ac97-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("ep93xx-ac97")));
|
||||
|
||||
static struct snd_soc_dai_link simone_dai = {
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 HiFi",
|
||||
.cpu_dai_name = "ep93xx-ac97",
|
||||
.codec_dai_name = "ac97-hifi",
|
||||
.codec_name = "ac97-codec",
|
||||
.platform_name = "ep93xx-ac97",
|
||||
SND_SOC_DAILINK_REG(hifi),
|
||||
};
|
||||
|
||||
static struct snd_soc_card snd_soc_simone = {
|
||||
|
|
|
@ -60,16 +60,19 @@ static const struct snd_soc_dapm_route audio_map[] = {
|
|||
{"MICIN", NULL, "Mic Jack"},
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(aic23,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("ep93xx-i2s")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic23-codec.0-001a",
|
||||
"tlv320aic23-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("ep93xx-i2s")));
|
||||
|
||||
static struct snd_soc_dai_link snappercl15_dai = {
|
||||
.name = "tlv320aic23",
|
||||
.stream_name = "AIC23",
|
||||
.cpu_dai_name = "ep93xx-i2s",
|
||||
.codec_dai_name = "tlv320aic23-hifi",
|
||||
.codec_name = "tlv320aic23-codec.0-001a",
|
||||
.platform_name = "ep93xx-i2s",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
.ops = &snappercl15_ops,
|
||||
SND_SOC_DAILINK_REG(aic23),
|
||||
};
|
||||
|
||||
static struct snd_soc_card snd_soc_snappercl15 = {
|
||||
|
|
|
@ -71,8 +71,12 @@ config SND_SOC_ALL_CODECS
|
|||
select SND_SOC_CS4341 if SND_SOC_I2C_AND_SPI
|
||||
select SND_SOC_CS4349 if I2C
|
||||
select SND_SOC_CS47L24 if MFD_CS47L24
|
||||
select SND_SOC_CS47L35 if MFD_CS47L35
|
||||
select SND_SOC_CS47L85 if MFD_CS47L85
|
||||
select SND_SOC_CS47L90 if MFD_CS47L90
|
||||
select SND_SOC_CS53L30 if I2C
|
||||
select SND_SOC_CX20442 if TTY
|
||||
select SND_SOC_CX2072X if I2C
|
||||
select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
|
||||
select SND_SOC_DA7213 if I2C
|
||||
select SND_SOC_DA7218 if I2C
|
||||
|
@ -140,7 +144,9 @@ config SND_SOC_ALL_CODECS
|
|||
select SND_SOC_RT274 if I2C
|
||||
select SND_SOC_RT286 if I2C
|
||||
select SND_SOC_RT298 if I2C
|
||||
select SND_SOC_RT1011 if I2C
|
||||
select SND_SOC_RT1305 if I2C
|
||||
select SND_SOC_RT1308 if I2C
|
||||
select SND_SOC_RT5514 if I2C
|
||||
select SND_SOC_RT5616 if I2C
|
||||
select SND_SOC_RT5631 if I2C
|
||||
|
@ -283,10 +289,12 @@ config SND_SOC_WM_HUBS
|
|||
config SND_SOC_WM_ADSP
|
||||
tristate
|
||||
select SND_SOC_COMPRESS
|
||||
default y if SND_SOC_MADERA=y
|
||||
default y if SND_SOC_CS47L24=y
|
||||
default y if SND_SOC_WM5102=y
|
||||
default y if SND_SOC_WM5110=y
|
||||
default y if SND_SOC_WM2200=y
|
||||
default m if SND_SOC_MADERA=m
|
||||
default m if SND_SOC_CS47L24=m
|
||||
default m if SND_SOC_WM5102=m
|
||||
default m if SND_SOC_WM5110=m
|
||||
|
@ -576,6 +584,15 @@ config SND_SOC_CS4349
|
|||
config SND_SOC_CS47L24
|
||||
tristate
|
||||
|
||||
config SND_SOC_CS47L35
|
||||
tristate
|
||||
|
||||
config SND_SOC_CS47L85
|
||||
tristate
|
||||
|
||||
config SND_SOC_CS47L90
|
||||
tristate
|
||||
|
||||
# Cirrus Logic Quad-Channel ADC
|
||||
config SND_SOC_CS53L30
|
||||
tristate "Cirrus Logic CS53L30 CODEC"
|
||||
|
@ -585,6 +602,12 @@ config SND_SOC_CX20442
|
|||
tristate
|
||||
depends on TTY
|
||||
|
||||
config SND_SOC_CX2072X
|
||||
tristate "Conexant CX2072X CODEC"
|
||||
depends on I2C
|
||||
help
|
||||
Enable support for Conexant CX20721 and CX20723 codec chips.
|
||||
|
||||
config SND_SOC_JZ4740_CODEC
|
||||
depends on MIPS || COMPILE_TEST
|
||||
select REGMAP_MMIO
|
||||
|
@ -697,6 +720,15 @@ config SND_SOC_LOCHNAGAR_SC
|
|||
This driver support the sound card functionality of the Cirrus
|
||||
Logic Lochnagar audio development board.
|
||||
|
||||
config SND_SOC_MADERA
|
||||
tristate
|
||||
default y if SND_SOC_CS47L35=y
|
||||
default y if SND_SOC_CS47L85=y
|
||||
default y if SND_SOC_CS47L90=y
|
||||
default m if SND_SOC_CS47L35=m
|
||||
default m if SND_SOC_CS47L85=m
|
||||
default m if SND_SOC_CS47L90=m
|
||||
|
||||
config SND_SOC_MAX98088
|
||||
tristate "Maxim MAX98088/9 Low-Power, Stereo Audio Codec"
|
||||
depends on I2C
|
||||
|
@ -708,7 +740,8 @@ config SND_SOC_MAX98095
|
|||
tristate
|
||||
|
||||
config SND_SOC_MAX98357A
|
||||
tristate
|
||||
tristate "Maxim MAX98357A CODEC"
|
||||
depends on GPIOLIB
|
||||
|
||||
config SND_SOC_MAX98371
|
||||
tristate
|
||||
|
@ -870,7 +903,9 @@ config SND_SOC_RL6231
|
|||
default y if SND_SOC_RT5670=y
|
||||
default y if SND_SOC_RT5677=y
|
||||
default y if SND_SOC_RT5682=y
|
||||
default y if SND_SOC_RT1011=y
|
||||
default y if SND_SOC_RT1305=y
|
||||
default y if SND_SOC_RT1308=y
|
||||
default m if SND_SOC_RT5514=m
|
||||
default m if SND_SOC_RT5616=m
|
||||
default m if SND_SOC_RT5640=m
|
||||
|
@ -884,7 +919,9 @@ config SND_SOC_RL6231
|
|||
default m if SND_SOC_RT5670=m
|
||||
default m if SND_SOC_RT5677=m
|
||||
default m if SND_SOC_RT5682=m
|
||||
default m if SND_SOC_RT1011=m
|
||||
default m if SND_SOC_RT1305=m
|
||||
default m if SND_SOC_RT1308=m
|
||||
|
||||
config SND_SOC_RL6347A
|
||||
tristate
|
||||
|
@ -907,9 +944,15 @@ config SND_SOC_RT298
|
|||
tristate
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_RT1011
|
||||
tristate
|
||||
|
||||
config SND_SOC_RT1305
|
||||
tristate
|
||||
|
||||
config SND_SOC_RT1308
|
||||
tristate
|
||||
|
||||
config SND_SOC_RT5514
|
||||
tristate
|
||||
|
||||
|
|
|
@ -65,8 +65,12 @@ snd-soc-cs43130-objs := cs43130.o
|
|||
snd-soc-cs4341-objs := cs4341.o
|
||||
snd-soc-cs4349-objs := cs4349.o
|
||||
snd-soc-cs47l24-objs := cs47l24.o
|
||||
snd-soc-cs47l35-objs := cs47l35.o
|
||||
snd-soc-cs47l85-objs := cs47l85.o
|
||||
snd-soc-cs47l90-objs := cs47l90.o
|
||||
snd-soc-cs53l30-objs := cs53l30.o
|
||||
snd-soc-cx20442-objs := cx20442.o
|
||||
snd-soc-cx2072x-objs := cx2072x.o
|
||||
snd-soc-da7210-objs := da7210.o
|
||||
snd-soc-da7213-objs := da7213.o
|
||||
snd-soc-da7218-objs := da7218.o
|
||||
|
@ -92,6 +96,7 @@ snd-soc-l3-objs := l3.o
|
|||
snd-soc-lm4857-objs := lm4857.o
|
||||
snd-soc-lm49453-objs := lm49453.o
|
||||
snd-soc-lochnagar-sc-objs := lochnagar-sc.o
|
||||
snd-soc-madera-objs := madera.o
|
||||
snd-soc-max9759-objs := max9759.o
|
||||
snd-soc-max9768-objs := max9768.o
|
||||
snd-soc-max98088-objs := max98088.o
|
||||
|
@ -141,7 +146,9 @@ snd-soc-pcm512x-spi-objs := pcm512x-spi.o
|
|||
snd-soc-rk3328-objs := rk3328_codec.o
|
||||
snd-soc-rl6231-objs := rl6231.o
|
||||
snd-soc-rl6347a-objs := rl6347a.o
|
||||
snd-soc-rt1011-objs := rt1011.o
|
||||
snd-soc-rt1305-objs := rt1305.o
|
||||
snd-soc-rt1308-objs := rt1308.o
|
||||
snd-soc-rt274-objs := rt274.o
|
||||
snd-soc-rt286-objs := rt286.o
|
||||
snd-soc-rt298-objs := rt298.o
|
||||
|
@ -339,8 +346,12 @@ obj-$(CONFIG_SND_SOC_CS43130) += snd-soc-cs43130.o
|
|||
obj-$(CONFIG_SND_SOC_CS4341) += snd-soc-cs4341.o
|
||||
obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o
|
||||
obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o
|
||||
obj-$(CONFIG_SND_SOC_CS47L35) += snd-soc-cs47l35.o
|
||||
obj-$(CONFIG_SND_SOC_CS47L85) += snd-soc-cs47l85.o
|
||||
obj-$(CONFIG_SND_SOC_CS47L90) += snd-soc-cs47l90.o
|
||||
obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o
|
||||
obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
|
||||
obj-$(CONFIG_SND_SOC_CX2072X) += snd-soc-cx2072x.o
|
||||
obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
|
||||
obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
|
||||
obj-$(CONFIG_SND_SOC_DA7218) += snd-soc-da7218.o
|
||||
|
@ -366,6 +377,7 @@ obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
|
|||
obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
|
||||
obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o
|
||||
obj-$(CONFIG_SND_SOC_LOCHNAGAR_SC) += snd-soc-lochnagar-sc.o
|
||||
obj-$(CONFIG_SND_SOC_MADERA) += snd-soc-madera.o
|
||||
obj-$(CONFIG_SND_SOC_MAX9759) += snd-soc-max9759.o
|
||||
obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o
|
||||
obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
|
||||
|
@ -415,7 +427,9 @@ obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
|
|||
obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o
|
||||
obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
|
||||
obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o
|
||||
obj-$(CONFIG_SND_SOC_RT1011) += snd-soc-rt1011.o
|
||||
obj-$(CONFIG_SND_SOC_RT1305) += snd-soc-rt1305.o
|
||||
obj-$(CONFIG_SND_SOC_RT1308) += snd-soc-rt1308.o
|
||||
obj-$(CONFIG_SND_SOC_RT274) += snd-soc-rt274.o
|
||||
obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
|
||||
obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o
|
||||
|
|
|
@ -413,6 +413,48 @@ static struct snd_soc_dai_driver ad193x_no_adc_dai = {
|
|||
.ops = &ad193x_dai_ops,
|
||||
};
|
||||
|
||||
struct ad193x_reg_default {
|
||||
unsigned int reg;
|
||||
unsigned int val;
|
||||
};
|
||||
|
||||
/* codec register values to set after reset */
|
||||
static void ad193x_reg_default_init(struct ad193x_priv *ad193x)
|
||||
{
|
||||
const struct ad193x_reg_default reg_init[] = {
|
||||
{ 0, 0x99 }, /* PLL_CLK_CTRL0: pll input: mclki/xi 12.288Mhz */
|
||||
{ 1, 0x04 }, /* PLL_CLK_CTRL1: no on-chip Vref */
|
||||
{ 2, 0x40 }, /* DAC_CTRL0: TDM mode */
|
||||
{ 3, 0x00 }, /* DAC_CTRL1: reset */
|
||||
{ 4, 0x1A }, /* DAC_CTRL2: 48kHz de-emphasis, unmute dac */
|
||||
{ 5, 0x00 }, /* DAC_CHNL_MUTE: unmute DAC channels */
|
||||
{ 6, 0x00 }, /* DAC_L1_VOL: no attenuation */
|
||||
{ 7, 0x00 }, /* DAC_R1_VOL: no attenuation */
|
||||
{ 8, 0x00 }, /* DAC_L2_VOL: no attenuation */
|
||||
{ 9, 0x00 }, /* DAC_R2_VOL: no attenuation */
|
||||
{ 10, 0x00 }, /* DAC_L3_VOL: no attenuation */
|
||||
{ 11, 0x00 }, /* DAC_R3_VOL: no attenuation */
|
||||
{ 12, 0x00 }, /* DAC_L4_VOL: no attenuation */
|
||||
{ 13, 0x00 }, /* DAC_R4_VOL: no attenuation */
|
||||
};
|
||||
const struct ad193x_reg_default reg_adc_init[] = {
|
||||
{ 14, 0x03 }, /* ADC_CTRL0: high-pass filter enable */
|
||||
{ 15, 0x43 }, /* ADC_CTRL1: sata delay=1, adc aux mode */
|
||||
{ 16, 0x00 }, /* ADC_CTRL2: reset */
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(reg_init); i++)
|
||||
regmap_write(ad193x->regmap, reg_init[i].reg, reg_init[i].val);
|
||||
|
||||
if (ad193x_has_adc(ad193x)) {
|
||||
for (i = 0; i < ARRAY_SIZE(reg_adc_init); i++) {
|
||||
regmap_write(ad193x->regmap, reg_adc_init[i].reg,
|
||||
reg_adc_init[i].val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int ad193x_component_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
|
||||
|
@ -420,25 +462,7 @@ static int ad193x_component_probe(struct snd_soc_component *component)
|
|||
int num, ret;
|
||||
|
||||
/* default setting for ad193x */
|
||||
|
||||
/* unmute dac channels */
|
||||
regmap_write(ad193x->regmap, AD193X_DAC_CHNL_MUTE, 0x0);
|
||||
/* de-emphasis: 48kHz, powedown dac */
|
||||
regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A);
|
||||
/* dac in tdm mode */
|
||||
regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x40);
|
||||
|
||||
/* adc only */
|
||||
if (ad193x_has_adc(ad193x)) {
|
||||
/* high-pass filter enable */
|
||||
regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3);
|
||||
/* sata delay=1, adc aux mode */
|
||||
regmap_write(ad193x->regmap, AD193X_ADC_CTRL1, 0x43);
|
||||
}
|
||||
|
||||
/* pll input: mclki/xi */
|
||||
regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
|
||||
regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04);
|
||||
ad193x_reg_default_init(ad193x);
|
||||
|
||||
/* adc only */
|
||||
if (ad193x_has_adc(ad193x)) {
|
||||
|
|
|
@ -400,14 +400,8 @@ static int ak4118_i2c_probe(struct i2c_client *i2c,
|
|||
return ret;
|
||||
}
|
||||
|
||||
return snd_soc_register_component(&i2c->dev, &soc_component_drv_ak4118,
|
||||
&ak4118_dai, 1);
|
||||
}
|
||||
|
||||
static int ak4118_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
snd_soc_unregister_component(&i2c->dev);
|
||||
return 0;
|
||||
return devm_snd_soc_register_component(&i2c->dev,
|
||||
&soc_component_drv_ak4118, &ak4118_dai, 1);
|
||||
}
|
||||
|
||||
static const struct of_device_id ak4118_of_match[] = {
|
||||
|
@ -429,7 +423,6 @@ static struct i2c_driver ak4118_i2c_driver = {
|
|||
},
|
||||
.id_table = ak4118_id_table,
|
||||
.probe = ak4118_i2c_probe,
|
||||
.remove = ak4118_i2c_remove,
|
||||
};
|
||||
|
||||
module_i2c_driver(ak4118_i2c_driver);
|
||||
|
|
|
@ -413,7 +413,7 @@ static int cros_ec_codec_platform_probe(struct platform_device *pd)
|
|||
|
||||
platform_set_drvdata(pd, codec_data);
|
||||
|
||||
return snd_soc_register_component(dev, &cros_ec_component_driver,
|
||||
return devm_snd_soc_register_component(dev, &cros_ec_component_driver,
|
||||
cros_ec_dai, ARRAY_SIZE(cros_ec_dai));
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <sound/pcm_params.h>
|
||||
|
@ -45,6 +46,7 @@ struct cs42xx8_priv {
|
|||
bool slave_mode;
|
||||
unsigned long sysclk;
|
||||
u32 tx_channels;
|
||||
struct gpio_desc *gpiod_reset;
|
||||
};
|
||||
|
||||
/* -127.5dB to 0dB with step of 0.5dB */
|
||||
|
@ -467,6 +469,13 @@ int cs42xx8_probe(struct device *dev, struct regmap *regmap)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
cs42xx8->gpiod_reset = devm_gpiod_get_optional(dev, "reset",
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(cs42xx8->gpiod_reset))
|
||||
return PTR_ERR(cs42xx8->gpiod_reset);
|
||||
|
||||
gpiod_set_value_cansleep(cs42xx8->gpiod_reset, 0);
|
||||
|
||||
cs42xx8->clk = devm_clk_get(dev, "mclk");
|
||||
if (IS_ERR(cs42xx8->clk)) {
|
||||
dev_err(dev, "failed to get the clock: %ld\n",
|
||||
|
@ -547,6 +556,8 @@ static int cs42xx8_runtime_resume(struct device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(cs42xx8->gpiod_reset, 0);
|
||||
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies),
|
||||
cs42xx8->supplies);
|
||||
if (ret) {
|
||||
|
@ -586,6 +597,8 @@ static int cs42xx8_runtime_suspend(struct device *dev)
|
|||
regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
|
||||
cs42xx8->supplies);
|
||||
|
||||
gpiod_set_value_cansleep(cs42xx8->gpiod_reset, 1);
|
||||
|
||||
clk_disable_unprepare(cs42xx8->clk);
|
||||
|
||||
return 0;
|
||||
|
|
1777
sound/soc/codecs/cs47l35.c
Normal file
1777
sound/soc/codecs/cs47l35.c
Normal file
File diff suppressed because it is too large
Load diff
2730
sound/soc/codecs/cs47l85.c
Normal file
2730
sound/soc/codecs/cs47l85.c
Normal file
File diff suppressed because it is too large
Load diff
2653
sound/soc/codecs/cs47l90.c
Normal file
2653
sound/soc/codecs/cs47l90.c
Normal file
File diff suppressed because it is too large
Load diff
1725
sound/soc/codecs/cx2072x.c
Normal file
1725
sound/soc/codecs/cx2072x.c
Normal file
File diff suppressed because it is too large
Load diff
314
sound/soc/codecs/cx2072x.h
Normal file
314
sound/soc/codecs/cx2072x.h
Normal file
|
@ -0,0 +1,314 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* ALSA SoC CX20721/CX20723 codec driver
|
||||
*
|
||||
* Copyright: (C) 2017 Conexant Systems, Inc.
|
||||
* Author: Simon Ho, <Simon.ho@conexant.com>
|
||||
*/
|
||||
|
||||
#ifndef __CX2072X_H__
|
||||
#define __CX2072X_H__
|
||||
|
||||
#define CX2072X_MCLK_PLL 1
|
||||
#define CX2072X_MCLK_EXTERNAL_PLL 1
|
||||
#define CX2072X_MCLK_INTERNAL_OSC 2
|
||||
|
||||
/*#define CX2072X_RATES SNDRV_PCM_RATE_8000_192000*/
|
||||
#define CX2072X_RATES_DSP SNDRV_PCM_RATE_48000
|
||||
|
||||
#define CX2072X_REG_MAX 0x8a3c
|
||||
|
||||
#define CX2072X_VENDOR_ID 0x0200
|
||||
#define CX2072X_REVISION_ID 0x0208
|
||||
#define CX2072X_CURRENT_BCLK_FREQUENCY 0x00dc
|
||||
#define CX2072X_AFG_POWER_STATE 0x0414
|
||||
#define CX2072X_UM_RESPONSE 0x0420
|
||||
#define CX2072X_GPIO_DATA 0x0454
|
||||
#define CX2072X_GPIO_ENABLE 0x0458
|
||||
#define CX2072X_GPIO_DIRECTION 0x045c
|
||||
#define CX2072X_GPIO_WAKE 0x0460
|
||||
#define CX2072X_GPIO_UM_ENABLE 0x0464
|
||||
#define CX2072X_GPIO_STICKY_MASK 0x0468
|
||||
#define CX2072X_AFG_FUNCTION_RESET 0x07fc
|
||||
#define CX2072X_DAC1_CONVERTER_FORMAT 0x43c8
|
||||
#define CX2072X_DAC1_AMP_GAIN_RIGHT 0x41c0
|
||||
#define CX2072X_DAC1_AMP_GAIN_LEFT 0x41e0
|
||||
#define CX2072X_DAC1_POWER_STATE 0x4014
|
||||
#define CX2072X_DAC1_CONVERTER_STREAM_CHANNEL 0x4018
|
||||
#define CX2072X_DAC1_EAPD_ENABLE 0x4030
|
||||
#define CX2072X_DAC2_CONVERTER_FORMAT 0x47c8
|
||||
#define CX2072X_DAC2_AMP_GAIN_RIGHT 0x45c0
|
||||
#define CX2072X_DAC2_AMP_GAIN_LEFT 0x45e0
|
||||
#define CX2072X_DAC2_POWER_STATE 0x4414
|
||||
#define CX2072X_DAC2_CONVERTER_STREAM_CHANNEL 0x4418
|
||||
#define CX2072X_ADC1_CONVERTER_FORMAT 0x4fc8
|
||||
#define CX2072X_ADC1_AMP_GAIN_RIGHT_0 0x4d80
|
||||
#define CX2072X_ADC1_AMP_GAIN_LEFT_0 0x4da0
|
||||
#define CX2072X_ADC1_AMP_GAIN_RIGHT_1 0x4d84
|
||||
#define CX2072X_ADC1_AMP_GAIN_LEFT_1 0x4da4
|
||||
#define CX2072X_ADC1_AMP_GAIN_RIGHT_2 0x4d88
|
||||
#define CX2072X_ADC1_AMP_GAIN_LEFT_2 0x4da8
|
||||
#define CX2072X_ADC1_AMP_GAIN_RIGHT_3 0x4d8c
|
||||
#define CX2072X_ADC1_AMP_GAIN_LEFT_3 0x4dac
|
||||
#define CX2072X_ADC1_AMP_GAIN_RIGHT_4 0x4d90
|
||||
#define CX2072X_ADC1_AMP_GAIN_LEFT_4 0x4db0
|
||||
#define CX2072X_ADC1_AMP_GAIN_RIGHT_5 0x4d94
|
||||
#define CX2072X_ADC1_AMP_GAIN_LEFT_5 0x4db4
|
||||
#define CX2072X_ADC1_AMP_GAIN_RIGHT_6 0x4d98
|
||||
#define CX2072X_ADC1_AMP_GAIN_LEFT_6 0x4db8
|
||||
#define CX2072X_ADC1_CONNECTION_SELECT_CONTROL 0x4c04
|
||||
#define CX2072X_ADC1_POWER_STATE 0x4c14
|
||||
#define CX2072X_ADC1_CONVERTER_STREAM_CHANNEL 0x4c18
|
||||
#define CX2072X_ADC2_CONVERTER_FORMAT 0x53c8
|
||||
#define CX2072X_ADC2_AMP_GAIN_RIGHT_0 0x5180
|
||||
#define CX2072X_ADC2_AMP_GAIN_LEFT_0 0x51a0
|
||||
#define CX2072X_ADC2_AMP_GAIN_RIGHT_1 0x5184
|
||||
#define CX2072X_ADC2_AMP_GAIN_LEFT_1 0x51a4
|
||||
#define CX2072X_ADC2_AMP_GAIN_RIGHT_2 0x5188
|
||||
#define CX2072X_ADC2_AMP_GAIN_LEFT_2 0x51a8
|
||||
#define CX2072X_ADC2_CONNECTION_SELECT_CONTROL 0x5004
|
||||
#define CX2072X_ADC2_POWER_STATE 0x5014
|
||||
#define CX2072X_ADC2_CONVERTER_STREAM_CHANNEL 0x5018
|
||||
#define CX2072X_PORTA_CONNECTION_SELECT_CTRL 0x5804
|
||||
#define CX2072X_PORTA_POWER_STATE 0x5814
|
||||
#define CX2072X_PORTA_PIN_CTRL 0x581c
|
||||
#define CX2072X_PORTA_UNSOLICITED_RESPONSE 0x5820
|
||||
#define CX2072X_PORTA_PIN_SENSE 0x5824
|
||||
#define CX2072X_PORTA_EAPD_BTL 0x5830
|
||||
#define CX2072X_PORTB_POWER_STATE 0x6014
|
||||
#define CX2072X_PORTB_PIN_CTRL 0x601c
|
||||
#define CX2072X_PORTB_UNSOLICITED_RESPONSE 0x6020
|
||||
#define CX2072X_PORTB_PIN_SENSE 0x6024
|
||||
#define CX2072X_PORTB_EAPD_BTL 0x6030
|
||||
#define CX2072X_PORTB_GAIN_RIGHT 0x6180
|
||||
#define CX2072X_PORTB_GAIN_LEFT 0x61a0
|
||||
#define CX2072X_PORTC_POWER_STATE 0x6814
|
||||
#define CX2072X_PORTC_PIN_CTRL 0x681c
|
||||
#define CX2072X_PORTC_GAIN_RIGHT 0x6980
|
||||
#define CX2072X_PORTC_GAIN_LEFT 0x69a0
|
||||
#define CX2072X_PORTD_POWER_STATE 0x6414
|
||||
#define CX2072X_PORTD_PIN_CTRL 0x641c
|
||||
#define CX2072X_PORTD_UNSOLICITED_RESPONSE 0x6420
|
||||
#define CX2072X_PORTD_PIN_SENSE 0x6424
|
||||
#define CX2072X_PORTD_GAIN_RIGHT 0x6580
|
||||
#define CX2072X_PORTD_GAIN_LEFT 0x65a0
|
||||
#define CX2072X_PORTE_CONNECTION_SELECT_CTRL 0x7404
|
||||
#define CX2072X_PORTE_POWER_STATE 0x7414
|
||||
#define CX2072X_PORTE_PIN_CTRL 0x741c
|
||||
#define CX2072X_PORTE_UNSOLICITED_RESPONSE 0x7420
|
||||
#define CX2072X_PORTE_PIN_SENSE 0x7424
|
||||
#define CX2072X_PORTE_EAPD_BTL 0x7430
|
||||
#define CX2072X_PORTE_GAIN_RIGHT 0x7580
|
||||
#define CX2072X_PORTE_GAIN_LEFT 0x75a0
|
||||
#define CX2072X_PORTF_POWER_STATE 0x7814
|
||||
#define CX2072X_PORTF_PIN_CTRL 0x781c
|
||||
#define CX2072X_PORTF_UNSOLICITED_RESPONSE 0x7820
|
||||
#define CX2072X_PORTF_PIN_SENSE 0x7824
|
||||
#define CX2072X_PORTF_GAIN_RIGHT 0x7980
|
||||
#define CX2072X_PORTF_GAIN_LEFT 0x79a0
|
||||
#define CX2072X_PORTG_POWER_STATE 0x5c14
|
||||
#define CX2072X_PORTG_PIN_CTRL 0x5c1c
|
||||
#define CX2072X_PORTG_CONNECTION_SELECT_CTRL 0x5c04
|
||||
#define CX2072X_PORTG_EAPD_BTL 0x5c30
|
||||
#define CX2072X_PORTM_POWER_STATE 0x8814
|
||||
#define CX2072X_PORTM_PIN_CTRL 0x881c
|
||||
#define CX2072X_PORTM_CONNECTION_SELECT_CTRL 0x8804
|
||||
#define CX2072X_PORTM_EAPD_BTL 0x8830
|
||||
#define CX2072X_MIXER_POWER_STATE 0x5414
|
||||
#define CX2072X_MIXER_GAIN_RIGHT_0 0x5580
|
||||
#define CX2072X_MIXER_GAIN_LEFT_0 0x55a0
|
||||
#define CX2072X_MIXER_GAIN_RIGHT_1 0x5584
|
||||
#define CX2072X_MIXER_GAIN_LEFT_1 0x55a4
|
||||
#define CX2072X_EQ_ENABLE_BYPASS 0x6d00
|
||||
#define CX2072X_EQ_B0_COEFF 0x6d02
|
||||
#define CX2072X_EQ_B1_COEFF 0x6d04
|
||||
#define CX2072X_EQ_B2_COEFF 0x6d06
|
||||
#define CX2072X_EQ_A1_COEFF 0x6d08
|
||||
#define CX2072X_EQ_A2_COEFF 0x6d0a
|
||||
#define CX2072X_EQ_G_COEFF 0x6d0c
|
||||
#define CX2072X_EQ_BAND 0x6d0d
|
||||
#define CX2072X_SPKR_DRC_ENABLE_STEP 0x6d10
|
||||
#define CX2072X_SPKR_DRC_CONTROL 0x6d14
|
||||
#define CX2072X_SPKR_DRC_TEST 0x6d18
|
||||
#define CX2072X_DIGITAL_BIOS_TEST0 0x6d80
|
||||
#define CX2072X_DIGITAL_BIOS_TEST2 0x6d84
|
||||
#define CX2072X_I2SPCM_CONTROL1 0x6e00
|
||||
#define CX2072X_I2SPCM_CONTROL2 0x6e04
|
||||
#define CX2072X_I2SPCM_CONTROL3 0x6e08
|
||||
#define CX2072X_I2SPCM_CONTROL4 0x6e0c
|
||||
#define CX2072X_I2SPCM_CONTROL5 0x6e10
|
||||
#define CX2072X_I2SPCM_CONTROL6 0x6e18
|
||||
#define CX2072X_UM_INTERRUPT_CRTL_E 0x6e14
|
||||
#define CX2072X_CODEC_TEST2 0x7108
|
||||
#define CX2072X_CODEC_TEST9 0x7124
|
||||
#define CX2072X_CODEC_TESTXX 0x7290
|
||||
#define CX2072X_CODEC_TEST20 0x7310
|
||||
#define CX2072X_CODEC_TEST24 0x731c
|
||||
#define CX2072X_CODEC_TEST26 0x7328
|
||||
#define CX2072X_ANALOG_TEST3 0x718c
|
||||
#define CX2072X_ANALOG_TEST4 0x7190
|
||||
#define CX2072X_ANALOG_TEST5 0x7194
|
||||
#define CX2072X_ANALOG_TEST6 0x7198
|
||||
#define CX2072X_ANALOG_TEST7 0x719c
|
||||
#define CX2072X_ANALOG_TEST8 0x71a0
|
||||
#define CX2072X_ANALOG_TEST9 0x71a4
|
||||
#define CX2072X_ANALOG_TEST10 0x71a8
|
||||
#define CX2072X_ANALOG_TEST11 0x71ac
|
||||
#define CX2072X_ANALOG_TEST12 0x71b0
|
||||
#define CX2072X_ANALOG_TEST13 0x71b4
|
||||
#define CX2072X_DIGITAL_TEST0 0x7200
|
||||
#define CX2072X_DIGITAL_TEST1 0x7204
|
||||
#define CX2072X_DIGITAL_TEST11 0x722c
|
||||
#define CX2072X_DIGITAL_TEST12 0x7230
|
||||
#define CX2072X_DIGITAL_TEST15 0x723c
|
||||
#define CX2072X_DIGITAL_TEST16 0x7080
|
||||
#define CX2072X_DIGITAL_TEST17 0x7084
|
||||
#define CX2072X_DIGITAL_TEST18 0x7088
|
||||
#define CX2072X_DIGITAL_TEST19 0x708c
|
||||
#define CX2072X_DIGITAL_TEST20 0x7090
|
||||
|
||||
/* not used in the current code, for future extensions (if any) */
|
||||
#define CX2072X_MAX_EQ_BAND 7
|
||||
#define CX2072X_MAX_EQ_COEFF 11
|
||||
#define CX2072X_MAX_DRC_REGS 9
|
||||
#define CX2072X_MIC_EQ_COEFF 10
|
||||
#define CX2072X_PLBK_EQ_BAND_NUM 7
|
||||
#define CX2072X_PLBK_EQ_COEF_LEN 11
|
||||
#define CX2072X_PLBK_DRC_PARM_LEN 9
|
||||
#define CX2072X_CLASSD_AMP_LEN 6
|
||||
|
||||
/* DAI interfae type */
|
||||
#define CX2072X_DAI_HIFI 1
|
||||
#define CX2072X_DAI_DSP 2
|
||||
#define CX2072X_DAI_DSP_PWM 3 /* 4 ch, including mic and AEC */
|
||||
|
||||
enum cx2072x_reg_sample_size {
|
||||
CX2072X_SAMPLE_SIZE_8_BITS = 0,
|
||||
CX2072X_SAMPLE_SIZE_16_BITS = 1,
|
||||
CX2072X_SAMPLE_SIZE_24_BITS = 2,
|
||||
CX2072X_SAMPLE_SIZE_RESERVED = 3,
|
||||
};
|
||||
|
||||
union cx2072x_reg_i2spcm_ctrl_reg1 {
|
||||
struct {
|
||||
u32 rx_data_one_line:1;
|
||||
u32 rx_ws_pol:1;
|
||||
u32 rx_ws_wid:7;
|
||||
u32 rx_frm_len:5;
|
||||
u32 rx_sa_size:2;
|
||||
u32 tx_data_one_line:1;
|
||||
u32 tx_ws_pol:1;
|
||||
u32 tx_ws_wid:7;
|
||||
u32 tx_frm_len:5;
|
||||
u32 tx_sa_size:2;
|
||||
} r;
|
||||
u32 ulval;
|
||||
};
|
||||
|
||||
union cx2072x_reg_i2spcm_ctrl_reg2 {
|
||||
struct {
|
||||
u32 tx_en_ch1:1;
|
||||
u32 tx_en_ch2:1;
|
||||
u32 tx_en_ch3:1;
|
||||
u32 tx_en_ch4:1;
|
||||
u32 tx_en_ch5:1;
|
||||
u32 tx_en_ch6:1;
|
||||
u32 tx_slot_1:5;
|
||||
u32 tx_slot_2:5;
|
||||
u32 tx_slot_3:5;
|
||||
u32 tx_slot_4:5;
|
||||
u32 res:1;
|
||||
u32 tx_data_neg_bclk:1;
|
||||
u32 tx_master:1;
|
||||
u32 tx_tri_n:1;
|
||||
u32 tx_endian_sel:1;
|
||||
u32 tx_dstart_dly:1;
|
||||
} r;
|
||||
u32 ulval;
|
||||
};
|
||||
|
||||
union cx2072x_reg_i2spcm_ctrl_reg3 {
|
||||
struct {
|
||||
u32 rx_en_ch1:1;
|
||||
u32 rx_en_ch2:1;
|
||||
u32 rx_en_ch3:1;
|
||||
u32 rx_en_ch4:1;
|
||||
u32 rx_en_ch5:1;
|
||||
u32 rx_en_ch6:1;
|
||||
u32 rx_slot_1:5;
|
||||
u32 rx_slot_2:5;
|
||||
u32 rx_slot_3:5;
|
||||
u32 rx_slot_4:5;
|
||||
u32 res:1;
|
||||
u32 rx_data_neg_bclk:1;
|
||||
u32 rx_master:1;
|
||||
u32 rx_tri_n:1;
|
||||
u32 rx_endian_sel:1;
|
||||
u32 rx_dstart_dly:1;
|
||||
} r;
|
||||
u32 ulval;
|
||||
};
|
||||
|
||||
union cx2072x_reg_i2spcm_ctrl_reg4 {
|
||||
struct {
|
||||
u32 rx_mute:1;
|
||||
u32 tx_mute:1;
|
||||
u32 reserved:1;
|
||||
u32 dac_34_independent:1;
|
||||
u32 dac_bclk_lrck_share:1;
|
||||
u32 bclk_lrck_share_en:1;
|
||||
u32 reserved2:2;
|
||||
u32 rx_last_dac_ch_en:1;
|
||||
u32 rx_last_dac_ch:3;
|
||||
u32 tx_last_adc_ch_en:1;
|
||||
u32 tx_last_adc_ch:3;
|
||||
u32 rx_slot_5:5;
|
||||
u32 rx_slot_6:5;
|
||||
u32 reserved3:6;
|
||||
} r;
|
||||
u32 ulval;
|
||||
};
|
||||
|
||||
union cx2072x_reg_i2spcm_ctrl_reg5 {
|
||||
struct {
|
||||
u32 tx_slot_5:5;
|
||||
u32 reserved:3;
|
||||
u32 tx_slot_6:5;
|
||||
u32 reserved2:3;
|
||||
u32 reserved3:8;
|
||||
u32 i2s_pcm_clk_div:7;
|
||||
u32 i2s_pcm_clk_div_chan_en:1;
|
||||
} r;
|
||||
u32 ulval;
|
||||
};
|
||||
|
||||
union cx2072x_reg_i2spcm_ctrl_reg6 {
|
||||
struct {
|
||||
u32 reserved:5;
|
||||
u32 rx_pause_cycles:3;
|
||||
u32 rx_pause_start_pos:8;
|
||||
u32 reserved2:5;
|
||||
u32 tx_pause_cycles:3;
|
||||
u32 tx_pause_start_pos:8;
|
||||
} r;
|
||||
u32 ulval;
|
||||
};
|
||||
|
||||
union cx2072x_reg_digital_bios_test2 {
|
||||
struct {
|
||||
u32 pull_down_eapd:2;
|
||||
u32 input_en_eapd_pad:1;
|
||||
u32 push_pull_mode:1;
|
||||
u32 eapd_pad_output_driver:2;
|
||||
u32 pll_source:1;
|
||||
u32 i2s_bclk_en:1;
|
||||
u32 i2s_bclk_invert:1;
|
||||
u32 pll_ref_clock:1;
|
||||
u32 class_d_shield_clk:1;
|
||||
u32 audio_pll_bypass_mode:1;
|
||||
u32 reserved:4;
|
||||
} r;
|
||||
u32 ulval;
|
||||
};
|
||||
|
||||
#endif /* __CX2072X_H__ */
|
|
@ -1890,6 +1890,12 @@ static void hdmi_codec_remove(struct snd_soc_component *component)
|
|||
{
|
||||
struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component);
|
||||
struct hdac_device *hdev = hdmi->hdev;
|
||||
int ret;
|
||||
|
||||
ret = snd_hdac_acomp_register_notifier(hdev->bus, NULL);
|
||||
if (ret < 0)
|
||||
dev_err(&hdev->dev, "notifier unregister failed: err: %d\n",
|
||||
ret);
|
||||
|
||||
pm_runtime_disable(&hdev->dev);
|
||||
}
|
||||
|
@ -2113,6 +2119,7 @@ static int hdac_hdmi_runtime_suspend(struct device *dev)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
snd_hdac_codec_link_down(hdev);
|
||||
snd_hdac_ext_bus_link_put(bus, hlink);
|
||||
|
||||
snd_hdac_display_power(bus, hdev->addr, false);
|
||||
|
@ -2139,6 +2146,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev)
|
|||
}
|
||||
|
||||
snd_hdac_ext_bus_link_get(bus, hlink);
|
||||
snd_hdac_codec_link_up(hdev);
|
||||
|
||||
snd_hdac_display_power(bus, hdev->addr, true);
|
||||
|
||||
|
|
|
@ -270,13 +270,10 @@ static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
|
|||
|
||||
struct hdmi_codec_priv {
|
||||
struct hdmi_codec_pdata hcd;
|
||||
struct snd_soc_dai_driver *daidrv;
|
||||
struct hdmi_codec_daifmt daifmt[2];
|
||||
struct mutex current_stream_lock;
|
||||
struct snd_pcm_substream *current_stream;
|
||||
uint8_t eld[MAX_ELD_BYTES];
|
||||
struct snd_pcm_chmap *chmap_info;
|
||||
unsigned int chmap_idx;
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget hdmi_widgets[] = {
|
||||
|
@ -384,44 +381,22 @@ static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_codec_new_stream(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&hcp->current_stream_lock);
|
||||
if (!hcp->current_stream) {
|
||||
hcp->current_stream = substream;
|
||||
} else if (hcp->current_stream != substream) {
|
||||
dev_err(dai->dev, "Only one simultaneous stream supported!\n");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
mutex_unlock(&hcp->current_stream_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hdmi_codec_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
|
||||
int ret = 0;
|
||||
|
||||
dev_dbg(dai->dev, "%s()\n", __func__);
|
||||
|
||||
ret = hdmi_codec_new_stream(substream, dai);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = mutex_trylock(&hcp->lock);
|
||||
if (!ret) {
|
||||
dev_err(dai->dev, "Only one simultaneous stream supported!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hcp->hcd.ops->audio_startup) {
|
||||
ret = hcp->hcd.ops->audio_startup(dai->dev->parent, hcp->hcd.data);
|
||||
if (ret) {
|
||||
mutex_lock(&hcp->current_stream_lock);
|
||||
hcp->current_stream = NULL;
|
||||
mutex_unlock(&hcp->current_stream_lock);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (hcp->hcd.ops->get_eld) {
|
||||
|
@ -431,17 +406,18 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
|
|||
if (!ret) {
|
||||
ret = snd_pcm_hw_constraint_eld(substream->runtime,
|
||||
hcp->eld);
|
||||
if (ret) {
|
||||
mutex_lock(&hcp->current_stream_lock);
|
||||
hcp->current_stream = NULL;
|
||||
mutex_unlock(&hcp->current_stream_lock);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
/* Select chmap supported */
|
||||
hdmi_codec_eld_chmap(hcp);
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
/* Release the exclusive lock on error */
|
||||
mutex_unlock(&hcp->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
|
||||
|
@ -449,16 +425,10 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
dev_dbg(dai->dev, "%s()\n", __func__);
|
||||
|
||||
WARN_ON(hcp->current_stream != substream);
|
||||
|
||||
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
|
||||
hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
|
||||
|
||||
mutex_lock(&hcp->current_stream_lock);
|
||||
hcp->current_stream = NULL;
|
||||
mutex_unlock(&hcp->current_stream_lock);
|
||||
mutex_unlock(&hcp->lock);
|
||||
}
|
||||
|
||||
static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
|
||||
|
@ -466,6 +436,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
|
||||
struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
|
||||
struct hdmi_codec_params hp = {
|
||||
.iec = {
|
||||
.status = { 0 },
|
||||
|
@ -510,30 +481,27 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
|
|||
hp.channels = params_channels(params);
|
||||
|
||||
return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data,
|
||||
&hcp->daifmt[dai->id], &hp);
|
||||
cf, &hp);
|
||||
}
|
||||
|
||||
static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
|
||||
unsigned int fmt)
|
||||
static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai,
|
||||
unsigned int fmt)
|
||||
{
|
||||
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
|
||||
struct hdmi_codec_daifmt cf = { 0 };
|
||||
struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
|
||||
|
||||
dev_dbg(dai->dev, "%s()\n", __func__);
|
||||
|
||||
if (dai->id == DAI_ID_SPDIF)
|
||||
return 0;
|
||||
/* Reset daifmt */
|
||||
memset(cf, 0, sizeof(*cf));
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBM_CFM:
|
||||
cf.bit_clk_master = 1;
|
||||
cf.frame_clk_master = 1;
|
||||
cf->bit_clk_master = 1;
|
||||
cf->frame_clk_master = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFM:
|
||||
cf.frame_clk_master = 1;
|
||||
cf->frame_clk_master = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBM_CFS:
|
||||
cf.bit_clk_master = 1;
|
||||
cf->bit_clk_master = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
break;
|
||||
|
@ -545,43 +513,41 @@ static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
|
|||
case SND_SOC_DAIFMT_NB_NF:
|
||||
break;
|
||||
case SND_SOC_DAIFMT_NB_IF:
|
||||
cf.frame_clk_inv = 1;
|
||||
cf->frame_clk_inv = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_IB_NF:
|
||||
cf.bit_clk_inv = 1;
|
||||
cf->bit_clk_inv = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_IB_IF:
|
||||
cf.frame_clk_inv = 1;
|
||||
cf.bit_clk_inv = 1;
|
||||
cf->frame_clk_inv = 1;
|
||||
cf->bit_clk_inv = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
cf.fmt = HDMI_I2S;
|
||||
cf->fmt = HDMI_I2S;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
cf.fmt = HDMI_DSP_A;
|
||||
cf->fmt = HDMI_DSP_A;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
cf.fmt = HDMI_DSP_B;
|
||||
cf->fmt = HDMI_DSP_B;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_RIGHT_J:
|
||||
cf.fmt = HDMI_RIGHT_J;
|
||||
cf->fmt = HDMI_RIGHT_J;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
cf.fmt = HDMI_LEFT_J;
|
||||
cf->fmt = HDMI_LEFT_J;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_AC97:
|
||||
cf.fmt = HDMI_AC97;
|
||||
cf->fmt = HDMI_AC97;
|
||||
break;
|
||||
default:
|
||||
dev_err(dai->dev, "Invalid DAI interface format\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hcp->daifmt[dai->id] = cf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -589,8 +555,6 @@ static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
|
|||
{
|
||||
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
dev_dbg(dai->dev, "%s()\n", __func__);
|
||||
|
||||
if (hcp->hcd.ops->digital_mute)
|
||||
return hcp->hcd.ops->digital_mute(dai->dev->parent,
|
||||
hcp->hcd.data, mute);
|
||||
|
@ -598,14 +562,20 @@ static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops hdmi_dai_ops = {
|
||||
static const struct snd_soc_dai_ops hdmi_codec_i2s_dai_ops = {
|
||||
.startup = hdmi_codec_startup,
|
||||
.shutdown = hdmi_codec_shutdown,
|
||||
.hw_params = hdmi_codec_hw_params,
|
||||
.set_fmt = hdmi_codec_set_fmt,
|
||||
.set_fmt = hdmi_codec_i2s_set_fmt,
|
||||
.digital_mute = hdmi_codec_digital_mute,
|
||||
};
|
||||
|
||||
static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = {
|
||||
.startup = hdmi_codec_startup,
|
||||
.shutdown = hdmi_codec_shutdown,
|
||||
.hw_params = hdmi_codec_hw_params,
|
||||
.digital_mute = hdmi_codec_digital_mute,
|
||||
};
|
||||
|
||||
#define HDMI_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
|
||||
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
|
||||
|
@ -648,8 +618,6 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
|
|||
};
|
||||
int ret;
|
||||
|
||||
dev_dbg(dai->dev, "%s()\n", __func__);
|
||||
|
||||
ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK,
|
||||
NULL, drv->playback.channels_max, 0,
|
||||
&hcp->chmap_info);
|
||||
|
@ -675,20 +643,52 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
|
|||
static int hdmi_dai_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm;
|
||||
struct hdmi_codec_daifmt *daifmt;
|
||||
struct snd_soc_dapm_route route = {
|
||||
.sink = "TX",
|
||||
.source = dai->driver->playback.stream_name,
|
||||
};
|
||||
int ret;
|
||||
|
||||
dapm = snd_soc_component_get_dapm(dai->component);
|
||||
ret = snd_soc_dapm_add_routes(dapm, &route, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return snd_soc_dapm_add_routes(dapm, &route, 1);
|
||||
daifmt = kzalloc(sizeof(*daifmt), GFP_KERNEL);
|
||||
if (!daifmt)
|
||||
return -ENOMEM;
|
||||
|
||||
dai->playback_dma_data = daifmt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
|
||||
int ret;
|
||||
|
||||
ret = hdmi_dai_probe(dai);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cf = dai->playback_dma_data;
|
||||
cf->fmt = HDMI_SPDIF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_codec_dai_remove(struct snd_soc_dai *dai)
|
||||
{
|
||||
kfree(dai->playback_dma_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_driver hdmi_i2s_dai = {
|
||||
.name = "i2s-hifi",
|
||||
.id = DAI_ID_I2S,
|
||||
.probe = hdmi_dai_probe,
|
||||
.remove = hdmi_codec_dai_remove,
|
||||
.playback = {
|
||||
.stream_name = "I2S Playback",
|
||||
.channels_min = 2,
|
||||
|
@ -697,14 +697,15 @@ static const struct snd_soc_dai_driver hdmi_i2s_dai = {
|
|||
.formats = I2S_FORMATS,
|
||||
.sig_bits = 24,
|
||||
},
|
||||
.ops = &hdmi_dai_ops,
|
||||
.ops = &hdmi_codec_i2s_dai_ops,
|
||||
.pcm_new = hdmi_codec_pcm_new,
|
||||
};
|
||||
|
||||
static const struct snd_soc_dai_driver hdmi_spdif_dai = {
|
||||
.name = "spdif-hifi",
|
||||
.id = DAI_ID_SPDIF,
|
||||
.probe = hdmi_dai_probe,
|
||||
.probe = hdmi_dai_spdif_probe,
|
||||
.remove = hdmi_codec_dai_remove,
|
||||
.playback = {
|
||||
.stream_name = "SPDIF Playback",
|
||||
.channels_min = 2,
|
||||
|
@ -712,7 +713,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = {
|
|||
.rates = HDMI_RATES,
|
||||
.formats = SPDIF_FORMATS,
|
||||
},
|
||||
.ops = &hdmi_dai_ops,
|
||||
.ops = &hdmi_codec_spdif_dai_ops,
|
||||
.pcm_new = hdmi_codec_pcm_new,
|
||||
};
|
||||
|
||||
|
@ -741,13 +742,12 @@ static const struct snd_soc_component_driver hdmi_driver = {
|
|||
static int hdmi_codec_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
|
||||
struct snd_soc_dai_driver *daidrv;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct hdmi_codec_priv *hcp;
|
||||
int dai_count, i = 0;
|
||||
int ret;
|
||||
|
||||
dev_dbg(dev, "%s()\n", __func__);
|
||||
|
||||
if (!hcd) {
|
||||
dev_err(dev, "%s: No platform data\n", __func__);
|
||||
return -EINVAL;
|
||||
|
@ -765,29 +765,25 @@ static int hdmi_codec_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
|
||||
hcp->hcd = *hcd;
|
||||
mutex_init(&hcp->current_stream_lock);
|
||||
mutex_init(&hcp->lock);
|
||||
|
||||
hcp->daidrv = devm_kcalloc(dev, dai_count, sizeof(*hcp->daidrv),
|
||||
GFP_KERNEL);
|
||||
if (!hcp->daidrv)
|
||||
daidrv = devm_kcalloc(dev, dai_count, sizeof(*daidrv), GFP_KERNEL);
|
||||
if (!daidrv)
|
||||
return -ENOMEM;
|
||||
|
||||
if (hcd->i2s) {
|
||||
hcp->daidrv[i] = hdmi_i2s_dai;
|
||||
hcp->daidrv[i].playback.channels_max =
|
||||
hcd->max_i2s_channels;
|
||||
daidrv[i] = hdmi_i2s_dai;
|
||||
daidrv[i].playback.channels_max = hcd->max_i2s_channels;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (hcd->spdif) {
|
||||
hcp->daidrv[i] = hdmi_spdif_dai;
|
||||
hcp->daifmt[DAI_ID_SPDIF].fmt = HDMI_SPDIF;
|
||||
}
|
||||
if (hcd->spdif)
|
||||
daidrv[i] = hdmi_spdif_dai;
|
||||
|
||||
dev_set_drvdata(dev, hcp);
|
||||
|
||||
ret = devm_snd_soc_register_component(dev, &hdmi_driver, hcp->daidrv,
|
||||
dai_count);
|
||||
ret = devm_snd_soc_register_component(dev, &hdmi_driver, daidrv,
|
||||
dai_count);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: snd_soc_register_component() failed (%d)\n",
|
||||
__func__, ret);
|
||||
|
|
4177
sound/soc/codecs/madera.c
Normal file
4177
sound/soc/codecs/madera.c
Normal file
File diff suppressed because it is too large
Load diff
442
sound/soc/codecs/madera.h
Normal file
442
sound/soc/codecs/madera.h
Normal file
|
@ -0,0 +1,442 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Cirrus Logic Madera class codecs common support
|
||||
*
|
||||
* Copyright (C) 2015-2018 Cirrus Logic, Inc. and
|
||||
* Cirrus Logic International Semiconductor Ltd.
|
||||
*/
|
||||
|
||||
#ifndef ASOC_MADERA_H
|
||||
#define ASOC_MADERA_H
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/madera-pdata.h>
|
||||
|
||||
#include "wm_adsp.h"
|
||||
|
||||
#define MADERA_FLL1_REFCLK 1
|
||||
#define MADERA_FLL2_REFCLK 2
|
||||
#define MADERA_FLL3_REFCLK 3
|
||||
#define MADERA_FLLAO_REFCLK 4
|
||||
#define MADERA_FLL1_SYNCCLK 5
|
||||
#define MADERA_FLL2_SYNCCLK 6
|
||||
#define MADERA_FLL3_SYNCCLK 7
|
||||
#define MADERA_FLLAO_SYNCCLK 8
|
||||
|
||||
#define MADERA_FLL_SRC_NONE -1
|
||||
#define MADERA_FLL_SRC_MCLK1 0
|
||||
#define MADERA_FLL_SRC_MCLK2 1
|
||||
#define MADERA_FLL_SRC_SLIMCLK 3
|
||||
#define MADERA_FLL_SRC_FLL1 4
|
||||
#define MADERA_FLL_SRC_FLL2 5
|
||||
#define MADERA_FLL_SRC_AIF1BCLK 8
|
||||
#define MADERA_FLL_SRC_AIF2BCLK 9
|
||||
#define MADERA_FLL_SRC_AIF3BCLK 10
|
||||
#define MADERA_FLL_SRC_AIF4BCLK 11
|
||||
#define MADERA_FLL_SRC_AIF1LRCLK 12
|
||||
#define MADERA_FLL_SRC_AIF2LRCLK 13
|
||||
#define MADERA_FLL_SRC_AIF3LRCLK 14
|
||||
#define MADERA_FLL_SRC_AIF4LRCLK 15
|
||||
|
||||
#define MADERA_CLK_SYSCLK_1 1
|
||||
#define MADERA_CLK_ASYNCCLK_1 2
|
||||
#define MADERA_CLK_OPCLK 3
|
||||
#define MADERA_CLK_ASYNC_OPCLK 4
|
||||
#define MADERA_CLK_SYSCLK_2 5
|
||||
#define MADERA_CLK_SYSCLK_3 6
|
||||
#define MADERA_CLK_ASYNCCLK_2 7
|
||||
#define MADERA_CLK_DSPCLK 8
|
||||
|
||||
#define MADERA_CLK_SRC_MCLK1 0x0
|
||||
#define MADERA_CLK_SRC_MCLK2 0x1
|
||||
#define MADERA_CLK_SRC_FLL1 0x4
|
||||
#define MADERA_CLK_SRC_FLL2 0x5
|
||||
#define MADERA_CLK_SRC_FLL3 0x6
|
||||
#define MADERA_CLK_SRC_FLLAO_HI 0x7
|
||||
#define MADERA_CLK_SRC_FLL1_DIV6 0x7
|
||||
#define MADERA_CLK_SRC_AIF1BCLK 0x8
|
||||
#define MADERA_CLK_SRC_AIF2BCLK 0x9
|
||||
#define MADERA_CLK_SRC_AIF3BCLK 0xA
|
||||
#define MADERA_CLK_SRC_AIF4BCLK 0xB
|
||||
#define MADERA_CLK_SRC_FLLAO 0xF
|
||||
|
||||
#define MADERA_MIXER_VOL_MASK 0x00FE
|
||||
#define MADERA_MIXER_VOL_SHIFT 1
|
||||
#define MADERA_MIXER_VOL_WIDTH 7
|
||||
|
||||
#define MADERA_DOM_GRP_FX 0
|
||||
#define MADERA_DOM_GRP_ASRC1 1
|
||||
#define MADERA_DOM_GRP_ASRC2 2
|
||||
#define MADERA_DOM_GRP_ISRC1 3
|
||||
#define MADERA_DOM_GRP_ISRC2 4
|
||||
#define MADERA_DOM_GRP_ISRC3 5
|
||||
#define MADERA_DOM_GRP_ISRC4 6
|
||||
#define MADERA_DOM_GRP_OUT 7
|
||||
#define MADERA_DOM_GRP_SPD 8
|
||||
#define MADERA_DOM_GRP_DSP1 9
|
||||
#define MADERA_DOM_GRP_DSP2 10
|
||||
#define MADERA_DOM_GRP_DSP3 11
|
||||
#define MADERA_DOM_GRP_DSP4 12
|
||||
#define MADERA_DOM_GRP_DSP5 13
|
||||
#define MADERA_DOM_GRP_DSP6 14
|
||||
#define MADERA_DOM_GRP_DSP7 15
|
||||
#define MADERA_DOM_GRP_AIF1 16
|
||||
#define MADERA_DOM_GRP_AIF2 17
|
||||
#define MADERA_DOM_GRP_AIF3 18
|
||||
#define MADERA_DOM_GRP_AIF4 19
|
||||
#define MADERA_DOM_GRP_SLIMBUS 20
|
||||
#define MADERA_DOM_GRP_PWM 21
|
||||
#define MADERA_DOM_GRP_DFC 22
|
||||
#define MADERA_N_DOM_GRPS 23
|
||||
|
||||
#define MADERA_MAX_DAI 11
|
||||
#define MADERA_MAX_ADSP 7
|
||||
|
||||
#define MADERA_NUM_MIXER_INPUTS 148
|
||||
|
||||
struct madera;
|
||||
struct wm_adsp;
|
||||
|
||||
struct madera_voice_trigger_info {
|
||||
/** Which core triggered, 1-based (1 = DSP1, ...) */
|
||||
int core_num;
|
||||
};
|
||||
|
||||
struct madera_dai_priv {
|
||||
int clk;
|
||||
struct snd_pcm_hw_constraint_list constraint;
|
||||
};
|
||||
|
||||
struct madera_priv {
|
||||
struct wm_adsp adsp[MADERA_MAX_ADSP];
|
||||
struct madera *madera;
|
||||
struct device *dev;
|
||||
int sysclk;
|
||||
int asyncclk;
|
||||
int dspclk;
|
||||
struct madera_dai_priv dai[MADERA_MAX_DAI];
|
||||
|
||||
int num_inputs;
|
||||
|
||||
unsigned int in_pending;
|
||||
|
||||
unsigned int out_up_pending;
|
||||
unsigned int out_up_delay;
|
||||
unsigned int out_down_pending;
|
||||
unsigned int out_down_delay;
|
||||
|
||||
unsigned int adsp_rate_cache[MADERA_MAX_ADSP];
|
||||
|
||||
struct mutex rate_lock;
|
||||
|
||||
int tdm_width[MADERA_MAX_AIF];
|
||||
int tdm_slots[MADERA_MAX_AIF];
|
||||
|
||||
int domain_group_ref[MADERA_N_DOM_GRPS];
|
||||
};
|
||||
|
||||
struct madera_fll_cfg {
|
||||
int n;
|
||||
unsigned int theta;
|
||||
unsigned int lambda;
|
||||
int refdiv;
|
||||
int fratio;
|
||||
int gain;
|
||||
int alt_gain;
|
||||
};
|
||||
|
||||
struct madera_fll {
|
||||
struct madera *madera;
|
||||
int id;
|
||||
unsigned int base;
|
||||
|
||||
unsigned int fout;
|
||||
|
||||
int sync_src;
|
||||
unsigned int sync_freq;
|
||||
|
||||
int ref_src;
|
||||
unsigned int ref_freq;
|
||||
struct madera_fll_cfg ref_cfg;
|
||||
};
|
||||
|
||||
struct madera_enum {
|
||||
struct soc_enum mixer_enum;
|
||||
int val;
|
||||
};
|
||||
|
||||
extern const unsigned int madera_ana_tlv[];
|
||||
extern const unsigned int madera_eq_tlv[];
|
||||
extern const unsigned int madera_digital_tlv[];
|
||||
extern const unsigned int madera_noise_tlv[];
|
||||
extern const unsigned int madera_ng_tlv[];
|
||||
|
||||
extern const unsigned int madera_mixer_tlv[];
|
||||
extern const char * const madera_mixer_texts[MADERA_NUM_MIXER_INPUTS];
|
||||
extern const unsigned int madera_mixer_values[MADERA_NUM_MIXER_INPUTS];
|
||||
|
||||
#define MADERA_GAINMUX_CONTROLS(name, base) \
|
||||
SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1, \
|
||||
MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
|
||||
madera_mixer_tlv)
|
||||
|
||||
#define MADERA_MIXER_CONTROLS(name, base) \
|
||||
SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \
|
||||
MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
|
||||
madera_mixer_tlv), \
|
||||
SOC_SINGLE_RANGE_TLV(name " Input 2 Volume", base + 3, \
|
||||
MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
|
||||
madera_mixer_tlv), \
|
||||
SOC_SINGLE_RANGE_TLV(name " Input 3 Volume", base + 5, \
|
||||
MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
|
||||
madera_mixer_tlv), \
|
||||
SOC_SINGLE_RANGE_TLV(name " Input 4 Volume", base + 7, \
|
||||
MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
|
||||
madera_mixer_tlv)
|
||||
|
||||
#define MADERA_MUX_ENUM_DECL(name, reg) \
|
||||
SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL( \
|
||||
name, reg, 0, 0xff, madera_mixer_texts, madera_mixer_values)
|
||||
|
||||
#define MADERA_MUX_CTL_DECL(name) \
|
||||
const struct snd_kcontrol_new name##_mux = \
|
||||
SOC_DAPM_ENUM("Route", name##_enum)
|
||||
|
||||
#define MADERA_MUX_ENUMS(name, base_reg) \
|
||||
static MADERA_MUX_ENUM_DECL(name##_enum, base_reg); \
|
||||
static MADERA_MUX_CTL_DECL(name)
|
||||
|
||||
#define MADERA_MIXER_ENUMS(name, base_reg) \
|
||||
MADERA_MUX_ENUMS(name##_in1, base_reg); \
|
||||
MADERA_MUX_ENUMS(name##_in2, base_reg + 2); \
|
||||
MADERA_MUX_ENUMS(name##_in3, base_reg + 4); \
|
||||
MADERA_MUX_ENUMS(name##_in4, base_reg + 6)
|
||||
|
||||
#define MADERA_DSP_AUX_ENUMS(name, base_reg) \
|
||||
MADERA_MUX_ENUMS(name##_aux1, base_reg); \
|
||||
MADERA_MUX_ENUMS(name##_aux2, base_reg + 8); \
|
||||
MADERA_MUX_ENUMS(name##_aux3, base_reg + 16); \
|
||||
MADERA_MUX_ENUMS(name##_aux4, base_reg + 24); \
|
||||
MADERA_MUX_ENUMS(name##_aux5, base_reg + 32); \
|
||||
MADERA_MUX_ENUMS(name##_aux6, base_reg + 40)
|
||||
|
||||
#define MADERA_MUX(name, ctrl) \
|
||||
SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
|
||||
|
||||
#define MADERA_MUX_WIDGETS(name, name_str) \
|
||||
MADERA_MUX(name_str " Input 1", &name##_mux)
|
||||
|
||||
#define MADERA_MIXER_WIDGETS(name, name_str) \
|
||||
MADERA_MUX(name_str " Input 1", &name##_in1_mux), \
|
||||
MADERA_MUX(name_str " Input 2", &name##_in2_mux), \
|
||||
MADERA_MUX(name_str " Input 3", &name##_in3_mux), \
|
||||
MADERA_MUX(name_str " Input 4", &name##_in4_mux), \
|
||||
SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
|
||||
|
||||
#define MADERA_DSP_WIDGETS(name, name_str) \
|
||||
MADERA_MIXER_WIDGETS(name##L, name_str "L"), \
|
||||
MADERA_MIXER_WIDGETS(name##R, name_str "R"), \
|
||||
MADERA_MUX(name_str " Aux 1", &name##_aux1_mux), \
|
||||
MADERA_MUX(name_str " Aux 2", &name##_aux2_mux), \
|
||||
MADERA_MUX(name_str " Aux 3", &name##_aux3_mux), \
|
||||
MADERA_MUX(name_str " Aux 4", &name##_aux4_mux), \
|
||||
MADERA_MUX(name_str " Aux 5", &name##_aux5_mux), \
|
||||
MADERA_MUX(name_str " Aux 6", &name##_aux6_mux)
|
||||
|
||||
#define MADERA_MUX_ROUTES(widget, name) \
|
||||
{ widget, NULL, name " Input 1" }, \
|
||||
MADERA_MIXER_INPUT_ROUTES(name " Input 1")
|
||||
|
||||
#define MADERA_MIXER_ROUTES(widget, name) \
|
||||
{ widget, NULL, name " Mixer" }, \
|
||||
{ name " Mixer", NULL, name " Input 1" }, \
|
||||
{ name " Mixer", NULL, name " Input 2" }, \
|
||||
{ name " Mixer", NULL, name " Input 3" }, \
|
||||
{ name " Mixer", NULL, name " Input 4" }, \
|
||||
MADERA_MIXER_INPUT_ROUTES(name " Input 1"), \
|
||||
MADERA_MIXER_INPUT_ROUTES(name " Input 2"), \
|
||||
MADERA_MIXER_INPUT_ROUTES(name " Input 3"), \
|
||||
MADERA_MIXER_INPUT_ROUTES(name " Input 4")
|
||||
|
||||
#define MADERA_DSP_ROUTES(name) \
|
||||
{ name, NULL, name " Preloader"}, \
|
||||
{ name " Preload", NULL, name " Preloader"}, \
|
||||
{ name, NULL, "SYSCLK"}, \
|
||||
{ name, NULL, "DSPCLK"}, \
|
||||
{ name, NULL, name " Aux 1" }, \
|
||||
{ name, NULL, name " Aux 2" }, \
|
||||
{ name, NULL, name " Aux 3" }, \
|
||||
{ name, NULL, name " Aux 4" }, \
|
||||
{ name, NULL, name " Aux 5" }, \
|
||||
{ name, NULL, name " Aux 6" }, \
|
||||
MADERA_MIXER_INPUT_ROUTES(name " Aux 1"), \
|
||||
MADERA_MIXER_INPUT_ROUTES(name " Aux 2"), \
|
||||
MADERA_MIXER_INPUT_ROUTES(name " Aux 3"), \
|
||||
MADERA_MIXER_INPUT_ROUTES(name " Aux 4"), \
|
||||
MADERA_MIXER_INPUT_ROUTES(name " Aux 5"), \
|
||||
MADERA_MIXER_INPUT_ROUTES(name " Aux 6"), \
|
||||
MADERA_MIXER_ROUTES(name, name "L"), \
|
||||
MADERA_MIXER_ROUTES(name, name "R")
|
||||
|
||||
#define MADERA_RATE_ENUM(xname, xenum) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
|
||||
.info = snd_soc_info_enum_double, \
|
||||
.get = snd_soc_get_enum_double, .put = madera_rate_put, \
|
||||
.private_value = (unsigned long)&xenum }
|
||||
|
||||
#define MADERA_EQ_CONTROL(xname, xbase) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
|
||||
.put = madera_eq_coeff_put, .private_value = \
|
||||
((unsigned long)&(struct soc_bytes) { .base = xbase, \
|
||||
.num_regs = 20, .mask = ~MADERA_EQ1_B1_MODE }) }
|
||||
|
||||
#define MADERA_LHPF_CONTROL(xname, xbase) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
|
||||
.put = madera_lhpf_coeff_put, .private_value = \
|
||||
((unsigned long)&(struct soc_bytes) { .base = xbase, \
|
||||
.num_regs = 1 }) }
|
||||
|
||||
#define MADERA_RATES SNDRV_PCM_RATE_KNOT
|
||||
|
||||
#define MADERA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
|
||||
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
||||
#define MADERA_OSR_ENUM_SIZE 5
|
||||
#define MADERA_SYNC_RATE_ENUM_SIZE 3
|
||||
#define MADERA_ASYNC_RATE_ENUM_SIZE 2
|
||||
#define MADERA_RATE_ENUM_SIZE \
|
||||
(MADERA_SYNC_RATE_ENUM_SIZE + MADERA_ASYNC_RATE_ENUM_SIZE)
|
||||
#define MADERA_SAMPLE_RATE_ENUM_SIZE 16
|
||||
#define MADERA_DFC_TYPE_ENUM_SIZE 5
|
||||
#define MADERA_DFC_WIDTH_ENUM_SIZE 5
|
||||
|
||||
extern const struct snd_soc_dai_ops madera_dai_ops;
|
||||
extern const struct snd_soc_dai_ops madera_simple_dai_ops;
|
||||
|
||||
extern const struct snd_kcontrol_new madera_inmux[];
|
||||
extern const struct snd_kcontrol_new madera_inmode[];
|
||||
|
||||
extern const char * const madera_rate_text[MADERA_RATE_ENUM_SIZE];
|
||||
extern const unsigned int madera_rate_val[MADERA_RATE_ENUM_SIZE];
|
||||
|
||||
extern const struct soc_enum madera_sample_rate[];
|
||||
extern const struct soc_enum madera_isrc_fsl[];
|
||||
extern const struct soc_enum madera_isrc_fsh[];
|
||||
extern const struct soc_enum madera_asrc1_rate[];
|
||||
extern const struct soc_enum madera_asrc2_rate[];
|
||||
extern const struct soc_enum madera_dfc_width[];
|
||||
extern const struct soc_enum madera_dfc_type[];
|
||||
|
||||
extern const struct soc_enum madera_in_vi_ramp;
|
||||
extern const struct soc_enum madera_in_vd_ramp;
|
||||
|
||||
extern const struct soc_enum madera_out_vi_ramp;
|
||||
extern const struct soc_enum madera_out_vd_ramp;
|
||||
|
||||
extern const struct soc_enum madera_lhpf1_mode;
|
||||
extern const struct soc_enum madera_lhpf2_mode;
|
||||
extern const struct soc_enum madera_lhpf3_mode;
|
||||
extern const struct soc_enum madera_lhpf4_mode;
|
||||
|
||||
extern const struct soc_enum madera_ng_hold;
|
||||
extern const struct soc_enum madera_in_hpf_cut_enum;
|
||||
extern const struct soc_enum madera_in_dmic_osr[];
|
||||
|
||||
extern const struct soc_enum madera_output_anc_src[];
|
||||
extern const struct soc_enum madera_anc_input_src[];
|
||||
extern const struct soc_enum madera_anc_ng_enum;
|
||||
|
||||
extern const struct snd_kcontrol_new madera_dsp_trigger_output_mux[];
|
||||
extern const struct snd_kcontrol_new madera_drc_activity_output_mux[];
|
||||
|
||||
extern const struct snd_kcontrol_new madera_adsp_rate_controls[];
|
||||
|
||||
int madera_dfc_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int madera_lp_mode_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int madera_out1_demux_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int madera_out1_demux_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int madera_rate_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int madera_eq_coeff_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int madera_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
int madera_sysclk_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event);
|
||||
int madera_spk_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event);
|
||||
int madera_in_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event);
|
||||
int madera_out_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event);
|
||||
int madera_hp_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event);
|
||||
int madera_anc_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event);
|
||||
int madera_domain_clk_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event);
|
||||
|
||||
int madera_set_adsp_clk(struct madera_priv *priv, int dsp_num,
|
||||
unsigned int freq);
|
||||
|
||||
int madera_set_sysclk(struct snd_soc_component *component, int clk_id,
|
||||
int source, unsigned int freq, int dir);
|
||||
|
||||
int madera_init_fll(struct madera *madera, int id, int base,
|
||||
struct madera_fll *fll);
|
||||
int madera_set_fll_refclk(struct madera_fll *fll, int source,
|
||||
unsigned int fref, unsigned int fout);
|
||||
int madera_set_fll_syncclk(struct madera_fll *fll, int source,
|
||||
unsigned int fref, unsigned int fout);
|
||||
int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
|
||||
unsigned int fin, unsigned int fout);
|
||||
|
||||
int madera_core_init(struct madera_priv *priv);
|
||||
int madera_core_free(struct madera_priv *priv);
|
||||
int madera_init_overheat(struct madera_priv *priv);
|
||||
int madera_free_overheat(struct madera_priv *priv);
|
||||
int madera_init_inputs(struct snd_soc_component *component);
|
||||
int madera_init_outputs(struct snd_soc_component *component, int n_mono_routes);
|
||||
int madera_init_bus_error_irq(struct madera_priv *priv, int dsp_num,
|
||||
irq_handler_t handler);
|
||||
void madera_free_bus_error_irq(struct madera_priv *priv, int dsp_num);
|
||||
|
||||
int madera_init_dai(struct madera_priv *priv, int dai);
|
||||
|
||||
int madera_set_output_mode(struct snd_soc_component *component, int output,
|
||||
bool differential);
|
||||
|
||||
/* Following functions are for use by machine drivers */
|
||||
static inline int madera_register_notifier(struct snd_soc_component *component,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
struct madera_priv *priv = snd_soc_component_get_drvdata(component);
|
||||
struct madera *madera = priv->madera;
|
||||
|
||||
return blocking_notifier_chain_register(&madera->notifier, nb);
|
||||
}
|
||||
|
||||
static inline int
|
||||
madera_unregister_notifier(struct snd_soc_component *component,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
struct madera_priv *priv = snd_soc_component_get_drvdata(component);
|
||||
struct madera *madera = priv->madera;
|
||||
|
||||
return blocking_notifier_chain_unregister(&madera->notifier, nb);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -19,24 +19,42 @@
|
|||
#include <sound/soc-dai.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
|
||||
struct max98357a_priv {
|
||||
struct delayed_work enable_sdmode_work;
|
||||
struct gpio_desc *sdmode;
|
||||
unsigned int sdmode_delay;
|
||||
};
|
||||
|
||||
static void max98357a_enable_sdmode_work(struct work_struct *work)
|
||||
{
|
||||
struct max98357a_priv *max98357a =
|
||||
container_of(work, struct max98357a_priv,
|
||||
enable_sdmode_work.work);
|
||||
|
||||
gpiod_set_value(max98357a->sdmode, 1);
|
||||
}
|
||||
|
||||
static int max98357a_daiops_trigger(struct snd_pcm_substream *substream,
|
||||
int cmd, struct snd_soc_dai *dai)
|
||||
{
|
||||
struct gpio_desc *sdmode = snd_soc_dai_get_drvdata(dai);
|
||||
struct max98357a_priv *max98357a = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (!sdmode)
|
||||
if (!max98357a->sdmode)
|
||||
return 0;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
gpiod_set_value(sdmode, 1);
|
||||
queue_delayed_work(system_power_efficient_wq,
|
||||
&max98357a->enable_sdmode_work,
|
||||
msecs_to_jiffies(max98357a->sdmode_delay));
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
gpiod_set_value(sdmode, 0);
|
||||
cancel_delayed_work_sync(&max98357a->enable_sdmode_work);
|
||||
gpiod_set_value(max98357a->sdmode, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -51,21 +69,7 @@ static const struct snd_soc_dapm_route max98357a_dapm_routes[] = {
|
|||
{"Speaker", NULL, "HiFi Playback"},
|
||||
};
|
||||
|
||||
static int max98357a_component_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct gpio_desc *sdmode;
|
||||
|
||||
sdmode = devm_gpiod_get_optional(component->dev, "sdmode", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(sdmode))
|
||||
return PTR_ERR(sdmode);
|
||||
|
||||
snd_soc_component_set_drvdata(component, sdmode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver max98357a_component_driver = {
|
||||
.probe = max98357a_component_probe,
|
||||
.dapm_widgets = max98357a_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(max98357a_dapm_widgets),
|
||||
.dapm_routes = max98357a_dapm_routes,
|
||||
|
@ -104,16 +108,39 @@ static struct snd_soc_dai_driver max98357a_dai_driver = {
|
|||
|
||||
static int max98357a_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct max98357a_priv *max98357a;
|
||||
int ret;
|
||||
|
||||
max98357a = devm_kzalloc(&pdev->dev, sizeof(*max98357a), GFP_KERNEL);
|
||||
|
||||
if (!max98357a)
|
||||
return -ENOMEM;
|
||||
|
||||
max98357a->sdmode = devm_gpiod_get_optional(&pdev->dev,
|
||||
"sdmode", GPIOD_OUT_LOW);
|
||||
|
||||
if (IS_ERR(max98357a->sdmode))
|
||||
return PTR_ERR(max98357a->sdmode);
|
||||
|
||||
ret = device_property_read_u32(&pdev->dev, "sdmode-delay",
|
||||
&max98357a->sdmode_delay);
|
||||
|
||||
if (ret) {
|
||||
max98357a->sdmode_delay = 0;
|
||||
dev_dbg(&pdev->dev,
|
||||
"no optional property 'sdmode-delay' found, default: no delay\n");
|
||||
}
|
||||
|
||||
dev_set_drvdata(&pdev->dev, max98357a);
|
||||
|
||||
INIT_DELAYED_WORK(&max98357a->enable_sdmode_work,
|
||||
max98357a_enable_sdmode_work);
|
||||
|
||||
return devm_snd_soc_register_component(&pdev->dev,
|
||||
&max98357a_component_driver,
|
||||
&max98357a_dai_driver, 1);
|
||||
}
|
||||
|
||||
static int max98357a_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id max98357a_device_id[] = {
|
||||
{ .compatible = "maxim,max98357a" },
|
||||
|
@ -137,7 +164,6 @@ static struct platform_driver max98357a_platform_driver = {
|
|||
.acpi_match_table = ACPI_PTR(max98357a_acpi_match),
|
||||
},
|
||||
.probe = max98357a_platform_probe,
|
||||
.remove = max98357a_platform_remove,
|
||||
};
|
||||
module_platform_driver(max98357a_platform_driver);
|
||||
|
||||
|
|
|
@ -187,6 +187,43 @@
|
|||
#define MSM8916_WCD_DIGITAL_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
|
||||
SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
||||
/* Codec supports 2 IIR filters */
|
||||
enum {
|
||||
IIR1 = 0,
|
||||
IIR2,
|
||||
IIR_MAX,
|
||||
};
|
||||
|
||||
/* Codec supports 5 bands */
|
||||
enum {
|
||||
BAND1 = 0,
|
||||
BAND2,
|
||||
BAND3,
|
||||
BAND4,
|
||||
BAND5,
|
||||
BAND_MAX,
|
||||
};
|
||||
|
||||
#define WCD_IIR_FILTER_SIZE (sizeof(u32)*BAND_MAX)
|
||||
|
||||
#define WCD_IIR_FILTER_CTL(xname, iidx, bidx) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = wcd_iir_filter_info, \
|
||||
.get = msm8x16_wcd_get_iir_band_audio_mixer, \
|
||||
.put = msm8x16_wcd_put_iir_band_audio_mixer, \
|
||||
.private_value = (unsigned long)&(struct wcd_iir_filter_ctl) { \
|
||||
.iir_idx = iidx, \
|
||||
.band_idx = bidx, \
|
||||
.bytes_ext = {.max = WCD_IIR_FILTER_SIZE, }, \
|
||||
} \
|
||||
}
|
||||
|
||||
struct wcd_iir_filter_ctl {
|
||||
unsigned int iir_idx;
|
||||
unsigned int band_idx;
|
||||
struct soc_bytes_ext bytes_ext;
|
||||
};
|
||||
|
||||
struct msm8916_wcd_digital_priv {
|
||||
struct clk *ahbclk, *mclk;
|
||||
};
|
||||
|
@ -298,6 +335,161 @@ static SOC_ENUM_SINGLE_DECL(rx2_dcb_cutoff_enum, LPASS_CDC_RX2_B4_CTL, 0,
|
|||
static SOC_ENUM_SINGLE_DECL(rx3_dcb_cutoff_enum, LPASS_CDC_RX3_B4_CTL, 0,
|
||||
dc_blocker_cutoff_text);
|
||||
|
||||
static int msm8x16_wcd_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_dapm_to_component(w->dapm);
|
||||
int value = 0, reg = 0;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
if (w->shift == 0)
|
||||
reg = LPASS_CDC_IIR1_GAIN_B1_CTL;
|
||||
else if (w->shift == 1)
|
||||
reg = LPASS_CDC_IIR2_GAIN_B1_CTL;
|
||||
value = snd_soc_component_read32(component, reg);
|
||||
snd_soc_component_write(component, reg, value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t get_iir_band_coeff(struct snd_soc_component *component,
|
||||
int iir_idx, int band_idx,
|
||||
int coeff_idx)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
|
||||
/* Address does not automatically update if reading */
|
||||
snd_soc_component_write(component,
|
||||
(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
|
||||
((band_idx * BAND_MAX + coeff_idx)
|
||||
* sizeof(uint32_t)) & 0x7F);
|
||||
|
||||
value |= snd_soc_component_read32(component,
|
||||
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx));
|
||||
|
||||
snd_soc_component_write(component,
|
||||
(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
|
||||
((band_idx * BAND_MAX + coeff_idx)
|
||||
* sizeof(uint32_t) + 1) & 0x7F);
|
||||
|
||||
value |= (snd_soc_component_read32(component,
|
||||
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 8);
|
||||
|
||||
snd_soc_component_write(component,
|
||||
(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
|
||||
((band_idx * BAND_MAX + coeff_idx)
|
||||
* sizeof(uint32_t) + 2) & 0x7F);
|
||||
|
||||
value |= (snd_soc_component_read32(component,
|
||||
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 16);
|
||||
|
||||
snd_soc_component_write(component,
|
||||
(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
|
||||
((band_idx * BAND_MAX + coeff_idx)
|
||||
* sizeof(uint32_t) + 3) & 0x7F);
|
||||
|
||||
/* Mask bits top 2 bits since they are reserved */
|
||||
value |= ((snd_soc_component_read32(component,
|
||||
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) & 0x3f) << 24);
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
static int msm8x16_wcd_get_iir_band_audio_mixer(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd_iir_filter_ctl *ctl =
|
||||
(struct wcd_iir_filter_ctl *)kcontrol->private_value;
|
||||
struct soc_bytes_ext *params = &ctl->bytes_ext;
|
||||
int iir_idx = ctl->iir_idx;
|
||||
int band_idx = ctl->band_idx;
|
||||
u32 coeff[BAND_MAX];
|
||||
|
||||
coeff[0] = get_iir_band_coeff(component, iir_idx, band_idx, 0);
|
||||
coeff[1] = get_iir_band_coeff(component, iir_idx, band_idx, 1);
|
||||
coeff[2] = get_iir_band_coeff(component, iir_idx, band_idx, 2);
|
||||
coeff[3] = get_iir_band_coeff(component, iir_idx, band_idx, 3);
|
||||
coeff[4] = get_iir_band_coeff(component, iir_idx, band_idx, 4);
|
||||
|
||||
memcpy(ucontrol->value.bytes.data, &coeff[0], params->max);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_iir_band_coeff(struct snd_soc_component *component,
|
||||
int iir_idx, int band_idx,
|
||||
uint32_t value)
|
||||
{
|
||||
snd_soc_component_write(component,
|
||||
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
|
||||
(value & 0xFF));
|
||||
|
||||
snd_soc_component_write(component,
|
||||
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
|
||||
(value >> 8) & 0xFF);
|
||||
|
||||
snd_soc_component_write(component,
|
||||
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
|
||||
(value >> 16) & 0xFF);
|
||||
|
||||
/* Mask top 2 bits, 7-8 are reserved */
|
||||
snd_soc_component_write(component,
|
||||
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
|
||||
(value >> 24) & 0x3F);
|
||||
}
|
||||
|
||||
static int msm8x16_wcd_put_iir_band_audio_mixer(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd_iir_filter_ctl *ctl =
|
||||
(struct wcd_iir_filter_ctl *)kcontrol->private_value;
|
||||
struct soc_bytes_ext *params = &ctl->bytes_ext;
|
||||
int iir_idx = ctl->iir_idx;
|
||||
int band_idx = ctl->band_idx;
|
||||
u32 coeff[BAND_MAX];
|
||||
|
||||
memcpy(&coeff[0], ucontrol->value.bytes.data, params->max);
|
||||
|
||||
/* Mask top bit it is reserved */
|
||||
/* Updates addr automatically for each B2 write */
|
||||
snd_soc_component_write(component,
|
||||
(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
|
||||
(band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
|
||||
|
||||
set_iir_band_coeff(component, iir_idx, band_idx, coeff[0]);
|
||||
set_iir_band_coeff(component, iir_idx, band_idx, coeff[1]);
|
||||
set_iir_band_coeff(component, iir_idx, band_idx, coeff[2]);
|
||||
set_iir_band_coeff(component, iir_idx, band_idx, coeff[3]);
|
||||
set_iir_band_coeff(component, iir_idx, band_idx, coeff[4]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd_iir_filter_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *ucontrol)
|
||||
{
|
||||
struct wcd_iir_filter_ctl *ctl =
|
||||
(struct wcd_iir_filter_ctl *)kcontrol->private_value;
|
||||
struct soc_bytes_ext *params = &ctl->bytes_ext;
|
||||
|
||||
ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES;
|
||||
ucontrol->count = params->max;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = {
|
||||
SOC_SINGLE_S8_TLV("RX1 Digital Volume", LPASS_CDC_RX1_VOL_CTL_B2_CTL,
|
||||
-128, 127, digital_gain),
|
||||
|
@ -322,6 +514,44 @@ static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = {
|
|||
SOC_SINGLE("RX1 Mute Switch", LPASS_CDC_RX1_B6_CTL, 0, 1, 0),
|
||||
SOC_SINGLE("RX2 Mute Switch", LPASS_CDC_RX2_B6_CTL, 0, 1, 0),
|
||||
SOC_SINGLE("RX3 Mute Switch", LPASS_CDC_RX3_B6_CTL, 0, 1, 0),
|
||||
|
||||
SOC_SINGLE("IIR1 Band1 Switch", LPASS_CDC_IIR1_CTL, 0, 1, 0),
|
||||
SOC_SINGLE("IIR1 Band2 Switch", LPASS_CDC_IIR1_CTL, 1, 1, 0),
|
||||
SOC_SINGLE("IIR1 Band3 Switch", LPASS_CDC_IIR1_CTL, 2, 1, 0),
|
||||
SOC_SINGLE("IIR1 Band4 Switch", LPASS_CDC_IIR1_CTL, 3, 1, 0),
|
||||
SOC_SINGLE("IIR1 Band5 Switch", LPASS_CDC_IIR1_CTL, 4, 1, 0),
|
||||
SOC_SINGLE("IIR2 Band1 Switch", LPASS_CDC_IIR2_CTL, 0, 1, 0),
|
||||
SOC_SINGLE("IIR2 Band2 Switch", LPASS_CDC_IIR2_CTL, 1, 1, 0),
|
||||
SOC_SINGLE("IIR2 Band3 Switch", LPASS_CDC_IIR2_CTL, 2, 1, 0),
|
||||
SOC_SINGLE("IIR2 Band4 Switch", LPASS_CDC_IIR2_CTL, 3, 1, 0),
|
||||
SOC_SINGLE("IIR2 Band5 Switch", LPASS_CDC_IIR2_CTL, 4, 1, 0),
|
||||
WCD_IIR_FILTER_CTL("IIR1 Band1", IIR1, BAND1),
|
||||
WCD_IIR_FILTER_CTL("IIR1 Band2", IIR1, BAND2),
|
||||
WCD_IIR_FILTER_CTL("IIR1 Band3", IIR1, BAND3),
|
||||
WCD_IIR_FILTER_CTL("IIR1 Band4", IIR1, BAND4),
|
||||
WCD_IIR_FILTER_CTL("IIR1 Band5", IIR1, BAND5),
|
||||
WCD_IIR_FILTER_CTL("IIR2 Band1", IIR2, BAND1),
|
||||
WCD_IIR_FILTER_CTL("IIR2 Band2", IIR2, BAND2),
|
||||
WCD_IIR_FILTER_CTL("IIR2 Band3", IIR2, BAND3),
|
||||
WCD_IIR_FILTER_CTL("IIR2 Band4", IIR2, BAND4),
|
||||
WCD_IIR_FILTER_CTL("IIR2 Band5", IIR2, BAND5),
|
||||
SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL,
|
||||
0, -84, 40, digital_gain),
|
||||
SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL,
|
||||
0, -84, 40, digital_gain),
|
||||
SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL,
|
||||
0, -84, 40, digital_gain),
|
||||
SOC_SINGLE_SX_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL,
|
||||
0, -84, 40, digital_gain),
|
||||
SOC_SINGLE_SX_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL,
|
||||
0, -84, 40, digital_gain),
|
||||
SOC_SINGLE_SX_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL,
|
||||
0, -84, 40, digital_gain),
|
||||
SOC_SINGLE_SX_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL,
|
||||
0, -84, 40, digital_gain),
|
||||
SOC_SINGLE_SX_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL,
|
||||
0, -84, 40, digital_gain),
|
||||
|
||||
};
|
||||
|
||||
static int msm8916_wcd_digital_enable_interpolator(
|
||||
|
@ -448,6 +678,24 @@ static int msm8916_wcd_digital_enable_dmic(struct snd_soc_dapm_widget *w,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const char * const iir_inp1_text[] = {
|
||||
"ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3"
|
||||
};
|
||||
|
||||
static const struct soc_enum iir1_inp1_mux_enum =
|
||||
SOC_ENUM_SINGLE(LPASS_CDC_CONN_EQ1_B1_CTL,
|
||||
0, 6, iir_inp1_text);
|
||||
|
||||
static const struct soc_enum iir2_inp1_mux_enum =
|
||||
SOC_ENUM_SINGLE(LPASS_CDC_CONN_EQ2_B1_CTL,
|
||||
0, 6, iir_inp1_text);
|
||||
|
||||
static const struct snd_kcontrol_new iir1_inp1_mux =
|
||||
SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
|
||||
|
||||
static const struct snd_kcontrol_new iir2_inp1_mux =
|
||||
SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum);
|
||||
|
||||
static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = {
|
||||
/*RX stuff */
|
||||
SND_SOC_DAPM_AIF_IN("I2S RX1", NULL, 0, SND_SOC_NOPM, 0, 0),
|
||||
|
@ -534,6 +782,15 @@ static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_MIC("Digital Mic1", NULL),
|
||||
SND_SOC_DAPM_MIC("Digital Mic2", NULL),
|
||||
|
||||
/* Sidetone */
|
||||
SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
|
||||
SND_SOC_DAPM_PGA_E("IIR1", LPASS_CDC_CLK_SD_CTL, 0, 0, NULL, 0,
|
||||
msm8x16_wcd_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU),
|
||||
|
||||
SND_SOC_DAPM_MUX("IIR2 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir2_inp1_mux),
|
||||
SND_SOC_DAPM_PGA_E("IIR2", LPASS_CDC_CLK_SD_CTL, 1, 0, NULL, 0,
|
||||
msm8x16_wcd_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU),
|
||||
|
||||
};
|
||||
|
||||
static int msm8916_wcd_digital_get_clks(struct platform_device *pdev,
|
||||
|
@ -708,10 +965,14 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = {
|
|||
{"RX1 MIX1 INP1", "RX1", "I2S RX1"},
|
||||
{"RX1 MIX1 INP1", "RX2", "I2S RX2"},
|
||||
{"RX1 MIX1 INP1", "RX3", "I2S RX3"},
|
||||
{"RX1 MIX1 INP1", "IIR1", "IIR1"},
|
||||
{"RX1 MIX1 INP1", "IIR2", "IIR2"},
|
||||
|
||||
{"RX1 MIX1 INP2", "RX1", "I2S RX1"},
|
||||
{"RX1 MIX1 INP2", "RX2", "I2S RX2"},
|
||||
{"RX1 MIX1 INP2", "RX3", "I2S RX3"},
|
||||
{"RX1 MIX1 INP2", "IIR1", "IIR1"},
|
||||
{"RX1 MIX1 INP2", "IIR2", "IIR2"},
|
||||
|
||||
{"RX1 MIX1 INP3", "RX1", "I2S RX1"},
|
||||
{"RX1 MIX1 INP3", "RX2", "I2S RX2"},
|
||||
|
@ -728,10 +989,14 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = {
|
|||
{"RX2 MIX1 INP1", "RX1", "I2S RX1"},
|
||||
{"RX2 MIX1 INP1", "RX2", "I2S RX2"},
|
||||
{"RX2 MIX1 INP1", "RX3", "I2S RX3"},
|
||||
{"RX2 MIX1 INP1", "IIR1", "IIR1"},
|
||||
{"RX2 MIX1 INP1", "IIR2", "IIR2"},
|
||||
|
||||
{"RX2 MIX1 INP2", "RX1", "I2S RX1"},
|
||||
{"RX2 MIX1 INP2", "RX2", "I2S RX2"},
|
||||
{"RX2 MIX1 INP2", "RX3", "I2S RX3"},
|
||||
{"RX2 MIX1 INP1", "IIR1", "IIR1"},
|
||||
{"RX2 MIX1 INP1", "IIR2", "IIR2"},
|
||||
|
||||
{"RX2 MIX1 INP3", "RX1", "I2S RX1"},
|
||||
{"RX2 MIX1 INP3", "RX2", "I2S RX2"},
|
||||
|
@ -748,10 +1013,27 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = {
|
|||
{"RX3 MIX1 INP1", "RX1", "I2S RX1"},
|
||||
{"RX3 MIX1 INP1", "RX2", "I2S RX2"},
|
||||
{"RX3 MIX1 INP1", "RX3", "I2S RX3"},
|
||||
{"RX3 MIX1 INP1", "IIR1", "IIR1"},
|
||||
{"RX3 MIX1 INP1", "IIR2", "IIR2"},
|
||||
|
||||
{"RX3 MIX1 INP2", "RX1", "I2S RX1"},
|
||||
{"RX3 MIX1 INP2", "RX2", "I2S RX2"},
|
||||
{"RX3 MIX1 INP2", "RX3", "I2S RX3"},
|
||||
{"RX3 MIX1 INP2", "IIR1", "IIR1"},
|
||||
{"RX3 MIX1 INP2", "IIR2", "IIR2"},
|
||||
|
||||
{"RX1 MIX2 INP1", "IIR1", "IIR1"},
|
||||
{"RX2 MIX2 INP1", "IIR1", "IIR1"},
|
||||
{"RX1 MIX2 INP1", "IIR2", "IIR2"},
|
||||
{"RX2 MIX2 INP1", "IIR2", "IIR2"},
|
||||
|
||||
{"IIR1", NULL, "IIR1 INP1 MUX"},
|
||||
{"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
|
||||
{"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
|
||||
|
||||
{"IIR2", NULL, "IIR2 INP1 MUX"},
|
||||
{"IIR2 INP1 MUX", "DEC1", "DEC1 MUX"},
|
||||
{"IIR2 INP1 MUX", "DEC2", "DEC2 MUX"},
|
||||
|
||||
{"RX3 MIX1 INP3", "RX1", "I2S RX1"},
|
||||
{"RX3 MIX1 INP3", "RX2", "I2S RX2"},
|
||||
|
|
|
@ -828,6 +828,24 @@ static int nau8822_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_component *component = dai->component;
|
||||
struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);
|
||||
int val_len = 0, val_rate = 0;
|
||||
unsigned int ctrl_val, bclk_fs, bclk_div;
|
||||
|
||||
/* make BCLK and LRC divide configuration if the codec as master. */
|
||||
snd_soc_component_read(component, NAU8822_REG_CLOCKING, &ctrl_val);
|
||||
if (ctrl_val & NAU8822_CLK_MASTER) {
|
||||
/* get the bclk and fs ratio */
|
||||
bclk_fs = snd_soc_params_to_bclk(params) / params_rate(params);
|
||||
if (bclk_fs <= 32)
|
||||
bclk_div = NAU8822_BCLKDIV_8;
|
||||
else if (bclk_fs <= 64)
|
||||
bclk_div = NAU8822_BCLKDIV_4;
|
||||
else if (bclk_fs <= 128)
|
||||
bclk_div = NAU8822_BCLKDIV_2;
|
||||
else
|
||||
return -EINVAL;
|
||||
snd_soc_component_update_bits(component, NAU8822_REG_CLOCKING,
|
||||
NAU8822_BCLKSEL_MASK, bclk_div);
|
||||
}
|
||||
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
|
|
|
@ -107,10 +107,17 @@
|
|||
|
||||
/* NAU8822_REG_CLOCKING (0x6) */
|
||||
#define NAU8822_CLKIOEN_MASK 0x1
|
||||
#define NAU8822_CLK_MASTER 0x1
|
||||
#define NAU8822_CLK_SLAVE 0x0
|
||||
#define NAU8822_MCLKSEL_SFT 5
|
||||
#define NAU8822_MCLKSEL_MASK (0x7 << 5)
|
||||
#define NAU8822_BCLKSEL_SFT 2
|
||||
#define NAU8822_BCLKSEL_MASK (0x7 << 2)
|
||||
#define NAU8822_BCLKDIV_1 (0x0 << 2)
|
||||
#define NAU8822_BCLKDIV_2 (0x1 << 2)
|
||||
#define NAU8822_BCLKDIV_4 (0x2 << 2)
|
||||
#define NAU8822_BCLKDIV_8 (0x3 << 2)
|
||||
#define NAU8822_BCLKDIV_16 (0x4 << 2)
|
||||
#define NAU8822_CLKM_MASK (0x1 << 8)
|
||||
#define NAU8822_CLKM_MCLK (0x0 << 8)
|
||||
#define NAU8822_CLKM_PLL (0x1 << 8)
|
||||
|
|
|
@ -53,6 +53,9 @@ struct pcm3168a_priv {
|
|||
unsigned long sysclk;
|
||||
unsigned int adc_fmt;
|
||||
unsigned int dac_fmt;
|
||||
int tdm_slots;
|
||||
u32 tdm_mask[2];
|
||||
int slot_width;
|
||||
};
|
||||
|
||||
static const char *const pcm3168a_roll_off[] = { "Sharp", "Slow" };
|
||||
|
@ -384,6 +387,47 @@ static int pcm3168a_set_dai_fmt_adc(struct snd_soc_dai *dai,
|
|||
return pcm3168a_set_dai_fmt(dai, format, false);
|
||||
}
|
||||
|
||||
static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
|
||||
unsigned int rx_mask, int slots,
|
||||
int slot_width)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) {
|
||||
dev_err(component->dev,
|
||||
"Bad tdm mask tx: 0x%08x rx: 0x%08x slots %d\n",
|
||||
tx_mask, rx_mask, slots);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (slot_width &&
|
||||
(slot_width != 16 && slot_width != 24 && slot_width != 32 )) {
|
||||
dev_err(component->dev, "Unsupported slot_width %d\n",
|
||||
slot_width);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pcm3168a->tdm_slots && pcm3168a->tdm_slots != slots) {
|
||||
dev_err(component->dev, "Not matching slots %d vs %d\n",
|
||||
pcm3168a->tdm_slots, slots);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pcm3168a->slot_width && pcm3168a->slot_width != slot_width) {
|
||||
dev_err(component->dev, "Not matching slot_width %d vs %d\n",
|
||||
pcm3168a->slot_width, slot_width);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pcm3168a->tdm_slots = slots;
|
||||
pcm3168a->slot_width = slot_width;
|
||||
pcm3168a->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask;
|
||||
pcm3168a->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
|
@ -393,11 +437,10 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
|
|||
bool tx, master_mode;
|
||||
u32 val, mask, shift, reg;
|
||||
unsigned int rate, fmt, ratio, max_ratio;
|
||||
unsigned int chan;
|
||||
int i, min_frame_size;
|
||||
unsigned int tdm_slots;
|
||||
int i, slot_width;
|
||||
|
||||
rate = params_rate(params);
|
||||
chan = params_channels(params);
|
||||
|
||||
ratio = pcm3168a->sysclk / rate;
|
||||
|
||||
|
@ -428,30 +471,46 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
min_frame_size = params_width(params) * 2;
|
||||
switch (min_frame_size) {
|
||||
case 32:
|
||||
if (pcm3168a->slot_width)
|
||||
slot_width = pcm3168a->slot_width;
|
||||
else
|
||||
slot_width = params_width(params);
|
||||
|
||||
switch (slot_width) {
|
||||
case 16:
|
||||
if (master_mode || (fmt != PCM3168A_FMT_RIGHT_J)) {
|
||||
dev_err(component->dev, "32-bit frames are supported only for slave mode using right justified\n");
|
||||
dev_err(component->dev, "16-bit slots are supported only for slave mode using right justified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
fmt = PCM3168A_FMT_RIGHT_J_16;
|
||||
break;
|
||||
case 48:
|
||||
case 24:
|
||||
if (master_mode || (fmt & PCM3168A_FMT_DSP_MASK)) {
|
||||
dev_err(component->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
|
||||
dev_err(component->dev, "24-bit slots not supported in master mode, or slave mode using DSP\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case 64:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "unsupported frame size: %d\n", min_frame_size);
|
||||
dev_err(component->dev, "unsupported frame size: %d\n", slot_width);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* for TDM */
|
||||
if (chan > 2) {
|
||||
if (pcm3168a->tdm_slots)
|
||||
tdm_slots = pcm3168a->tdm_slots;
|
||||
else
|
||||
tdm_slots = params_channels(params);
|
||||
|
||||
/*
|
||||
* Switch the codec to TDM mode when more than 2 TDM slots are needed
|
||||
* for the stream.
|
||||
* If pcm3168a->tdm_slots is not set or set to more than 2 (8/6 usually)
|
||||
* then DIN1/DOUT1 is used in TDM mode.
|
||||
* If pcm3168a->tdm_slots is set to 2 then DIN1/2/3/4 and DOUT1/2/3 is
|
||||
* used in normal mode, no need to switch to TDM modes.
|
||||
*/
|
||||
if (tdm_slots > 2) {
|
||||
switch (fmt) {
|
||||
case PCM3168A_FMT_I2S:
|
||||
case PCM3168A_FMT_DSP_A:
|
||||
|
@ -551,14 +610,16 @@ static const struct snd_soc_dai_ops pcm3168a_dac_dai_ops = {
|
|||
.set_fmt = pcm3168a_set_dai_fmt_dac,
|
||||
.set_sysclk = pcm3168a_set_dai_sysclk,
|
||||
.hw_params = pcm3168a_hw_params,
|
||||
.digital_mute = pcm3168a_digital_mute
|
||||
.digital_mute = pcm3168a_digital_mute,
|
||||
.set_tdm_slot = pcm3168a_set_tdm_slot,
|
||||
};
|
||||
|
||||
static const struct snd_soc_dai_ops pcm3168a_adc_dai_ops = {
|
||||
.startup = pcm3168a_startup,
|
||||
.set_fmt = pcm3168a_set_dai_fmt_adc,
|
||||
.set_sysclk = pcm3168a_set_dai_sysclk,
|
||||
.hw_params = pcm3168a_hw_params
|
||||
.hw_params = pcm3168a_hw_params,
|
||||
.set_tdm_slot = pcm3168a_set_tdm_slot,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver pcm3168a_dais[] = {
|
||||
|
|
2244
sound/soc/codecs/rt1011.c
Normal file
2244
sound/soc/codecs/rt1011.c
Normal file
File diff suppressed because it is too large
Load diff
672
sound/soc/codecs/rt1011.h
Normal file
672
sound/soc/codecs/rt1011.h
Normal file
|
@ -0,0 +1,672 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* rt1011.h -- RT1011 ALSA SoC amplifier component driver header
|
||||
*
|
||||
* Copyright(c) 2019 Realtek Semiconductor Corp.
|
||||
*/
|
||||
|
||||
#ifndef _RT1011_H_
|
||||
#define _RT1011_H_
|
||||
|
||||
#define RT1011_DEVICE_ID_NUM 0x1011
|
||||
|
||||
#define RT1011_RESET 0x0000
|
||||
#define RT1011_CLK_1 0x0002
|
||||
#define RT1011_CLK_2 0x0004
|
||||
#define RT1011_CLK_3 0x0006
|
||||
#define RT1011_CLK_4 0x0008
|
||||
#define RT1011_PLL_1 0x000a
|
||||
#define RT1011_PLL_2 0x000c
|
||||
#define RT1011_SRC_1 0x000e
|
||||
#define RT1011_SRC_2 0x0010
|
||||
#define RT1011_SRC_3 0x0012
|
||||
#define RT1011_CLK_DET 0x0020
|
||||
#define RT1011_SIL_DET 0x0022
|
||||
#define RT1011_PRIV_INDEX 0x006a
|
||||
#define RT1011_PRIV_DATA 0x006c
|
||||
#define RT1011_CUSTOMER_ID 0x0076
|
||||
#define RT1011_FM_VER 0x0078
|
||||
#define RT1011_VERSION_ID 0x007a
|
||||
#define RT1011_VENDOR_ID 0x007c
|
||||
#define RT1011_DEVICE_ID 0x007d
|
||||
#define RT1011_DUM_RW_0 0x00f0
|
||||
#define RT1011_DUM_YUN 0x00f2
|
||||
#define RT1011_DUM_RW_1 0x00f3
|
||||
#define RT1011_DUM_RO 0x00f4
|
||||
#define RT1011_MAN_I2C_DEV 0x0100
|
||||
#define RT1011_DAC_SET_1 0x0102
|
||||
#define RT1011_DAC_SET_2 0x0104
|
||||
#define RT1011_DAC_SET_3 0x0106
|
||||
#define RT1011_ADC_SET 0x0107
|
||||
#define RT1011_ADC_SET_1 0x0108
|
||||
#define RT1011_ADC_SET_2 0x010a
|
||||
#define RT1011_ADC_SET_3 0x010c
|
||||
#define RT1011_ADC_SET_4 0x010e
|
||||
#define RT1011_ADC_SET_5 0x0110
|
||||
#define RT1011_TDM_TOTAL_SET 0x0111
|
||||
#define RT1011_TDM1_SET_TCON 0x0112
|
||||
#define RT1011_TDM1_SET_1 0x0114
|
||||
#define RT1011_TDM1_SET_2 0x0116
|
||||
#define RT1011_TDM1_SET_3 0x0118
|
||||
#define RT1011_TDM1_SET_4 0x011a
|
||||
#define RT1011_TDM1_SET_5 0x011c
|
||||
#define RT1011_TDM2_SET_1 0x011e
|
||||
#define RT1011_TDM2_SET_2 0x0120
|
||||
#define RT1011_TDM2_SET_3 0x0122
|
||||
#define RT1011_TDM2_SET_4 0x0124
|
||||
#define RT1011_TDM2_SET_5 0x0126
|
||||
#define RT1011_PWM_CAL 0x0200
|
||||
#define RT1011_MIXER_1 0x0300
|
||||
#define RT1011_MIXER_2 0x0302
|
||||
#define RT1011_ADRC_LIMIT 0x0310
|
||||
#define RT1011_A_PRO 0x0311
|
||||
#define RT1011_A_TIMING_1 0x0313
|
||||
#define RT1011_A_TIMING_2 0x0314
|
||||
#define RT1011_A_TEMP_SEN 0x0316
|
||||
#define RT1011_SPK_VOL_DET_1 0x0319
|
||||
#define RT1011_SPK_VOL_DET_2 0x031a
|
||||
#define RT1011_SPK_VOL_TEST_OUT 0x031b
|
||||
#define RT1011_VBAT_VOL_DET_1 0x031c
|
||||
#define RT1011_VBAT_VOL_DET_2 0x031d
|
||||
#define RT1011_VBAT_TEST_OUT_1 0x031e
|
||||
#define RT1011_VBAT_TEST_OUT_2 0x031f
|
||||
#define RT1011_VBAT_PROTECTION 0x0320
|
||||
#define RT1011_VBAT_DET 0x0321
|
||||
#define RT1011_POWER_1 0x0322
|
||||
#define RT1011_POWER_2 0x0324
|
||||
#define RT1011_POWER_3 0x0326
|
||||
#define RT1011_POWER_4 0x0328
|
||||
#define RT1011_POWER_5 0x0329
|
||||
#define RT1011_POWER_6 0x032a
|
||||
#define RT1011_POWER_7 0x032b
|
||||
#define RT1011_POWER_8 0x032c
|
||||
#define RT1011_POWER_9 0x032d
|
||||
#define RT1011_CLASS_D_POS 0x032e
|
||||
#define RT1011_BOOST_CON_1 0x0330
|
||||
#define RT1011_BOOST_CON_2 0x0332
|
||||
#define RT1011_ANALOG_CTRL 0x0334
|
||||
#define RT1011_POWER_SEQ 0x0340
|
||||
#define RT1011_SHORT_CIRCUIT_DET_1 0x0508
|
||||
#define RT1011_SHORT_CIRCUIT_DET_2 0x050a
|
||||
#define RT1011_SPK_TEMP_PROTECT_0 0x050c
|
||||
#define RT1011_SPK_TEMP_PROTECT_1 0x050d
|
||||
#define RT1011_SPK_TEMP_PROTECT_2 0x050e
|
||||
#define RT1011_SPK_TEMP_PROTECT_3 0x050f
|
||||
#define RT1011_SPK_TEMP_PROTECT_4 0x0510
|
||||
#define RT1011_SPK_TEMP_PROTECT_5 0x0511
|
||||
#define RT1011_SPK_TEMP_PROTECT_6 0x0512
|
||||
#define RT1011_SPK_TEMP_PROTECT_7 0x0516
|
||||
#define RT1011_SPK_TEMP_PROTECT_8 0x0517
|
||||
#define RT1011_SPK_TEMP_PROTECT_9 0x0518
|
||||
#define RT1011_SPK_PRO_DC_DET_1 0x0519
|
||||
#define RT1011_SPK_PRO_DC_DET_2 0x051a
|
||||
#define RT1011_SPK_PRO_DC_DET_3 0x051b
|
||||
#define RT1011_SPK_PRO_DC_DET_4 0x051c
|
||||
#define RT1011_SPK_PRO_DC_DET_5 0x051d
|
||||
#define RT1011_SPK_PRO_DC_DET_6 0x051e
|
||||
#define RT1011_SPK_PRO_DC_DET_7 0x051f
|
||||
#define RT1011_SPK_PRO_DC_DET_8 0x0520
|
||||
#define RT1011_SPL_1 0x0521
|
||||
#define RT1011_SPL_2 0x0522
|
||||
#define RT1011_SPL_3 0x0524
|
||||
#define RT1011_SPL_4 0x0526
|
||||
#define RT1011_THER_FOLD_BACK_1 0x0528
|
||||
#define RT1011_THER_FOLD_BACK_2 0x052a
|
||||
#define RT1011_EXCUR_PROTECT_1 0x0530
|
||||
#define RT1011_EXCUR_PROTECT_2 0x0532
|
||||
#define RT1011_EXCUR_PROTECT_3 0x0534
|
||||
#define RT1011_EXCUR_PROTECT_4 0x0535
|
||||
#define RT1011_BAT_GAIN_1 0x0536
|
||||
#define RT1011_BAT_GAIN_2 0x0538
|
||||
#define RT1011_BAT_GAIN_3 0x053a
|
||||
#define RT1011_BAT_GAIN_4 0x053c
|
||||
#define RT1011_BAT_GAIN_5 0x053d
|
||||
#define RT1011_BAT_GAIN_6 0x053e
|
||||
#define RT1011_BAT_GAIN_7 0x053f
|
||||
#define RT1011_BAT_GAIN_8 0x0540
|
||||
#define RT1011_BAT_GAIN_9 0x0541
|
||||
#define RT1011_BAT_GAIN_10 0x0542
|
||||
#define RT1011_BAT_GAIN_11 0x0543
|
||||
#define RT1011_BAT_RT_THMAX_1 0x0544
|
||||
#define RT1011_BAT_RT_THMAX_2 0x0545
|
||||
#define RT1011_BAT_RT_THMAX_3 0x0546
|
||||
#define RT1011_BAT_RT_THMAX_4 0x0547
|
||||
#define RT1011_BAT_RT_THMAX_5 0x0548
|
||||
#define RT1011_BAT_RT_THMAX_6 0x0549
|
||||
#define RT1011_BAT_RT_THMAX_7 0x054a
|
||||
#define RT1011_BAT_RT_THMAX_8 0x054b
|
||||
#define RT1011_BAT_RT_THMAX_9 0x054c
|
||||
#define RT1011_BAT_RT_THMAX_10 0x054d
|
||||
#define RT1011_BAT_RT_THMAX_11 0x054e
|
||||
#define RT1011_BAT_RT_THMAX_12 0x054f
|
||||
#define RT1011_SPREAD_SPECTURM 0x0568
|
||||
#define RT1011_PRO_GAIN_MODE 0x056a
|
||||
#define RT1011_RT_DRC_CROSS 0x0600
|
||||
#define RT1011_RT_DRC_HB_1 0x0611
|
||||
#define RT1011_RT_DRC_HB_2 0x0612
|
||||
#define RT1011_RT_DRC_HB_3 0x0613
|
||||
#define RT1011_RT_DRC_HB_4 0x0614
|
||||
#define RT1011_RT_DRC_HB_5 0x0615
|
||||
#define RT1011_RT_DRC_HB_6 0x0616
|
||||
#define RT1011_RT_DRC_HB_7 0x0617
|
||||
#define RT1011_RT_DRC_HB_8 0x0618
|
||||
#define RT1011_RT_DRC_BB_1 0x0621
|
||||
#define RT1011_RT_DRC_BB_2 0x0622
|
||||
#define RT1011_RT_DRC_BB_3 0x0623
|
||||
#define RT1011_RT_DRC_BB_4 0x0624
|
||||
#define RT1011_RT_DRC_BB_5 0x0625
|
||||
#define RT1011_RT_DRC_BB_6 0x0626
|
||||
#define RT1011_RT_DRC_BB_7 0x0627
|
||||
#define RT1011_RT_DRC_BB_8 0x0628
|
||||
#define RT1011_RT_DRC_POS_1 0x0631
|
||||
#define RT1011_RT_DRC_POS_2 0x0632
|
||||
#define RT1011_RT_DRC_POS_3 0x0633
|
||||
#define RT1011_RT_DRC_POS_4 0x0634
|
||||
#define RT1011_RT_DRC_POS_5 0x0635
|
||||
#define RT1011_RT_DRC_POS_6 0x0636
|
||||
#define RT1011_RT_DRC_POS_7 0x0637
|
||||
#define RT1011_RT_DRC_POS_8 0x0638
|
||||
#define RT1011_CROSS_BQ_SET_1 0x0702
|
||||
#define RT1011_CROSS_BQ_SET_2 0x0704
|
||||
#define RT1011_BQ_SET_0 0x0706
|
||||
#define RT1011_BQ_SET_1 0x0708
|
||||
#define RT1011_BQ_SET_2 0x070a
|
||||
#define RT1011_BQ_PRE_GAIN_28_16 0x0710
|
||||
#define RT1011_BQ_PRE_GAIN_15_0 0x0711
|
||||
#define RT1011_BQ_POST_GAIN_28_16 0x0712
|
||||
#define RT1011_BQ_POST_GAIN_15_0 0x0713
|
||||
|
||||
#define RT1011_BQ_H0_28_16 0x0720
|
||||
#define RT1011_BQ_A2_15_0 0x0729
|
||||
#define RT1011_BQ_1_H0_28_16 0x0730
|
||||
#define RT1011_BQ_1_A2_15_0 0x0739
|
||||
#define RT1011_BQ_2_H0_28_16 0x0740
|
||||
#define RT1011_BQ_2_A2_15_0 0x0749
|
||||
#define RT1011_BQ_3_H0_28_16 0x0750
|
||||
#define RT1011_BQ_3_A2_15_0 0x0759
|
||||
#define RT1011_BQ_4_H0_28_16 0x0760
|
||||
#define RT1011_BQ_4_A2_15_0 0x0769
|
||||
#define RT1011_BQ_5_H0_28_16 0x0770
|
||||
#define RT1011_BQ_5_A2_15_0 0x0779
|
||||
#define RT1011_BQ_6_H0_28_16 0x0780
|
||||
#define RT1011_BQ_6_A2_15_0 0x0789
|
||||
#define RT1011_BQ_7_H0_28_16 0x0790
|
||||
#define RT1011_BQ_7_A2_15_0 0x0799
|
||||
#define RT1011_BQ_8_H0_28_16 0x07a0
|
||||
#define RT1011_BQ_8_A2_15_0 0x07a9
|
||||
#define RT1011_BQ_9_H0_28_16 0x07b0
|
||||
#define RT1011_BQ_9_A2_15_0 0x07b9
|
||||
#define RT1011_BQ_10_H0_28_16 0x07c0
|
||||
#define RT1011_BQ_10_A2_15_0 0x07c9
|
||||
#define RT1011_TEST_PAD_STATUS 0x1000
|
||||
#define RT1011_SYSTEM_RESET_1 0x1007
|
||||
#define RT1011_SYSTEM_RESET_2 0x1008
|
||||
#define RT1011_SYSTEM_RESET_3 0x1009
|
||||
#define RT1011_ADCDAT_OUT_SOURCE 0x100D
|
||||
#define RT1011_PLL_INTERNAL_SET 0x1010
|
||||
#define RT1011_TEST_OUT_1 0x1020
|
||||
#define RT1011_TEST_OUT_3 0x1024
|
||||
#define RT1011_DC_CALIB_CLASSD_1 0x1200
|
||||
#define RT1011_DC_CALIB_CLASSD_2 0x1202
|
||||
#define RT1011_DC_CALIB_CLASSD_3 0x1204
|
||||
#define RT1011_DC_CALIB_CLASSD_5 0x1208
|
||||
#define RT1011_DC_CALIB_CLASSD_6 0x120a
|
||||
#define RT1011_DC_CALIB_CLASSD_7 0x120c
|
||||
#define RT1011_DC_CALIB_CLASSD_8 0x120e
|
||||
#define RT1011_DC_CALIB_CLASSD_10 0x1212
|
||||
#define RT1011_CLASSD_INTERNAL_SET_1 0x1300
|
||||
#define RT1011_CLASSD_INTERNAL_SET_3 0x1304
|
||||
#define RT1011_CLASSD_INTERNAL_SET_8 0x130c
|
||||
#define RT1011_VREF_LV_1 0x131a
|
||||
#define RT1011_SMART_BOOST_TIMING_1 0x1322
|
||||
#define RT1011_SMART_BOOST_TIMING_36 0x1349
|
||||
#define RT1011_SINE_GEN_REG_1 0x1500
|
||||
#define RT1011_SINE_GEN_REG_2 0x1502
|
||||
#define RT1011_SINE_GEN_REG_3 0x1504
|
||||
#define RT1011_STP_INITIAL_RS_TEMP 0x1510
|
||||
#define RT1011_STP_CALIB_RS_TEMP 0x152a
|
||||
#define RT1011_INIT_RECIPROCAL_REG_24_16 0x1538
|
||||
#define RT1011_INIT_RECIPROCAL_REG_15_0 0x1539
|
||||
#define RT1011_STP_ALPHA_RECIPROCAL_MSB 0x153e
|
||||
#define RT1011_SPK_RESISTANCE_1 0x1544
|
||||
#define RT1011_SPK_RESISTANCE_2 0x1546
|
||||
#define RT1011_SPK_THERMAL 0x1548
|
||||
#define RT1011_STP_OTP_TH 0x1552
|
||||
#define RT1011_ALC_BK_GAIN_O 0x1554
|
||||
#define RT1011_ALC_BK_GAIN_O_PRE 0x1556
|
||||
#define RT1011_SPK_DC_O_23_16 0x155a
|
||||
#define RT1011_SPK_DC_O_15_0 0x155c
|
||||
#define RT1011_INIT_RECIPROCAL_SYN_24_16 0x1560
|
||||
#define RT1011_INIT_RECIPROCAL_SYN_15_0 0x1562
|
||||
#define RT1011_STP_BQ_1_A1_L_28_16 0x1570
|
||||
#define RT1011_STP_BQ_1_H0_R_15_0 0x1583
|
||||
#define RT1011_STP_BQ_2_A1_L_28_16 0x1590
|
||||
#define RT1011_SPK_EXCURSION_23_16 0x15be
|
||||
#define RT1011_SPK_EXCURSION_15_0 0x15bf
|
||||
#define RT1011_SEP_MAIN_OUT_23_16 0x15c0
|
||||
#define RT1011_SEP_MAIN_OUT_15_0 0x15c1
|
||||
#define RT1011_SEP_RE_REG_15_0 0x15f9
|
||||
#define RT1011_DRC_CF_PARAMS_1 0x1600
|
||||
#define RT1011_DRC_CF_PARAMS_12 0x160b
|
||||
#define RT1011_ALC_DRC_HB_INTERNAL_1 0x1611
|
||||
#define RT1011_ALC_DRC_HB_INTERNAL_5 0x1615
|
||||
#define RT1011_ALC_DRC_HB_INTERNAL_6 0x1616
|
||||
#define RT1011_ALC_DRC_HB_INTERNAL_7 0x1617
|
||||
#define RT1011_ALC_DRC_BB_INTERNAL_1 0x1621
|
||||
#define RT1011_ALC_DRC_BB_INTERNAL_5 0x1625
|
||||
#define RT1011_ALC_DRC_BB_INTERNAL_6 0x1626
|
||||
#define RT1011_ALC_DRC_BB_INTERNAL_7 0x1627
|
||||
#define RT1011_ALC_DRC_POS_INTERNAL_1 0x1631
|
||||
#define RT1011_ALC_DRC_POS_INTERNAL_5 0x1635
|
||||
#define RT1011_ALC_DRC_POS_INTERNAL_6 0x1636
|
||||
#define RT1011_ALC_DRC_POS_INTERNAL_7 0x1637
|
||||
#define RT1011_ALC_DRC_POS_INTERNAL_8 0x1638
|
||||
#define RT1011_ALC_DRC_POS_INTERNAL_9 0x163a
|
||||
#define RT1011_ALC_DRC_POS_INTERNAL_10 0x163c
|
||||
#define RT1011_ALC_DRC_POS_INTERNAL_11 0x163e
|
||||
#define RT1011_BQ_1_PARAMS_CHECK_5 0x1648
|
||||
#define RT1011_BQ_2_PARAMS_CHECK_1 0x1650
|
||||
#define RT1011_BQ_2_PARAMS_CHECK_5 0x1658
|
||||
#define RT1011_BQ_3_PARAMS_CHECK_1 0x1660
|
||||
#define RT1011_BQ_3_PARAMS_CHECK_5 0x1668
|
||||
#define RT1011_BQ_4_PARAMS_CHECK_1 0x1670
|
||||
#define RT1011_BQ_4_PARAMS_CHECK_5 0x1678
|
||||
#define RT1011_BQ_5_PARAMS_CHECK_1 0x1680
|
||||
#define RT1011_BQ_5_PARAMS_CHECK_5 0x1688
|
||||
#define RT1011_BQ_6_PARAMS_CHECK_1 0x1690
|
||||
#define RT1011_BQ_6_PARAMS_CHECK_5 0x1698
|
||||
#define RT1011_BQ_7_PARAMS_CHECK_1 0x1700
|
||||
#define RT1011_BQ_7_PARAMS_CHECK_5 0x1708
|
||||
#define RT1011_BQ_8_PARAMS_CHECK_1 0x1710
|
||||
#define RT1011_BQ_8_PARAMS_CHECK_5 0x1718
|
||||
#define RT1011_BQ_9_PARAMS_CHECK_1 0x1720
|
||||
#define RT1011_BQ_9_PARAMS_CHECK_5 0x1728
|
||||
#define RT1011_BQ_10_PARAMS_CHECK_1 0x1730
|
||||
#define RT1011_BQ_10_PARAMS_CHECK_5 0x1738
|
||||
#define RT1011_IRQ_1 0x173a
|
||||
#define RT1011_PART_NUMBER_EFUSE 0x173e
|
||||
#define RT1011_EFUSE_CONTROL_1 0x17bb
|
||||
#define RT1011_EFUSE_CONTROL_2 0x17bd
|
||||
#define RT1011_EFUSE_MATCH_DONE 0x17cb
|
||||
#define RT1011_EFUSE_ADC_OFFSET_18_16 0x17e5
|
||||
#define RT1011_EFUSE_ADC_OFFSET_15_0 0x17e7
|
||||
#define RT1011_EFUSE_DAC_OFFSET_G0_20_16 0x17e9
|
||||
#define RT1011_EFUSE_DAC_OFFSET_G0_15_0 0x17eb
|
||||
#define RT1011_EFUSE_DAC_OFFSET_G1_20_16 0x17ed
|
||||
#define RT1011_EFUSE_DAC_OFFSET_G1_15_0 0x17ef
|
||||
#define RT1011_EFUSE_READ_R0_3_15_0 0x1803
|
||||
#define RT1011_MAX_REG 0x1803
|
||||
#define RT1011_REG_DISP_LEN 23
|
||||
|
||||
|
||||
/* CLOCK-2 (0x0004) */
|
||||
#define RT1011_FS_SYS_PRE_MASK (0x3 << 14)
|
||||
#define RT1011_FS_SYS_PRE_SFT 14
|
||||
#define RT1011_FS_SYS_PRE_MCLK (0x0 << 14)
|
||||
#define RT1011_FS_SYS_PRE_BCLK (0x1 << 14)
|
||||
#define RT1011_FS_SYS_PRE_PLL1 (0x2 << 14)
|
||||
#define RT1011_FS_SYS_PRE_RCCLK (0x3 << 14)
|
||||
#define RT1011_PLL1_SRC_MASK (0x1 << 13)
|
||||
#define RT1011_PLL1_SRC_SFT 13
|
||||
#define RT1011_PLL1_SRC_PLL2 (0x0 << 13)
|
||||
#define RT1011_PLL1_SRC_BCLK (0x1 << 13)
|
||||
#define RT1011_PLL2_SRC_MASK (0x1 << 12)
|
||||
#define RT1011_PLL2_SRC_SFT 12
|
||||
#define RT1011_PLL2_SRC_MCLK (0x0 << 12)
|
||||
#define RT1011_PLL2_SRC_RCCLK (0x1 << 12)
|
||||
#define RT1011_PLL2_SRC_DIV_MASK (0x3 << 10)
|
||||
#define RT1011_PLL2_SRC_DIV_SFT 10
|
||||
#define RT1011_SRCIN_DIV_MASK (0x3 << 8)
|
||||
#define RT1011_SRCIN_DIV_SFT 8
|
||||
#define RT1011_FS_SYS_DIV_MASK (0x7 << 4)
|
||||
#define RT1011_FS_SYS_DIV_SFT 4
|
||||
|
||||
/* PLL-1 (0x000a) */
|
||||
#define RT1011_PLL1_QM_MASK (0xf << 12)
|
||||
#define RT1011_PLL1_QM_SFT 12
|
||||
#define RT1011_PLL1_BPM_MASK (0x1 << 11)
|
||||
#define RT1011_PLL1_BPM_SFT 11
|
||||
#define RT1011_PLL1_BPM (0x1 << 11)
|
||||
#define RT1011_PLL1_QN_MASK (0x1ff << 0)
|
||||
#define RT1011_PLL1_QN_SFT 0
|
||||
|
||||
/* PLL-2 (0x000c) */
|
||||
#define RT1011_PLL2_BPK_MASK (0x1 << 5)
|
||||
#define RT1011_PLL2_BPK_SFT 5
|
||||
#define RT1011_PLL2_BPK (0x1 << 5)
|
||||
#define RT1011_PLL2_QK_MASK (0x1f << 0)
|
||||
#define RT1011_PLL2_QK_SFT 0
|
||||
|
||||
/* Clock Detect (0x0020) */
|
||||
#define RT1011_EN_MCLK_DET_MASK (0x1 << 15)
|
||||
#define RT1011_EN_MCLK_DET_SFT 15
|
||||
#define RT1011_EN_MCLK_DET (0x1 << 15)
|
||||
|
||||
/* DAC Setting-2 (0x0104) */
|
||||
#define RT1011_EN_CKGEN_DAC_MASK (0x1 << 13)
|
||||
#define RT1011_EN_CKGEN_DAC_SFT 13
|
||||
#define RT1011_EN_CKGEN_DAC (0x1 << 13)
|
||||
|
||||
/* DAC Setting-3 (0x0106) */
|
||||
#define RT1011_DA_MUTE_EN_MASK (0x1 << 15)
|
||||
#define RT1011_DA_MUTE_EN_SFT 15
|
||||
|
||||
/* ADC Setting-5 (0x0110) */
|
||||
#define RT1011_AD_EN_CKGEN_ADC_MASK (0x1 << 9)
|
||||
#define RT1011_AD_EN_CKGEN_ADC_SFT 9
|
||||
#define RT1011_AD_EN_CKGEN_ADC (0x1 << 9)
|
||||
|
||||
/* TDM Total Setting (0x0111) */
|
||||
#define RT1011_I2S_TDM_MS_MASK (0x1 << 14)
|
||||
#define RT1011_I2S_TDM_MS_SFT 14
|
||||
#define RT1011_I2S_TDM_MS_S (0x0 << 14)
|
||||
#define RT1011_I2S_TDM_MS_M (0x1 << 14)
|
||||
#define RT1011_I2S_TX_DL_MASK (0x7 << 8)
|
||||
#define RT1011_I2S_TX_DL_SFT 8
|
||||
#define RT1011_I2S_TX_DL_16B (0x0 << 8)
|
||||
#define RT1011_I2S_TX_DL_20B (0x1 << 8)
|
||||
#define RT1011_I2S_TX_DL_24B (0x2 << 8)
|
||||
#define RT1011_I2S_TX_DL_32B (0x3 << 8)
|
||||
#define RT1011_I2S_TX_DL_8B (0x4 << 8)
|
||||
#define RT1011_I2S_RX_DL_MASK (0x7 << 5)
|
||||
#define RT1011_I2S_RX_DL_SFT 5
|
||||
#define RT1011_I2S_RX_DL_16B (0x0 << 5)
|
||||
#define RT1011_I2S_RX_DL_20B (0x1 << 5)
|
||||
#define RT1011_I2S_RX_DL_24B (0x2 << 5)
|
||||
#define RT1011_I2S_RX_DL_32B (0x3 << 5)
|
||||
#define RT1011_I2S_RX_DL_8B (0x4 << 5)
|
||||
#define RT1011_ADCDAT1_PIN_CONFIG (0x1 << 4)
|
||||
#define RT1011_ADCDAT1_OUTPUT (0x0 << 4)
|
||||
#define RT1011_ADCDAT1_INPUT (0x1 << 4)
|
||||
#define RT1011_ADCDAT2_PIN_CONFIG (0x1 << 3)
|
||||
#define RT1011_ADCDAT2_OUTPUT (0x0 << 3)
|
||||
#define RT1011_ADCDAT2_INPUT (0x1 << 3)
|
||||
#define RT1011_I2S_TDM_DF_MASK (0x7 << 0)
|
||||
#define RT1011_I2S_TDM_DF_SFT 0
|
||||
#define RT1011_I2S_TDM_DF_I2S (0x0)
|
||||
#define RT1011_I2S_TDM_DF_LEFT (0x1)
|
||||
#define RT1011_I2S_TDM_DF_PCM_A (0x2)
|
||||
#define RT1011_I2S_TDM_DF_PCM_B (0x3)
|
||||
#define RT1011_I2S_TDM_DF_PCM_A_N (0x6)
|
||||
#define RT1011_I2S_TDM_DF_PCM_B_N (0x7)
|
||||
|
||||
/* TDM_tcon Setting (0x0112) */
|
||||
#define RT1011_TCON_DF_MASK (0x7 << 13)
|
||||
#define RT1011_TCON_DF_SFT 13
|
||||
#define RT1011_TCON_DF_I2S (0x0 << 13)
|
||||
#define RT1011_TCON_DF_LEFT (0x1 << 13)
|
||||
#define RT1011_TCON_DF_PCM_A (0x2 << 13)
|
||||
#define RT1011_TCON_DF_PCM_B (0x3 << 13)
|
||||
#define RT1011_TCON_DF_PCM_A_N (0x6 << 13)
|
||||
#define RT1011_TCON_DF_PCM_B_N (0x7 << 13)
|
||||
#define RT1011_TCON_BCLK_SEL_MASK (0x3 << 10)
|
||||
#define RT1011_TCON_BCLK_SEL_SFT 10
|
||||
#define RT1011_TCON_BCLK_SEL_32FS (0x0 << 10)
|
||||
#define RT1011_TCON_BCLK_SEL_64FS (0x1 << 10)
|
||||
#define RT1011_TCON_BCLK_SEL_128FS (0x2 << 10)
|
||||
#define RT1011_TCON_BCLK_SEL_256FS (0x3 << 10)
|
||||
#define RT1011_TCON_CH_LEN_MASK (0x3 << 5)
|
||||
#define RT1011_TCON_CH_LEN_SFT 5
|
||||
#define RT1011_TCON_CH_LEN_16B (0x0 << 5)
|
||||
#define RT1011_TCON_CH_LEN_20B (0x1 << 5)
|
||||
#define RT1011_TCON_CH_LEN_24B (0x2 << 5)
|
||||
#define RT1011_TCON_CH_LEN_32B (0x3 << 5)
|
||||
#define RT1011_TCON_BCLK_MST_MASK (0x1 << 4)
|
||||
#define RT1011_TCON_BCLK_MST_SFT 4
|
||||
#define RT1011_TCON_BCLK_MST_INV (0x1 << 4)
|
||||
|
||||
/* TDM1 Setting-1 (0x0114) */
|
||||
#define RT1011_TDM_INV_BCLK_MASK (0x1 << 15)
|
||||
#define RT1011_TDM_INV_BCLK_SFT 15
|
||||
#define RT1011_TDM_INV_BCLK (0x1 << 15)
|
||||
#define RT1011_I2S_CH_TX_MASK (0x3 << 10)
|
||||
#define RT1011_I2S_CH_TX_SFT 10
|
||||
#define RT1011_I2S_TX_2CH (0x0 << 10)
|
||||
#define RT1011_I2S_TX_4CH (0x1 << 10)
|
||||
#define RT1011_I2S_TX_6CH (0x2 << 10)
|
||||
#define RT1011_I2S_TX_8CH (0x3 << 10)
|
||||
#define RT1011_I2S_CH_RX_MASK (0x3 << 8)
|
||||
#define RT1011_I2S_CH_RX_SFT 8
|
||||
#define RT1011_I2S_RX_2CH (0x0 << 8)
|
||||
#define RT1011_I2S_RX_4CH (0x1 << 8)
|
||||
#define RT1011_I2S_RX_6CH (0x2 << 8)
|
||||
#define RT1011_I2S_RX_8CH (0x3 << 8)
|
||||
#define RT1011_I2S_LR_CH_SEL_MASK (0x1 << 7)
|
||||
#define RT1011_I2S_LR_CH_SEL_SFT 7
|
||||
#define RT1011_I2S_LEFT_CH_SEL (0x0 << 7)
|
||||
#define RT1011_I2S_RIGHT_CH_SEL (0x1 << 7)
|
||||
#define RT1011_I2S_CH_TX_LEN_MASK (0x7 << 4)
|
||||
#define RT1011_I2S_CH_TX_LEN_SFT 4
|
||||
#define RT1011_I2S_CH_TX_LEN_16B (0x0 << 4)
|
||||
#define RT1011_I2S_CH_TX_LEN_20B (0x1 << 4)
|
||||
#define RT1011_I2S_CH_TX_LEN_24B (0x2 << 4)
|
||||
#define RT1011_I2S_CH_TX_LEN_32B (0x3 << 4)
|
||||
#define RT1011_I2S_CH_TX_LEN_8B (0x4 << 4)
|
||||
#define RT1011_I2S_CH_RX_LEN_MASK (0x7 << 0)
|
||||
#define RT1011_I2S_CH_RX_LEN_SFT 0
|
||||
#define RT1011_I2S_CH_RX_LEN_16B (0x0 << 0)
|
||||
#define RT1011_I2S_CH_RX_LEN_20B (0x1 << 0)
|
||||
#define RT1011_I2S_CH_RX_LEN_24B (0x2 << 0)
|
||||
#define RT1011_I2S_CH_RX_LEN_32B (0x3 << 0)
|
||||
#define RT1011_I2S_CH_RX_LEN_8B (0x4 << 0)
|
||||
|
||||
/* TDM1 Setting-2 (0x0116) */
|
||||
#define RT1011_TDM_I2S_DOCK_ADCDAT_LEN_1_MASK (0x7 << 13)
|
||||
#define RT1011_TDM_I2S_DOCK_ADCDAT_2CH (0x1 << 13)
|
||||
#define RT1011_TDM_I2S_DOCK_ADCDAT_4CH (0x3 << 13)
|
||||
#define RT1011_TDM_I2S_DOCK_ADCDAT_6CH (0x5 << 13)
|
||||
#define RT1011_TDM_I2S_DOCK_ADCDAT_8CH (0x7 << 13)
|
||||
#define RT1011_TDM_I2S_DOCK_EN_1_MASK (0x1 << 3)
|
||||
#define RT1011_TDM_I2S_DOCK_EN_1_SFT 3
|
||||
#define RT1011_TDM_I2S_DOCK_EN_1 (0x1 << 3)
|
||||
|
||||
/* TDM2 Setting-2 (0x0120) */
|
||||
#define RT1011_TDM_I2S_DOCK_ADCDAT_LEN_2_MASK (0x7 << 13)
|
||||
#define RT1011_TDM_I2S_DOCK_EN_2_MASK (0x1 << 3)
|
||||
#define RT1011_TDM_I2S_DOCK_EN_2_SFT 3
|
||||
#define RT1011_TDM_I2S_DOCK_EN_2 (0x1 << 3)
|
||||
|
||||
/* MIXER 1 (0x0300) */
|
||||
#define RT1011_MIXER_MUTE_MIX_I_MASK (0x1 << 15)
|
||||
#define RT1011_MIXER_MUTE_MIX_I_SFT 15
|
||||
#define RT1011_MIXER_MUTE_MIX_I (0x1 << 15)
|
||||
#define RT1011_MIXER_MUTE_SUM_I_MASK (0x1 << 14)
|
||||
#define RT1011_MIXER_MUTE_SUM_I_SFT 14
|
||||
#define RT1011_MIXER_MUTE_SUM_I (0x1 << 14)
|
||||
#define RT1011_MIXER_MUTE_MIX_V_MASK (0x1 << 7)
|
||||
#define RT1011_MIXER_MUTE_MIX_V_SFT 7
|
||||
#define RT1011_MIXER_MUTE_MIX_V (0x1 << 7)
|
||||
#define RT1011_MIXER_MUTE_SUM_V_MASK (0x1 << 6)
|
||||
#define RT1011_MIXER_MUTE_SUM_V_SFT 6
|
||||
#define RT1011_MIXER_MUTE_SUM_V (0x1 << 6)
|
||||
|
||||
/* Analog Temperature Sensor (0x0316) */
|
||||
#define RT1011_POW_TEMP_REG (0x1 << 2)
|
||||
#define RT1011_POW_TEMP_REG_BIT 2
|
||||
|
||||
/* POWER-1 (0x0322) */
|
||||
#define RT1011_POW_LDO2 (0x1 << 15)
|
||||
#define RT1011_POW_LDO2_BIT 15
|
||||
#define RT1011_POW_DAC (0x1 << 14)
|
||||
#define RT1011_POW_DAC_BIT 14
|
||||
#define RT1011_POW_CLK12M (0x1 << 13)
|
||||
#define RT1011_POW_CLK12M_BIT 13
|
||||
#define RT1011_POW_TEMP (0x1 << 12)
|
||||
#define RT1011_POW_TEMP_BIT 12
|
||||
#define RT1011_POW_ISENSE_SPK (0x1 << 7)
|
||||
#define RT1011_POW_ISENSE_SPK_BIT 7
|
||||
#define RT1011_POW_LPF_SPK (0x1 << 6)
|
||||
#define RT1011_POW_LPF_SPK_BIT 6
|
||||
#define RT1011_POW_VSENSE_SPK (0x1 << 5)
|
||||
#define RT1011_POW_VSENSE_SPK_BIT 5
|
||||
#define RT1011_POW_TWO_BATTERY_SPK (0x1 << 4)
|
||||
#define RT1011_POW_TWO_BATTERY_SPK_BIT 4
|
||||
|
||||
/* POWER-2 (0x0324) */
|
||||
#define RT1011_PLLEN (0x1 << 2)
|
||||
#define RT1011_PLLEN_BIT 2
|
||||
#define RT1011_POW_BG (0x1 << 1)
|
||||
#define RT1011_POW_BG_BIT 1
|
||||
#define RT1011_POW_BG_MBIAS_LV (0x1 << 0)
|
||||
#define RT1011_POW_BG_MBIAS_LV_BIT 0
|
||||
|
||||
/* POWER-3 (0x0326) */
|
||||
#define RT1011_POW_DET_SPKVDD (0x1 << 15)
|
||||
#define RT1011_POW_DET_SPKVDD_BIT 15
|
||||
#define RT1011_POW_DET_VBAT (0x1 << 14)
|
||||
#define RT1011_POW_DET_VBAT_BIT 14
|
||||
#define RT1011_POW_FC (0x1 << 13)
|
||||
#define RT1011_POW_FC_BIT 13
|
||||
#define RT1011_POW_MBIAS_LV (0x1 << 12)
|
||||
#define RT1011_POW_MBIAS_LV_BIT 12
|
||||
#define RT1011_POW_ADC_I (0x1 << 11)
|
||||
#define RT1011_POW_ADC_I_BIT 11
|
||||
#define RT1011_POW_ADC_V (0x1 << 10)
|
||||
#define RT1011_POW_ADC_V_BIT 10
|
||||
#define RT1011_POW_ADC_T (0x1 << 9)
|
||||
#define RT1011_POW_ADC_T_BIT 9
|
||||
#define RT1011_POWD_ADC_T (0x1 << 8)
|
||||
#define RT1011_POWD_ADC_T_BIT 8
|
||||
#define RT1011_POW_MIX_I (0x1 << 7)
|
||||
#define RT1011_POW_MIX_I_BIT 7
|
||||
#define RT1011_POW_MIX_V (0x1 << 6)
|
||||
#define RT1011_POW_MIX_V_BIT 6
|
||||
#define RT1011_POW_SUM_I (0x1 << 5)
|
||||
#define RT1011_POW_SUM_I_BIT 5
|
||||
#define RT1011_POW_SUM_V (0x1 << 4)
|
||||
#define RT1011_POW_SUM_V_BIT 4
|
||||
#define RT1011_POW_MIX_T (0x1 << 2)
|
||||
#define RT1011_POW_MIX_T_BIT 2
|
||||
#define RT1011_BYPASS_MIX_T (0x1 << 1)
|
||||
#define RT1011_BYPASS_MIX_T_BIT 1
|
||||
#define RT1011_POW_VREF_LV (0x1 << 0)
|
||||
#define RT1011_POW_VREF_LV_BIT 0
|
||||
|
||||
/* POWER-4 (0x0328) */
|
||||
#define RT1011_POW_EN_SWR (0x1 << 12)
|
||||
#define RT1011_POW_EN_SWR_BIT 12
|
||||
#define RT1011_POW_EN_PASS_BGOK_SWR (0x1 << 10)
|
||||
#define RT1011_POW_EN_PASS_BGOK_SWR_BIT 10
|
||||
#define RT1011_POW_EN_PASS_VPOK_SWR (0x1 << 9)
|
||||
#define RT1011_POW_EN_PASS_VPOK_SWR_BIT 9
|
||||
|
||||
/* POWER-9 (0x032d) */
|
||||
#define RT1011_POW_SDB_REG_MASK (0x1 << 9)
|
||||
#define RT1011_POW_SDB_REG_BIT 9
|
||||
#define RT1011_POW_SDB_REG (0x1 << 9)
|
||||
#define RT1011_POW_SEL_SDB_MODE_MASK (0x1 << 6)
|
||||
#define RT1011_POW_SEL_SDB_MODE_BIT 6
|
||||
#define RT1011_POW_SEL_SDB_MODE (0x1 << 6)
|
||||
#define RT1011_POW_MNL_SDB_MASK (0x1 << 5)
|
||||
#define RT1011_POW_MNL_SDB_BIT 5
|
||||
#define RT1011_POW_MNL_SDB (0x1 << 5)
|
||||
|
||||
/* SPK Protection-Temperature Protection (0x050c) */
|
||||
#define RT1011_STP_EN_MASK (0x1 << 15)
|
||||
#define RT1011_STP_EN_BIT 15
|
||||
#define RT1011_STP_EN (0x1 << 15)
|
||||
#define RT1011_STP_RS_CLB_EN_MASK (0x1 << 14)
|
||||
#define RT1011_STP_RS_CLB_EN_BIT 14
|
||||
#define RT1011_STP_RS_CLB_EN (0x1 << 14)
|
||||
|
||||
/* SPK Protection-Temperature Protection-4 (0x0510) */
|
||||
#define RT1011_STP_R0_SELECT_MASK (0x3 << 6)
|
||||
#define RT1011_STP_R0_SELECT_EFUSE (0x0 << 6)
|
||||
#define RT1011_STP_R0_SELECT_START_VAL (0x1 << 6)
|
||||
#define RT1011_STP_R0_SELECT_REG (0x2 << 6)
|
||||
#define RT1011_STP_R0_SELECT_FORCE_ZERO (0x3 << 6)
|
||||
|
||||
/* SPK Protection-Temperature Protection-6 (0x0512) */
|
||||
#define RT1011_STP_R0_EN_MASK (0x1 << 7)
|
||||
#define RT1011_STP_R0_EN_BIT 7
|
||||
#define RT1011_STP_R0_EN (0x1 << 7)
|
||||
#define RT1011_STP_T0_EN_MASK (0x1 << 6)
|
||||
#define RT1011_STP_T0_EN_BIT 6
|
||||
#define RT1011_STP_T0_EN (0x1 << 6)
|
||||
|
||||
/* ClassD Internal Setting-1 (0x1300) */
|
||||
#define RT1011_DRIVER_READY_SPK (0x1 << 12)
|
||||
#define RT1011_DRIVER_READY_SPK_BIT 12
|
||||
#define RT1011_RECV_MODE_SPK_MASK (0x1 << 5)
|
||||
#define RT1011_SPK_MODE (0x0 << 5)
|
||||
#define RT1011_RECV_MODE (0x1 << 5)
|
||||
#define RT1011_RECV_MODE_SPK_BIT 5
|
||||
|
||||
/* ClassD Internal Setting-3 (0x1304) */
|
||||
#define RT1011_REG_GAIN_CLASSD_RI_SPK_MASK (0x7 << 12)
|
||||
#define RT1011_REG_GAIN_CLASSD_RI_410K (0x0 << 12)
|
||||
#define RT1011_REG_GAIN_CLASSD_RI_95K (0x1 << 12)
|
||||
#define RT1011_REG_GAIN_CLASSD_RI_82P5K (0x2 << 12)
|
||||
#define RT1011_REG_GAIN_CLASSD_RI_72P5K (0x3 << 12)
|
||||
#define RT1011_REG_GAIN_CLASSD_RI_62P5K (0x4 << 12)
|
||||
|
||||
/* ClassD Internal Setting-8 (0x130c) */
|
||||
#define RT1011_TM_PORPVDD_SPK (0x1 << 1)
|
||||
#define RT1011_TM_PORPVDD_SPK_BIT 1
|
||||
|
||||
/* SPK Protection-Temperature Protection-SINE_GEN_REG-1 (0x1500) */
|
||||
#define RT1011_STP_SIN_GEN_EN_MASK (0x1 << 13)
|
||||
#define RT1011_STP_SIN_GEN_EN (0x1 << 13)
|
||||
#define RT1011_STP_SIN_GEN_EN_BIT 13
|
||||
|
||||
|
||||
/* System Clock Source */
|
||||
enum {
|
||||
RT1011_FS_SYS_PRE_S_MCLK,
|
||||
RT1011_FS_SYS_PRE_S_BCLK,
|
||||
RT1011_FS_SYS_PRE_S_PLL1,
|
||||
RT1011_FS_SYS_PRE_S_RCCLK, /* 12M Hz */
|
||||
};
|
||||
|
||||
/* PLL Source 1/2 */
|
||||
enum {
|
||||
RT1011_PLL1_S_BCLK,
|
||||
RT1011_PLL2_S_MCLK,
|
||||
RT1011_PLL2_S_RCCLK, /* 12M Hz */
|
||||
};
|
||||
|
||||
enum {
|
||||
RT1011_AIF1,
|
||||
RT1011_AIFS
|
||||
};
|
||||
|
||||
/* BiQual & DRC related settings */
|
||||
#define RT1011_BQ_DRC_NUM 128
|
||||
struct rt1011_bq_drc_params {
|
||||
unsigned short val;
|
||||
unsigned short reg;
|
||||
#ifdef CONFIG_64BIT
|
||||
unsigned int reserved;
|
||||
#endif
|
||||
};
|
||||
enum {
|
||||
RT1011_ADVMODE_INITIAL_SET,
|
||||
RT1011_ADVMODE_SEP_BQ_COEFF,
|
||||
RT1011_ADVMODE_EQ_BQ_COEFF,
|
||||
RT1011_ADVMODE_BQ_UI_COEFF,
|
||||
RT1011_ADVMODE_SMARTBOOST_COEFF,
|
||||
RT1011_ADVMODE_NUM,
|
||||
};
|
||||
|
||||
struct rt1011_priv {
|
||||
struct snd_soc_component *component;
|
||||
struct regmap *regmap;
|
||||
struct work_struct cali_work;
|
||||
struct rt1011_bq_drc_params **bq_drc_params;
|
||||
|
||||
int sysclk;
|
||||
int sysclk_src;
|
||||
int lrck;
|
||||
int bclk;
|
||||
int id;
|
||||
|
||||
int pll_src;
|
||||
int pll_in;
|
||||
int pll_out;
|
||||
|
||||
int bq_drc_set;
|
||||
unsigned int r0_reg;
|
||||
int recv_spk_mode;
|
||||
};
|
||||
|
||||
#endif /* end of _RT1011_H_ */
|
898
sound/soc/codecs/rt1308.c
Executable file
898
sound/soc/codecs/rt1308.c
Executable file
|
@ -0,0 +1,898 @@
|
|||
/*
|
||||
* rt1308.c -- RT1308 ALSA SoC amplifier component driver
|
||||
*
|
||||
* Copyright 2019 Realtek Semiconductor Corp.
|
||||
* Author: Derek Fang <derek.fang@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.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/firmware.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 "rt1308.h"
|
||||
|
||||
static const struct reg_sequence init_list[] = {
|
||||
|
||||
{ RT1308_I2C_I2S_SDW_SET, 0x01014005 },
|
||||
{ RT1308_CLASS_D_SET_2, 0x227f5501 },
|
||||
{ RT1308_PADS_1, 0x50150505 },
|
||||
{ RT1308_VREF, 0x18100000 },
|
||||
{ RT1308_IV_SENSE, 0x87010000 },
|
||||
{ RT1308_DUMMY_REG, 0x00000200 },
|
||||
{ RT1308_SIL_DET, 0x61c30000 },
|
||||
{ RT1308_DC_CAL_2, 0x00ffff00 },
|
||||
{ RT1308_CLK_DET, 0x01000000 },
|
||||
{ RT1308_POWER_STATUS, 0x00800000 },
|
||||
{ RT1308_DAC_SET, 0xafaf0700 },
|
||||
|
||||
};
|
||||
#define RT1308_INIT_REG_LEN ARRAY_SIZE(init_list)
|
||||
|
||||
struct rt1308_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;
|
||||
};
|
||||
|
||||
static const struct reg_default rt1308_reg[] = {
|
||||
|
||||
{ 0x01, 0x1f3f5f00 },
|
||||
{ 0x02, 0x07000000 },
|
||||
{ 0x03, 0x80003e00 },
|
||||
{ 0x04, 0x80800600 },
|
||||
{ 0x05, 0x0aaa1a0a },
|
||||
{ 0x06, 0x52000000 },
|
||||
{ 0x07, 0x00000000 },
|
||||
{ 0x08, 0x00600000 },
|
||||
{ 0x09, 0xe1030000 },
|
||||
{ 0x0a, 0x00000000 },
|
||||
{ 0x0b, 0x30000000 },
|
||||
{ 0x0c, 0x7fff7000 },
|
||||
{ 0x10, 0xffff0700 },
|
||||
{ 0x11, 0x0a000000 },
|
||||
{ 0x12, 0x60040000 },
|
||||
{ 0x13, 0x00000000 },
|
||||
{ 0x14, 0x0f300000 },
|
||||
{ 0x15, 0x00000022 },
|
||||
{ 0x16, 0x02000000 },
|
||||
{ 0x17, 0x01004045 },
|
||||
{ 0x18, 0x00000000 },
|
||||
{ 0x19, 0x00000000 },
|
||||
{ 0x1a, 0x80000000 },
|
||||
{ 0x1b, 0x10325476 },
|
||||
{ 0x1c, 0x1d1d0000 },
|
||||
{ 0x20, 0xd2101300 },
|
||||
{ 0x21, 0xf3ffff00 },
|
||||
{ 0x22, 0x00000000 },
|
||||
{ 0x23, 0x00000000 },
|
||||
{ 0x24, 0x00000000 },
|
||||
{ 0x25, 0x00000000 },
|
||||
{ 0x26, 0x00000000 },
|
||||
{ 0x27, 0x00000000 },
|
||||
{ 0x28, 0x00000000 },
|
||||
{ 0x29, 0x00000000 },
|
||||
{ 0x2a, 0x00000000 },
|
||||
{ 0x2b, 0x00000000 },
|
||||
{ 0x2c, 0x00000000 },
|
||||
{ 0x2d, 0x00000000 },
|
||||
{ 0x2e, 0x00000000 },
|
||||
{ 0x2f, 0x00000000 },
|
||||
{ 0x30, 0x01000000 },
|
||||
{ 0x31, 0x20025501 },
|
||||
{ 0x32, 0x00000000 },
|
||||
{ 0x33, 0x105a0000 },
|
||||
{ 0x34, 0x10100000 },
|
||||
{ 0x35, 0x2aaa52aa },
|
||||
{ 0x36, 0x00c00000 },
|
||||
{ 0x37, 0x20046100 },
|
||||
{ 0x50, 0x10022f00 },
|
||||
{ 0x51, 0x003c0000 },
|
||||
{ 0x54, 0x04000000 },
|
||||
{ 0x55, 0x01000000 },
|
||||
{ 0x56, 0x02000000 },
|
||||
{ 0x57, 0x02000000 },
|
||||
{ 0x58, 0x02000000 },
|
||||
{ 0x59, 0x02000000 },
|
||||
{ 0x5b, 0x02000000 },
|
||||
{ 0x5c, 0x00000000 },
|
||||
{ 0x5d, 0x00000000 },
|
||||
{ 0x5e, 0x00000000 },
|
||||
{ 0x5f, 0x00000000 },
|
||||
{ 0x60, 0x02000000 },
|
||||
{ 0x61, 0x00000000 },
|
||||
{ 0x62, 0x00000000 },
|
||||
{ 0x63, 0x00000000 },
|
||||
{ 0x64, 0x00000000 },
|
||||
{ 0x65, 0x02000000 },
|
||||
{ 0x66, 0x00000000 },
|
||||
{ 0x67, 0x00000000 },
|
||||
{ 0x68, 0x00000000 },
|
||||
{ 0x69, 0x00000000 },
|
||||
{ 0x6a, 0x02000000 },
|
||||
{ 0x6c, 0x00000000 },
|
||||
{ 0x6d, 0x00000000 },
|
||||
{ 0x6e, 0x00000000 },
|
||||
{ 0x70, 0x10EC1308 },
|
||||
{ 0x71, 0x00000000 },
|
||||
{ 0x72, 0x00000000 },
|
||||
{ 0x73, 0x00000000 },
|
||||
{ 0x74, 0x00000000 },
|
||||
{ 0x75, 0x00000000 },
|
||||
{ 0x76, 0x00000000 },
|
||||
{ 0x77, 0x00000000 },
|
||||
{ 0x78, 0x00000000 },
|
||||
{ 0x79, 0x00000000 },
|
||||
{ 0x7a, 0x00000000 },
|
||||
{ 0x7b, 0x00000000 },
|
||||
{ 0x7c, 0x00000000 },
|
||||
{ 0x7d, 0x00000000 },
|
||||
{ 0x7e, 0x00000000 },
|
||||
{ 0x7f, 0x00020f00 },
|
||||
{ 0x80, 0x00000000 },
|
||||
{ 0x81, 0x00000000 },
|
||||
{ 0x82, 0x00000000 },
|
||||
{ 0x83, 0x00000000 },
|
||||
{ 0x84, 0x00000000 },
|
||||
{ 0x85, 0x00000000 },
|
||||
{ 0x86, 0x00000000 },
|
||||
{ 0x87, 0x00000000 },
|
||||
{ 0x88, 0x00000000 },
|
||||
{ 0x89, 0x00000000 },
|
||||
{ 0x8a, 0x00000000 },
|
||||
{ 0x8b, 0x00000000 },
|
||||
{ 0x8c, 0x00000000 },
|
||||
{ 0x8d, 0x00000000 },
|
||||
{ 0x8e, 0x00000000 },
|
||||
{ 0x90, 0x50250905 },
|
||||
{ 0x91, 0x15050000 },
|
||||
{ 0xa0, 0x00000000 },
|
||||
{ 0xa1, 0x00000000 },
|
||||
{ 0xa2, 0x00000000 },
|
||||
{ 0xa3, 0x00000000 },
|
||||
{ 0xa4, 0x00000000 },
|
||||
{ 0xb0, 0x00000000 },
|
||||
{ 0xb1, 0x00000000 },
|
||||
{ 0xb2, 0x00000000 },
|
||||
{ 0xb3, 0x00000000 },
|
||||
{ 0xb4, 0x00000000 },
|
||||
{ 0xb5, 0x00000000 },
|
||||
{ 0xb6, 0x00000000 },
|
||||
{ 0xb7, 0x00000000 },
|
||||
{ 0xb8, 0x00000000 },
|
||||
{ 0xb9, 0x00000000 },
|
||||
{ 0xba, 0x00000000 },
|
||||
{ 0xbb, 0x00000000 },
|
||||
{ 0xc0, 0x01000000 },
|
||||
{ 0xc1, 0x00000000 },
|
||||
{ 0xf0, 0x00000000 },
|
||||
};
|
||||
|
||||
static int rt1308_reg_init(struct snd_soc_component *component)
|
||||
{
|
||||
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
return regmap_multi_reg_write(rt1308->regmap, init_list,
|
||||
RT1308_INIT_REG_LEN);
|
||||
}
|
||||
|
||||
static bool rt1308_volatile_register(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case RT1308_RESET:
|
||||
case RT1308_RESET_N:
|
||||
case RT1308_CLK_2:
|
||||
case RT1308_SIL_DET:
|
||||
case RT1308_CLK_DET:
|
||||
case RT1308_DC_DET:
|
||||
case RT1308_DAC_SET:
|
||||
case RT1308_DAC_BUF:
|
||||
case RT1308_SDW_REG_RDATA:
|
||||
case RT1308_DC_CAL_1:
|
||||
case RT1308_PVDD_OFFSET_CTL:
|
||||
case RT1308_CAL_OFFSET_DAC_PBTL:
|
||||
case RT1308_CAL_OFFSET_DAC_L:
|
||||
case RT1308_CAL_OFFSET_DAC_R:
|
||||
case RT1308_CAL_OFFSET_PWM_L:
|
||||
case RT1308_CAL_OFFSET_PWM_R:
|
||||
case RT1308_CAL_PWM_VOS_ADC_L:
|
||||
case RT1308_CAL_PWM_VOS_ADC_R:
|
||||
case RT1308_MBIAS:
|
||||
case RT1308_POWER_STATUS:
|
||||
case RT1308_POWER_INT:
|
||||
case RT1308_SINE_TONE_GEN_2:
|
||||
case RT1308_BQ_SET:
|
||||
case RT1308_BQ_PARA_UPDATE:
|
||||
case RT1308_VEN_DEV_ID:
|
||||
case RT1308_VERSION_ID:
|
||||
case RT1308_EFUSE_1:
|
||||
case RT1308_EFUSE_READ_PVDD_L:
|
||||
case RT1308_EFUSE_READ_PVDD_R:
|
||||
case RT1308_EFUSE_READ_PVDD_PTBL:
|
||||
case RT1308_EFUSE_READ_DEV:
|
||||
case RT1308_EFUSE_READ_R0:
|
||||
case RT1308_EFUSE_READ_ADC_L:
|
||||
case RT1308_EFUSE_READ_ADC_R:
|
||||
case RT1308_EFUSE_READ_ADC_PBTL:
|
||||
case RT1308_EFUSE_RESERVE:
|
||||
case RT1308_EFUSE_DATA_0_MSB:
|
||||
case RT1308_EFUSE_DATA_0_LSB:
|
||||
case RT1308_EFUSE_DATA_1_MSB:
|
||||
case RT1308_EFUSE_DATA_1_LSB:
|
||||
case RT1308_EFUSE_DATA_2_MSB:
|
||||
case RT1308_EFUSE_DATA_2_LSB:
|
||||
case RT1308_EFUSE_DATA_3_MSB:
|
||||
case RT1308_EFUSE_DATA_3_LSB:
|
||||
case RT1308_EFUSE_STATUS_1:
|
||||
case RT1308_EFUSE_STATUS_2:
|
||||
case RT1308_DUMMY_REG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rt1308_readable_register(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case RT1308_RESET:
|
||||
case RT1308_RESET_N:
|
||||
case RT1308_CLK_GATING ... RT1308_DC_DET_THRES:
|
||||
case RT1308_DAC_SET ... RT1308_AD_FILTER_SET:
|
||||
case RT1308_DC_CAL_1 ... RT1308_POWER_INT:
|
||||
case RT1308_SINE_TONE_GEN_1:
|
||||
case RT1308_SINE_TONE_GEN_2:
|
||||
case RT1308_BQ_SET:
|
||||
case RT1308_BQ_PARA_UPDATE:
|
||||
case RT1308_BQ_PRE_VOL_L ... RT1308_BQ_POST_VOL_R:
|
||||
case RT1308_BQ1_L_H0 ... RT1308_BQ2_R_A2:
|
||||
case RT1308_VEN_DEV_ID:
|
||||
case RT1308_VERSION_ID:
|
||||
case RT1308_SPK_BOUND:
|
||||
case RT1308_BQ1_EQ_L_1 ... RT1308_BQ2_EQ_R_3:
|
||||
case RT1308_EFUSE_1 ... RT1308_EFUSE_RESERVE:
|
||||
case RT1308_PADS_1:
|
||||
case RT1308_PADS_2:
|
||||
case RT1308_TEST_MODE:
|
||||
case RT1308_TEST_1:
|
||||
case RT1308_TEST_2:
|
||||
case RT1308_TEST_3:
|
||||
case RT1308_TEST_4:
|
||||
case RT1308_EFUSE_DATA_0_MSB ... RT1308_EFUSE_STATUS_2:
|
||||
case RT1308_TCON_1:
|
||||
case RT1308_TCON_2:
|
||||
case RT1308_DUMMY_REG:
|
||||
case RT1308_MAX_REG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int rt1308_classd_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_dapm_to_component(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
msleep(30);
|
||||
snd_soc_component_update_bits(component, RT1308_POWER_STATUS,
|
||||
RT1308_POW_PDB_REG_BIT, RT1308_POW_PDB_REG_BIT);
|
||||
msleep(40);
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
snd_soc_component_update_bits(component, RT1308_POWER_STATUS,
|
||||
RT1308_POW_PDB_REG_BIT, 0);
|
||||
usleep_range(150000, 200000);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * const rt1308_rx_data_ch_select[] = {
|
||||
"LR",
|
||||
"LL",
|
||||
"RL",
|
||||
"RR",
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(rt1308_rx_data_ch_enum, RT1308_DATA_PATH, 24,
|
||||
rt1308_rx_data_ch_select);
|
||||
|
||||
static const struct snd_kcontrol_new rt1308_snd_controls[] = {
|
||||
|
||||
/* I2S Data Channel Selection */
|
||||
SOC_ENUM("RX Channel Select", rt1308_rx_data_ch_enum),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new rt1308_sto_dac_l =
|
||||
SOC_DAPM_SINGLE("Switch", RT1308_DAC_SET,
|
||||
RT1308_DVOL_MUTE_L_EN_SFT, 1, 1);
|
||||
|
||||
static const struct snd_kcontrol_new rt1308_sto_dac_r =
|
||||
SOC_DAPM_SINGLE("Switch", RT1308_DAC_SET,
|
||||
RT1308_DVOL_MUTE_R_EN_SFT, 1, 1);
|
||||
|
||||
static const struct snd_soc_dapm_widget rt1308_dapm_widgets[] = {
|
||||
/* Audio Interface */
|
||||
SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
|
||||
|
||||
/* Supply Widgets */
|
||||
SND_SOC_DAPM_SUPPLY("MBIAS20U", RT1308_POWER,
|
||||
RT1308_POW_MBIAS20U_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("ALDO", RT1308_POWER,
|
||||
RT1308_POW_ALDO_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("DBG", RT1308_POWER,
|
||||
RT1308_POW_DBG_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("DACL", RT1308_POWER,
|
||||
RT1308_POW_DACL_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("CLK25M", RT1308_POWER,
|
||||
RT1308_POW_CLK25M_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("ADC_R", RT1308_POWER,
|
||||
RT1308_POW_ADC_R_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("ADC_L", RT1308_POWER,
|
||||
RT1308_POW_ADC_L_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("DLDO", RT1308_POWER,
|
||||
RT1308_POW_DLDO_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("VREF", RT1308_POWER,
|
||||
RT1308_POW_VREF_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("MIXER_R", RT1308_POWER,
|
||||
RT1308_POW_MIXER_R_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("MIXER_L", RT1308_POWER,
|
||||
RT1308_POW_MIXER_L_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("MBIAS4U", RT1308_POWER,
|
||||
RT1308_POW_MBIAS4U_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("PLL2_LDO", RT1308_POWER,
|
||||
RT1308_POW_PLL2_LDO_EN_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("PLL2B", RT1308_POWER,
|
||||
RT1308_POW_PLL2B_EN_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("PLL2F", RT1308_POWER,
|
||||
RT1308_POW_PLL2F_EN_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("PLL2F2", RT1308_POWER,
|
||||
RT1308_POW_PLL2F2_EN_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("PLL2B2", RT1308_POWER,
|
||||
RT1308_POW_PLL2B2_EN_BIT, 0, NULL, 0),
|
||||
|
||||
/* Digital Interface */
|
||||
SND_SOC_DAPM_SUPPLY("DAC Power", RT1308_POWER,
|
||||
RT1308_POW_DAC1_BIT, 0, NULL, 0),
|
||||
SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_SWITCH("DAC L", SND_SOC_NOPM, 0, 0, &rt1308_sto_dac_l),
|
||||
SND_SOC_DAPM_SWITCH("DAC R", SND_SOC_NOPM, 0, 0, &rt1308_sto_dac_r),
|
||||
|
||||
/* Output Lines */
|
||||
SND_SOC_DAPM_PGA_E("CLASS D", SND_SOC_NOPM, 0, 0, NULL, 0,
|
||||
rt1308_classd_event,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_OUTPUT("SPOL"),
|
||||
SND_SOC_DAPM_OUTPUT("SPOR"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route rt1308_dapm_routes[] = {
|
||||
|
||||
{ "DAC", NULL, "AIF1RX" },
|
||||
|
||||
{ "DAC", NULL, "MBIAS20U" },
|
||||
{ "DAC", NULL, "ALDO" },
|
||||
{ "DAC", NULL, "DBG" },
|
||||
{ "DAC", NULL, "DACL" },
|
||||
{ "DAC", NULL, "CLK25M" },
|
||||
{ "DAC", NULL, "ADC_R" },
|
||||
{ "DAC", NULL, "ADC_L" },
|
||||
{ "DAC", NULL, "DLDO" },
|
||||
{ "DAC", NULL, "VREF" },
|
||||
{ "DAC", NULL, "MIXER_R" },
|
||||
{ "DAC", NULL, "MIXER_L" },
|
||||
{ "DAC", NULL, "MBIAS4U" },
|
||||
{ "DAC", NULL, "PLL2_LDO" },
|
||||
{ "DAC", NULL, "PLL2B" },
|
||||
{ "DAC", NULL, "PLL2F" },
|
||||
{ "DAC", NULL, "PLL2F2" },
|
||||
{ "DAC", NULL, "PLL2B2" },
|
||||
|
||||
{ "DAC L", "Switch", "DAC" },
|
||||
{ "DAC R", "Switch", "DAC" },
|
||||
{ "DAC L", NULL, "DAC Power" },
|
||||
{ "DAC R", NULL, "DAC Power" },
|
||||
|
||||
{ "CLASS D", NULL, "DAC L" },
|
||||
{ "CLASS D", NULL, "DAC R" },
|
||||
{ "SPOL", NULL, "CLASS D" },
|
||||
{ "SPOR", NULL, "CLASS D" },
|
||||
};
|
||||
|
||||
static int rt1308_get_clk_info(int sclk, int rate)
|
||||
{
|
||||
int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
|
||||
|
||||
if (sclk <= 0 || rate <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
rate = rate << 8;
|
||||
for (i = 0; i < ARRAY_SIZE(pd); i++)
|
||||
if (sclk == rate * pd[i])
|
||||
return i;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int rt1308_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 rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
|
||||
unsigned int val_len = 0, val_clk, mask_clk;
|
||||
int pre_div, bclk_ms, frame_size;
|
||||
|
||||
rt1308->lrck = params_rate(params);
|
||||
pre_div = rt1308_get_clk_info(rt1308->sysclk, rt1308->lrck);
|
||||
if (pre_div < 0) {
|
||||
dev_err(component->dev,
|
||||
"Unsupported clock setting %d\n", rt1308->lrck);
|
||||
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;
|
||||
rt1308->bclk = rt1308->lrck * (32 << bclk_ms);
|
||||
|
||||
dev_dbg(component->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
|
||||
bclk_ms, pre_div, dai->id);
|
||||
|
||||
dev_dbg(component->dev, "lrck is %dHz and pre_div is %d for iis %d\n",
|
||||
rt1308->lrck, pre_div, dai->id);
|
||||
|
||||
switch (params_width(params)) {
|
||||
case 16:
|
||||
val_len |= RT1308_I2S_DL_SEL_16B;
|
||||
break;
|
||||
case 20:
|
||||
val_len |= RT1308_I2S_DL_SEL_20B;
|
||||
break;
|
||||
case 24:
|
||||
val_len |= RT1308_I2S_DL_SEL_24B;
|
||||
break;
|
||||
case 8:
|
||||
val_len |= RT1308_I2S_DL_SEL_8B;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (dai->id) {
|
||||
case RT1308_AIF1:
|
||||
mask_clk = RT1308_DIV_FS_SYS_MASK;
|
||||
val_clk = pre_div << RT1308_DIV_FS_SYS_SFT;
|
||||
snd_soc_component_update_bits(component,
|
||||
RT1308_I2S_SET_2, RT1308_I2S_DL_SEL_MASK,
|
||||
val_len);
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snd_soc_component_update_bits(component, RT1308_CLK_1,
|
||||
mask_clk, val_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt1308_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
|
||||
unsigned int reg_val = 0, reg1_val = 0;
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
rt1308->master = 0;
|
||||
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 |= RT1308_I2S_DF_SEL_LEFT;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
reg_val |= RT1308_I2S_DF_SEL_PCM_A;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
reg_val |= RT1308_I2S_DF_SEL_PCM_B;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
||||
case SND_SOC_DAIFMT_NB_NF:
|
||||
break;
|
||||
case SND_SOC_DAIFMT_IB_NF:
|
||||
reg1_val |= RT1308_I2S_BCLK_INV;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (dai->id) {
|
||||
case RT1308_AIF1:
|
||||
snd_soc_component_update_bits(component,
|
||||
RT1308_I2S_SET_1, RT1308_I2S_DF_SEL_MASK,
|
||||
reg_val);
|
||||
snd_soc_component_update_bits(component,
|
||||
RT1308_I2S_SET_2, RT1308_I2S_BCLK_MASK,
|
||||
reg1_val);
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt1308_set_component_sysclk(struct snd_soc_component *component,
|
||||
int clk_id, int source, unsigned int freq, int dir)
|
||||
{
|
||||
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
|
||||
unsigned int reg_val = 0;
|
||||
|
||||
if (freq == rt1308->sysclk && clk_id == rt1308->sysclk_src)
|
||||
return 0;
|
||||
|
||||
switch (clk_id) {
|
||||
case RT1308_FS_SYS_S_MCLK:
|
||||
reg_val |= RT1308_SEL_FS_SYS_SRC_MCLK;
|
||||
snd_soc_component_update_bits(component,
|
||||
RT1308_CLK_DET, RT1308_MCLK_DET_EN_MASK,
|
||||
RT1308_MCLK_DET_EN);
|
||||
break;
|
||||
case RT1308_FS_SYS_S_BCLK:
|
||||
reg_val |= RT1308_SEL_FS_SYS_SRC_BCLK;
|
||||
break;
|
||||
case RT1308_FS_SYS_S_PLL:
|
||||
reg_val |= RT1308_SEL_FS_SYS_SRC_PLL;
|
||||
break;
|
||||
case RT1308_FS_SYS_S_RCCLK:
|
||||
reg_val |= RT1308_SEL_FS_SYS_SRC_RCCLK;
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
snd_soc_component_update_bits(component, RT1308_CLK_1,
|
||||
RT1308_SEL_FS_SYS_MASK, reg_val);
|
||||
rt1308->sysclk = freq;
|
||||
rt1308->sysclk_src = clk_id;
|
||||
|
||||
dev_dbg(component->dev, "Sysclk is %dHz and clock id is %d\n",
|
||||
freq, clk_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt1308_set_component_pll(struct snd_soc_component *component,
|
||||
int pll_id, int source, unsigned int freq_in,
|
||||
unsigned int freq_out)
|
||||
{
|
||||
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
|
||||
struct rl6231_pll_code pll_code;
|
||||
int ret;
|
||||
|
||||
if (source == rt1308->pll_src && freq_in == rt1308->pll_in &&
|
||||
freq_out == rt1308->pll_out)
|
||||
return 0;
|
||||
|
||||
if (!freq_in || !freq_out) {
|
||||
dev_dbg(component->dev, "PLL disabled\n");
|
||||
|
||||
rt1308->pll_in = 0;
|
||||
rt1308->pll_out = 0;
|
||||
snd_soc_component_update_bits(component,
|
||||
RT1308_CLK_1, RT1308_SEL_FS_SYS_MASK,
|
||||
RT1308_SEL_FS_SYS_SRC_MCLK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (source) {
|
||||
case RT1308_PLL_S_MCLK:
|
||||
snd_soc_component_update_bits(component,
|
||||
RT1308_CLK_2, RT1308_SEL_PLL_SRC_MASK,
|
||||
RT1308_SEL_PLL_SRC_MCLK);
|
||||
snd_soc_component_update_bits(component,
|
||||
RT1308_CLK_DET, RT1308_MCLK_DET_EN_MASK,
|
||||
RT1308_MCLK_DET_EN);
|
||||
break;
|
||||
case RT1308_PLL_S_BCLK:
|
||||
snd_soc_component_update_bits(component,
|
||||
RT1308_CLK_2, RT1308_SEL_PLL_SRC_MASK,
|
||||
RT1308_SEL_PLL_SRC_BCLK);
|
||||
break;
|
||||
case RT1308_PLL_S_RCCLK:
|
||||
snd_soc_component_update_bits(component,
|
||||
RT1308_CLK_2, RT1308_SEL_PLL_SRC_MASK,
|
||||
RT1308_SEL_PLL_SRC_RCCLK);
|
||||
freq_in = 25000000;
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "Unknown PLL Source %d\n", source);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
|
||||
if (ret < 0) {
|
||||
dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
|
||||
pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
|
||||
pll_code.n_code, pll_code.k_code);
|
||||
|
||||
snd_soc_component_write(component, RT1308_PLL_1,
|
||||
pll_code.k_code << RT1308_PLL1_K_SFT |
|
||||
pll_code.m_bp << RT1308_PLL1_M_BYPASS_SFT |
|
||||
(pll_code.m_bp ? 0 : pll_code.m_code) << RT1308_PLL1_M_SFT |
|
||||
pll_code.n_code << RT1308_PLL1_N_SFT);
|
||||
|
||||
rt1308->pll_in = freq_in;
|
||||
rt1308->pll_out = freq_out;
|
||||
rt1308->pll_src = source;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt1308_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
rt1308->component = component;
|
||||
|
||||
return rt1308_reg_init(component);
|
||||
}
|
||||
|
||||
static void rt1308_remove(struct snd_soc_component *component)
|
||||
{
|
||||
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
regmap_write(rt1308->regmap, RT1308_RESET, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int rt1308_suspend(struct snd_soc_component *component)
|
||||
{
|
||||
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
regcache_cache_only(rt1308->regmap, true);
|
||||
regcache_mark_dirty(rt1308->regmap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt1308_resume(struct snd_soc_component *component)
|
||||
{
|
||||
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
regcache_cache_only(rt1308->regmap, false);
|
||||
regcache_sync(rt1308->regmap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define rt1308_suspend NULL
|
||||
#define rt1308_resume NULL
|
||||
#endif
|
||||
|
||||
#define RT1308_STEREO_RATES SNDRV_PCM_RATE_48000
|
||||
#define RT1308_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
|
||||
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
SNDRV_PCM_FMTBIT_S24_LE)
|
||||
|
||||
static const struct snd_soc_dai_ops rt1308_aif_dai_ops = {
|
||||
.hw_params = rt1308_hw_params,
|
||||
.set_fmt = rt1308_set_dai_fmt,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver rt1308_dai[] = {
|
||||
{
|
||||
.name = "rt1308-aif",
|
||||
.playback = {
|
||||
.stream_name = "AIF1 Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = RT1308_STEREO_RATES,
|
||||
.formats = RT1308_FORMATS,
|
||||
},
|
||||
.ops = &rt1308_aif_dai_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver soc_component_dev_rt1308 = {
|
||||
.probe = rt1308_probe,
|
||||
.remove = rt1308_remove,
|
||||
.suspend = rt1308_suspend,
|
||||
.resume = rt1308_resume,
|
||||
.controls = rt1308_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(rt1308_snd_controls),
|
||||
.dapm_widgets = rt1308_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(rt1308_dapm_widgets),
|
||||
.dapm_routes = rt1308_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(rt1308_dapm_routes),
|
||||
.set_sysclk = rt1308_set_component_sysclk,
|
||||
.set_pll = rt1308_set_component_pll,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static const struct regmap_config rt1308_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 32,
|
||||
.max_register = RT1308_MAX_REG,
|
||||
.volatile_reg = rt1308_volatile_register,
|
||||
.readable_reg = rt1308_readable_register,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.reg_defaults = rt1308_reg,
|
||||
.num_reg_defaults = ARRAY_SIZE(rt1308_reg),
|
||||
.use_single_read = true,
|
||||
.use_single_write = true,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id rt1308_of_match[] = {
|
||||
{ .compatible = "realtek,rt1308", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rt1308_of_match);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static struct acpi_device_id rt1308_acpi_match[] = {
|
||||
{ "10EC1308", 0, },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, rt1308_acpi_match);
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id rt1308_i2c_id[] = {
|
||||
{ "rt1308", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, rt1308_i2c_id);
|
||||
|
||||
static void rt1308_efuse(struct rt1308_priv *rt1308)
|
||||
{
|
||||
regmap_write(rt1308->regmap, RT1308_RESET, 0);
|
||||
|
||||
regmap_write(rt1308->regmap, RT1308_POWER, 0xff371600);
|
||||
regmap_write(rt1308->regmap, RT1308_CLK_1, 0x52100000);
|
||||
regmap_write(rt1308->regmap, RT1308_I2C_I2S_SDW_SET, 0x01014005);
|
||||
regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x227f5501);
|
||||
regmap_write(rt1308->regmap, RT1308_PADS_1, 0x50150505);
|
||||
regmap_write(rt1308->regmap, RT1308_VREF, 0x18100000);
|
||||
regmap_write(rt1308->regmap, RT1308_IV_SENSE, 0x87010000);
|
||||
regmap_write(rt1308->regmap, RT1308_DUMMY_REG, 0x00000200);
|
||||
regmap_write(rt1308->regmap, RT1308_SIL_DET, 0x61c30000);
|
||||
regmap_write(rt1308->regmap, RT1308_CLK_DET, 0x03700000);
|
||||
regmap_write(rt1308->regmap, RT1308_SINE_TONE_GEN_1, 0x50022f00);
|
||||
regmap_write(rt1308->regmap, RT1308_POWER_STATUS, 0x01800000);
|
||||
regmap_write(rt1308->regmap, RT1308_DC_CAL_2, 0x00ffff00);
|
||||
regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x607e5501);
|
||||
|
||||
regmap_write(rt1308->regmap, RT1308_CLK_2, 0x0060e000);
|
||||
regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x04fe0f00);
|
||||
msleep(100);
|
||||
regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x44fe0f00);
|
||||
msleep(20);
|
||||
regmap_write(rt1308->regmap, RT1308_PVDD_OFFSET_CTL, 0x10000000);
|
||||
|
||||
regmap_write(rt1308->regmap, RT1308_POWER_STATUS, 0x00800000);
|
||||
regmap_write(rt1308->regmap, RT1308_POWER, 0x0);
|
||||
regmap_write(rt1308->regmap, RT1308_CLK_1, 0x52000000);
|
||||
regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x227f5501);
|
||||
regmap_write(rt1308->regmap, RT1308_SINE_TONE_GEN_1, 0x10022f00);
|
||||
}
|
||||
|
||||
static int rt1308_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct rt1308_priv *rt1308;
|
||||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
rt1308 = devm_kzalloc(&i2c->dev, sizeof(struct rt1308_priv),
|
||||
GFP_KERNEL);
|
||||
if (rt1308 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(i2c, rt1308);
|
||||
|
||||
rt1308->regmap = devm_regmap_init_i2c(i2c, &rt1308_regmap);
|
||||
if (IS_ERR(rt1308->regmap)) {
|
||||
ret = PTR_ERR(rt1308->regmap);
|
||||
dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
regmap_read(rt1308->regmap, RT1308_VEN_DEV_ID, &val);
|
||||
/* ignore last byte difference */
|
||||
if ((val & 0xFFFFFF00) != RT1308_DEVICE_ID_NUM) {
|
||||
dev_err(&i2c->dev,
|
||||
"Device with ID register %x is not rt1308\n", val);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rt1308_efuse(rt1308);
|
||||
|
||||
return devm_snd_soc_register_component(&i2c->dev,
|
||||
&soc_component_dev_rt1308,
|
||||
rt1308_dai, ARRAY_SIZE(rt1308_dai));
|
||||
}
|
||||
|
||||
static void rt1308_i2c_shutdown(struct i2c_client *client)
|
||||
{
|
||||
struct rt1308_priv *rt1308 = i2c_get_clientdata(client);
|
||||
|
||||
regmap_write(rt1308->regmap, RT1308_RESET, 0);
|
||||
}
|
||||
|
||||
static struct i2c_driver rt1308_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "rt1308",
|
||||
.of_match_table = of_match_ptr(rt1308_of_match),
|
||||
.acpi_match_table = ACPI_PTR(rt1308_acpi_match),
|
||||
},
|
||||
.probe = rt1308_i2c_probe,
|
||||
.shutdown = rt1308_i2c_shutdown,
|
||||
.id_table = rt1308_i2c_id,
|
||||
};
|
||||
module_i2c_driver(rt1308_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC RT1308 amplifier driver");
|
||||
MODULE_AUTHOR("Derek Fang <derek.fang@realtek.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
291
sound/soc/codecs/rt1308.h
Executable file
291
sound/soc/codecs/rt1308.h
Executable file
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* RT1308.h -- RT1308 ALSA SoC amplifier component driver
|
||||
*
|
||||
* Copyright 2019 Realtek Semiconductor Corp.
|
||||
* Author: Derek Fang <derek.fang@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 _RT1308_H_
|
||||
#define _RT1308_H_
|
||||
|
||||
#define RT1308_DEVICE_ID_NUM 0x10ec1300
|
||||
|
||||
#define RT1308_RESET 0x00
|
||||
#define RT1308_RESET_N 0x01
|
||||
#define RT1308_CLK_GATING 0x02
|
||||
#define RT1308_PLL_1 0x03
|
||||
#define RT1308_PLL_2 0x04
|
||||
#define RT1308_PLL_INT 0x05
|
||||
#define RT1308_CLK_1 0x06
|
||||
#define RT1308_DATA_PATH 0x07
|
||||
#define RT1308_CLK_2 0x08
|
||||
#define RT1308_SIL_DET 0x09
|
||||
#define RT1308_CLK_DET 0x0a
|
||||
#define RT1308_DC_DET 0x0b
|
||||
#define RT1308_DC_DET_THRES 0x0c
|
||||
#define RT1308_DAC_SET 0x10
|
||||
#define RT1308_SRC_SET 0x11
|
||||
#define RT1308_DAC_BUF 0x12
|
||||
#define RT1308_ADC_SET 0x13
|
||||
#define RT1308_ADC_SET_INT 0x14
|
||||
#define RT1308_I2S_SET_1 0x15
|
||||
#define RT1308_I2S_SET_2 0x16
|
||||
#define RT1308_I2C_I2S_SDW_SET 0x17
|
||||
#define RT1308_SDW_REG_RW 0x18
|
||||
#define RT1308_SDW_REG_RDATA 0x19
|
||||
#define RT1308_IV_SENSE 0x1a
|
||||
#define RT1308_I2S_TX_DAC_SET 0x1b
|
||||
#define RT1308_AD_FILTER_SET 0x1c
|
||||
#define RT1308_DC_CAL_1 0x20
|
||||
#define RT1308_DC_CAL_2 0x21
|
||||
#define RT1308_DC_CAL_L_OFFSET 0x22
|
||||
#define RT1308_DC_CAL_R_OFFSET 0x23
|
||||
#define RT1308_PVDD_OFFSET_CTL 0x24
|
||||
#define RT1308_PVDD_OFFSET_L 0x25
|
||||
#define RT1308_PVDD_OFFSET_R 0x26
|
||||
#define RT1308_PVDD_OFFSET_PBTL 0x27
|
||||
#define RT1308_PVDD_OFFSET_PVDD 0x28
|
||||
#define RT1308_CAL_OFFSET_DAC_PBTL 0x29
|
||||
#define RT1308_CAL_OFFSET_DAC_L 0x2a
|
||||
#define RT1308_CAL_OFFSET_DAC_R 0x2b
|
||||
#define RT1308_CAL_OFFSET_PWM_L 0x2c
|
||||
#define RT1308_CAL_OFFSET_PWM_R 0x2d
|
||||
#define RT1308_CAL_PWM_VOS_ADC_L 0x2e
|
||||
#define RT1308_CAL_PWM_VOS_ADC_R 0x2f
|
||||
#define RT1308_CLASS_D_SET_1 0x30
|
||||
#define RT1308_CLASS_D_SET_2 0x31
|
||||
#define RT1308_POWER 0x32
|
||||
#define RT1308_LDO 0x33
|
||||
#define RT1308_VREF 0x34
|
||||
#define RT1308_MBIAS 0x35
|
||||
#define RT1308_POWER_STATUS 0x36
|
||||
#define RT1308_POWER_INT 0x37
|
||||
#define RT1308_SINE_TONE_GEN_1 0x50
|
||||
#define RT1308_SINE_TONE_GEN_2 0x51
|
||||
#define RT1308_BQ_SET 0x54
|
||||
#define RT1308_BQ_PARA_UPDATE 0x55
|
||||
#define RT1308_BQ_PRE_VOL_L 0x56
|
||||
#define RT1308_BQ_PRE_VOL_R 0x57
|
||||
#define RT1308_BQ_POST_VOL_L 0x58
|
||||
#define RT1308_BQ_POST_VOL_R 0x59
|
||||
#define RT1308_BQ1_L_H0 0x5b
|
||||
#define RT1308_BQ1_L_B1 0x5c
|
||||
#define RT1308_BQ1_L_B2 0x5d
|
||||
#define RT1308_BQ1_L_A1 0x5e
|
||||
#define RT1308_BQ1_L_A2 0x5f
|
||||
#define RT1308_BQ1_R_H0 0x60
|
||||
#define RT1308_BQ1_R_B1 0x61
|
||||
#define RT1308_BQ1_R_B2 0x62
|
||||
#define RT1308_BQ1_R_A1 0x63
|
||||
#define RT1308_BQ1_R_A2 0x64
|
||||
#define RT1308_BQ2_L_H0 0x65
|
||||
#define RT1308_BQ2_L_B1 0x66
|
||||
#define RT1308_BQ2_L_B2 0x67
|
||||
#define RT1308_BQ2_L_A1 0x68
|
||||
#define RT1308_BQ2_L_A2 0x69
|
||||
#define RT1308_BQ2_R_H0 0x6a
|
||||
#define RT1308_BQ2_R_B1 0x6b
|
||||
#define RT1308_BQ2_R_B2 0x6c
|
||||
#define RT1308_BQ2_R_A1 0x6d
|
||||
#define RT1308_BQ2_R_A2 0x6e
|
||||
#define RT1308_VEN_DEV_ID 0x70
|
||||
#define RT1308_VERSION_ID 0x71
|
||||
#define RT1308_SPK_BOUND 0x72
|
||||
#define RT1308_BQ1_EQ_L_1 0x73
|
||||
#define RT1308_BQ1_EQ_L_2 0x74
|
||||
#define RT1308_BQ1_EQ_L_3 0x75
|
||||
#define RT1308_BQ1_EQ_R_1 0x76
|
||||
#define RT1308_BQ1_EQ_R_2 0x77
|
||||
#define RT1308_BQ1_EQ_R_3 0x78
|
||||
#define RT1308_BQ2_EQ_L_1 0x79
|
||||
#define RT1308_BQ2_EQ_L_2 0x7a
|
||||
#define RT1308_BQ2_EQ_L_3 0x7b
|
||||
#define RT1308_BQ2_EQ_R_1 0x7c
|
||||
#define RT1308_BQ2_EQ_R_2 0x7d
|
||||
#define RT1308_BQ2_EQ_R_3 0x7e
|
||||
#define RT1308_EFUSE_1 0x7f
|
||||
#define RT1308_EFUSE_2 0x80
|
||||
#define RT1308_EFUSE_PROG_PVDD_L 0x81
|
||||
#define RT1308_EFUSE_PROG_PVDD_R 0x82
|
||||
#define RT1308_EFUSE_PROG_R0_L 0x83
|
||||
#define RT1308_EFUSE_PROG_R0_R 0x84
|
||||
#define RT1308_EFUSE_PROG_DEV 0x85
|
||||
#define RT1308_EFUSE_READ_PVDD_L 0x86
|
||||
#define RT1308_EFUSE_READ_PVDD_R 0x87
|
||||
#define RT1308_EFUSE_READ_PVDD_PTBL 0x88
|
||||
#define RT1308_EFUSE_READ_DEV 0x89
|
||||
#define RT1308_EFUSE_READ_R0 0x8a
|
||||
#define RT1308_EFUSE_READ_ADC_L 0x8b
|
||||
#define RT1308_EFUSE_READ_ADC_R 0x8c
|
||||
#define RT1308_EFUSE_READ_ADC_PBTL 0x8d
|
||||
#define RT1308_EFUSE_RESERVE 0x8e
|
||||
#define RT1308_PADS_1 0x90
|
||||
#define RT1308_PADS_2 0x91
|
||||
#define RT1308_TEST_MODE 0xa0
|
||||
#define RT1308_TEST_1 0xa1
|
||||
#define RT1308_TEST_2 0xa2
|
||||
#define RT1308_TEST_3 0xa3
|
||||
#define RT1308_TEST_4 0xa4
|
||||
#define RT1308_EFUSE_DATA_0_MSB 0xb0
|
||||
#define RT1308_EFUSE_DATA_0_LSB 0xb1
|
||||
#define RT1308_EFUSE_DATA_1_MSB 0xb2
|
||||
#define RT1308_EFUSE_DATA_1_LSB 0xb3
|
||||
#define RT1308_EFUSE_DATA_2_MSB 0xb4
|
||||
#define RT1308_EFUSE_DATA_2_LSB 0xb5
|
||||
#define RT1308_EFUSE_DATA_3_MSB 0xb6
|
||||
#define RT1308_EFUSE_DATA_3_LSB 0xb7
|
||||
#define RT1308_EFUSE_DATA_TEST_MSB 0xb8
|
||||
#define RT1308_EFUSE_DATA_TEST_LSB 0xb9
|
||||
#define RT1308_EFUSE_STATUS_1 0xba
|
||||
#define RT1308_EFUSE_STATUS_2 0xbb
|
||||
#define RT1308_TCON_1 0xc0
|
||||
#define RT1308_TCON_2 0xc1
|
||||
#define RT1308_DUMMY_REG 0xf0
|
||||
#define RT1308_MAX_REG 0xff
|
||||
|
||||
/* PLL1 M/N/K Code-1 (0x03) */
|
||||
#define RT1308_PLL1_K_SFT 24
|
||||
#define RT1308_PLL1_K_MASK (0x1f << 24)
|
||||
#define RT1308_PLL1_M_BYPASS_MASK (0x1 << 23)
|
||||
#define RT1308_PLL1_M_BYPASS_SFT 23
|
||||
#define RT1308_PLL1_M_BYPASS (0x1 << 23)
|
||||
#define RT1308_PLL1_M_MASK (0x3f << 16)
|
||||
#define RT1308_PLL1_M_SFT 16
|
||||
#define RT1308_PLL1_N_MASK (0x7f << 8)
|
||||
#define RT1308_PLL1_N_SFT 8
|
||||
|
||||
/* CLOCK-1 (0x06) */
|
||||
#define RT1308_DIV_FS_SYS_MASK (0xf << 28)
|
||||
#define RT1308_DIV_FS_SYS_SFT 28
|
||||
#define RT1308_SEL_FS_SYS_MASK (0x7 << 24)
|
||||
#define RT1308_SEL_FS_SYS_SFT 24
|
||||
#define RT1308_SEL_FS_SYS_SRC_MCLK (0x0 << 24)
|
||||
#define RT1308_SEL_FS_SYS_SRC_BCLK (0x1 << 24)
|
||||
#define RT1308_SEL_FS_SYS_SRC_PLL (0x2 << 24)
|
||||
#define RT1308_SEL_FS_SYS_SRC_RCCLK (0x4 << 24)
|
||||
|
||||
/* CLOCK-2 (0x08) */
|
||||
#define RT1308_DIV_PRE_PLL_MASK (0xf << 28)
|
||||
#define RT1308_DIV_PRE_PLL_SFT 28
|
||||
#define RT1308_SEL_PLL_SRC_MASK (0x7 << 24)
|
||||
#define RT1308_SEL_PLL_SRC_SFT 24
|
||||
#define RT1308_SEL_PLL_SRC_MCLK (0x0 << 24)
|
||||
#define RT1308_SEL_PLL_SRC_BCLK (0x1 << 24)
|
||||
#define RT1308_SEL_PLL_SRC_RCCLK (0x4 << 24)
|
||||
|
||||
/* Clock Detect (0x0a) */
|
||||
#define RT1308_MCLK_DET_EN_MASK (0x1 << 25)
|
||||
#define RT1308_MCLK_DET_EN_SFT 25
|
||||
#define RT1308_MCLK_DET_EN (0x1 << 25)
|
||||
#define RT1308_BCLK_DET_EN_MASK (0x1 << 24)
|
||||
#define RT1308_BCLK_DET_EN_SFT 24
|
||||
#define RT1308_BCLK_DET_EN (0x1 << 24)
|
||||
|
||||
/* DAC Setting (0x10) */
|
||||
#define RT1308_DVOL_MUTE_R_EN_SFT 7
|
||||
#define RT1308_DVOL_MUTE_L_EN_SFT 6
|
||||
|
||||
/* I2S Setting-1 (0x15) */
|
||||
#define RT1308_I2S_DF_SEL_MASK (0x3 << 12)
|
||||
#define RT1308_I2S_DF_SEL_SFT 12
|
||||
#define RT1308_I2S_DF_SEL_I2S (0x0 << 12)
|
||||
#define RT1308_I2S_DF_SEL_LEFT (0x1 << 12)
|
||||
#define RT1308_I2S_DF_SEL_PCM_A (0x2 << 12)
|
||||
#define RT1308_I2S_DF_SEL_PCM_B (0x3 << 12)
|
||||
#define RT1308_I2S_DL_RX_SEL_MASK (0x7 << 4)
|
||||
#define RT1308_I2S_DL_RX_SEL_SFT 4
|
||||
#define RT1308_I2S_DL_RX_SEL_16B (0x0 << 4)
|
||||
#define RT1308_I2S_DL_RX_SEL_20B (0x1 << 4)
|
||||
#define RT1308_I2S_DL_RX_SEL_24B (0x2 << 4)
|
||||
#define RT1308_I2S_DL_RX_SEL_32B (0x3 << 4)
|
||||
#define RT1308_I2S_DL_RX_SEL_8B (0x4 << 4)
|
||||
#define RT1308_I2S_DL_TX_SEL_MASK (0x7 << 0)
|
||||
#define RT1308_I2S_DL_TX_SEL_SFT 0
|
||||
#define RT1308_I2S_DL_TX_SEL_16B (0x0 << 0)
|
||||
#define RT1308_I2S_DL_TX_SEL_20B (0x1 << 0)
|
||||
#define RT1308_I2S_DL_TX_SEL_24B (0x2 << 0)
|
||||
#define RT1308_I2S_DL_TX_SEL_32B (0x3 << 0)
|
||||
#define RT1308_I2S_DL_TX_SEL_8B (0x4 << 0)
|
||||
|
||||
/* I2S Setting-2 (0x16) */
|
||||
#define RT1308_I2S_DL_SEL_MASK (0x7 << 24)
|
||||
#define RT1308_I2S_DL_SEL_SFT 24
|
||||
#define RT1308_I2S_DL_SEL_16B (0x0 << 24)
|
||||
#define RT1308_I2S_DL_SEL_20B (0x1 << 24)
|
||||
#define RT1308_I2S_DL_SEL_24B (0x2 << 24)
|
||||
#define RT1308_I2S_DL_SEL_32B (0x3 << 24)
|
||||
#define RT1308_I2S_DL_SEL_8B (0x4 << 24)
|
||||
#define RT1308_I2S_BCLK_MASK (0x1 << 14)
|
||||
#define RT1308_I2S_BCLK_SFT 14
|
||||
#define RT1308_I2S_BCLK_NORMAL (0x0 << 14)
|
||||
#define RT1308_I2S_BCLK_INV (0x1 << 14)
|
||||
|
||||
/* Power Control-1 (0x32) */
|
||||
#define RT1308_POW_MBIAS20U (0x1 << 31)
|
||||
#define RT1308_POW_MBIAS20U_BIT 31
|
||||
#define RT1308_POW_ALDO (0x1 << 30)
|
||||
#define RT1308_POW_ALDO_BIT 30
|
||||
#define RT1308_POW_DBG (0x1 << 29)
|
||||
#define RT1308_POW_DBG_BIT 29
|
||||
#define RT1308_POW_DACL (0x1 << 28)
|
||||
#define RT1308_POW_DACL_BIT 28
|
||||
#define RT1308_POW_DAC1 (0x1 << 27)
|
||||
#define RT1308_POW_DAC1_BIT 27
|
||||
#define RT1308_POW_CLK25M (0x1 << 26)
|
||||
#define RT1308_POW_CLK25M_BIT 26
|
||||
#define RT1308_POW_ADC_R (0x1 << 25)
|
||||
#define RT1308_POW_ADC_R_BIT 25
|
||||
#define RT1308_POW_ADC_L (0x1 << 24)
|
||||
#define RT1308_POW_ADC_L_BIT 24
|
||||
#define RT1308_POW_DLDO (0x1 << 21)
|
||||
#define RT1308_POW_DLDO_BIT 21
|
||||
#define RT1308_POW_VREF (0x1 << 20)
|
||||
#define RT1308_POW_VREF_BIT 20
|
||||
#define RT1308_POW_MIXER_R (0x1 << 18)
|
||||
#define RT1308_POW_MIXER_R_BIT 18
|
||||
#define RT1308_POW_MIXER_L (0x1 << 17)
|
||||
#define RT1308_POW_MIXER_L_BIT 17
|
||||
#define RT1308_POW_MBIAS4U (0x1 << 16)
|
||||
#define RT1308_POW_MBIAS4U_BIT 16
|
||||
#define RT1308_POW_PLL2_LDO_EN (0x1 << 12)
|
||||
#define RT1308_POW_PLL2_LDO_EN_BIT 12
|
||||
#define RT1308_POW_PLL2B_EN (0x1 << 11)
|
||||
#define RT1308_POW_PLL2B_EN_BIT 11
|
||||
#define RT1308_POW_PLL2F_EN (0x1 << 10)
|
||||
#define RT1308_POW_PLL2F_EN_BIT 10
|
||||
#define RT1308_POW_PLL2F2_EN (0x1 << 9)
|
||||
#define RT1308_POW_PLL2F2_EN_BIT 9
|
||||
#define RT1308_POW_PLL2B2_EN (0x1 << 8)
|
||||
#define RT1308_POW_PLL2B2_EN_BIT 8
|
||||
|
||||
/* Power Control-2 (0x36) */
|
||||
#define RT1308_POW_PDB_SRC_BIT (0x1 << 27)
|
||||
#define RT1308_POW_PDB_MN_BIT (0x1 << 25)
|
||||
#define RT1308_POW_PDB_REG_BIT (0x1 << 24)
|
||||
|
||||
|
||||
/* System Clock Source */
|
||||
enum {
|
||||
RT1308_FS_SYS_S_MCLK,
|
||||
RT1308_FS_SYS_S_BCLK,
|
||||
RT1308_FS_SYS_S_PLL,
|
||||
RT1308_FS_SYS_S_RCCLK, /* 25.0 MHz */
|
||||
};
|
||||
|
||||
/* PLL Source */
|
||||
enum {
|
||||
RT1308_PLL_S_MCLK,
|
||||
RT1308_PLL_S_BCLK,
|
||||
RT1308_PLL_S_RCCLK,
|
||||
};
|
||||
|
||||
enum {
|
||||
RT1308_AIF1,
|
||||
RT1308_AIFS
|
||||
};
|
||||
|
||||
#endif /* end of _RT1308_H_ */
|
|
@ -470,9 +470,7 @@ static int __maybe_unused rt5514_suspend(struct device *dev)
|
|||
|
||||
static int __maybe_unused rt5514_resume(struct device *dev)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_lookup_component(dev, DRV_NAME);
|
||||
struct rt5514_dsp *rt5514_dsp =
|
||||
snd_soc_component_get_drvdata(component);
|
||||
struct rt5514_dsp *rt5514_dsp = dev_get_drvdata(dev);
|
||||
int irq = to_spi_device(dev)->irq;
|
||||
u8 buf[8];
|
||||
|
||||
|
|
|
@ -1478,7 +1478,7 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
|||
{
|
||||
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
|
||||
struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
|
||||
int pd, idx = -EINVAL;
|
||||
int pd, idx;
|
||||
|
||||
pd = rl6231_get_pre_div(rt5665->regmap,
|
||||
RT5665_ADDA_CLK_1, RT5665_I2S_PD1_SFT);
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include "rt5677-spi.h"
|
||||
|
||||
#define DRV_NAME "rt5677spi"
|
||||
|
||||
#define RT5677_SPI_BURST_LEN 240
|
||||
#define RT5677_SPI_HEADER 5
|
||||
#define RT5677_SPI_FREQ 6000000
|
||||
|
@ -230,7 +232,7 @@ MODULE_DEVICE_TABLE(acpi, rt5677_spi_acpi_id);
|
|||
|
||||
static struct spi_driver rt5677_spi_driver = {
|
||||
.driver = {
|
||||
.name = "rt5677",
|
||||
.name = DRV_NAME,
|
||||
.acpi_match_table = ACPI_PTR(rt5677_spi_acpi_id),
|
||||
},
|
||||
.probe = rt5677_spi_probe,
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include <linux/firmware.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
|
@ -829,13 +833,13 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = {
|
|||
|
||||
/* DAC Digital Volume */
|
||||
SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5677_DAC1_DIG_VOL,
|
||||
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 87, 0, dac_vol_tlv),
|
||||
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 127, 0, dac_vol_tlv),
|
||||
SOC_DOUBLE_TLV("DAC2 Playback Volume", RT5677_DAC2_DIG_VOL,
|
||||
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 87, 0, dac_vol_tlv),
|
||||
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 127, 0, dac_vol_tlv),
|
||||
SOC_DOUBLE_TLV("DAC3 Playback Volume", RT5677_DAC3_DIG_VOL,
|
||||
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 87, 0, dac_vol_tlv),
|
||||
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 127, 0, dac_vol_tlv),
|
||||
SOC_DOUBLE_TLV("DAC4 Playback Volume", RT5677_DAC4_DIG_VOL,
|
||||
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 87, 0, dac_vol_tlv),
|
||||
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 127, 0, dac_vol_tlv),
|
||||
|
||||
/* IN1/IN2 Control */
|
||||
SOC_SINGLE_TLV("IN1 Boost", RT5677_IN1, RT5677_BST_SFT1, 8, 0, bst_tlv),
|
||||
|
@ -2604,7 +2608,8 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5677_ASRC_1, 1, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("I2S3 ASRC", 1, RT5677_ASRC_1, 2, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("I2S4 ASRC", 1, RT5677_ASRC_1, 3, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5677_ASRC_2, 14, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5677_ASRC_2, 14, 0,
|
||||
rt5677_filter_power_event, SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_SUPPLY_S("DAC MONO2 L ASRC", 1, RT5677_ASRC_2, 13, 0, NULL,
|
||||
0),
|
||||
SND_SOC_DAPM_SUPPLY_S("DAC MONO2 R ASRC", 1, RT5677_ASRC_2, 12, 0, NULL,
|
||||
|
@ -4617,7 +4622,6 @@ static void rt5677_gpio_config(struct rt5677_priv *rt5677, unsigned offset,
|
|||
static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
struct rt5677_priv *rt5677 = gpiochip_get_data(chip);
|
||||
struct regmap_irq_chip_data *data = rt5677->irq_data;
|
||||
int irq;
|
||||
|
||||
if ((rt5677->pdata.jd1_gpio == 1 && offset == RT5677_GPIO1) ||
|
||||
|
@ -4643,11 +4647,11 @@ static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset)
|
|||
return -ENXIO;
|
||||
}
|
||||
|
||||
return regmap_irq_get_virq(data, irq);
|
||||
return irq_create_mapping(rt5677->domain, irq);
|
||||
}
|
||||
|
||||
static const struct gpio_chip rt5677_template_chip = {
|
||||
.label = "rt5677",
|
||||
.label = RT5677_DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.direction_output = rt5677_gpio_direction_out,
|
||||
.set = rt5677_gpio_set,
|
||||
|
@ -4713,37 +4717,13 @@ static int rt5677_probe(struct snd_soc_component *component)
|
|||
|
||||
snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
|
||||
|
||||
regmap_write(rt5677->regmap, RT5677_DIG_MISC, 0x0020);
|
||||
regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC,
|
||||
~RT5677_IRQ_DEBOUNCE_SEL_MASK, 0x0020);
|
||||
regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x0c00);
|
||||
|
||||
for (i = 0; i < RT5677_GPIO_NUM; i++)
|
||||
rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]);
|
||||
|
||||
if (rt5677->irq_data) {
|
||||
regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1, 0x8000,
|
||||
0x8000);
|
||||
regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x0018,
|
||||
0x0008);
|
||||
|
||||
if (rt5677->pdata.jd1_gpio)
|
||||
regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1,
|
||||
RT5677_SEL_GPIO_JD1_MASK,
|
||||
rt5677->pdata.jd1_gpio <<
|
||||
RT5677_SEL_GPIO_JD1_SFT);
|
||||
|
||||
if (rt5677->pdata.jd2_gpio)
|
||||
regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1,
|
||||
RT5677_SEL_GPIO_JD2_MASK,
|
||||
rt5677->pdata.jd2_gpio <<
|
||||
RT5677_SEL_GPIO_JD2_SFT);
|
||||
|
||||
if (rt5677->pdata.jd3_gpio)
|
||||
regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1,
|
||||
RT5677_SEL_GPIO_JD3_MASK,
|
||||
rt5677->pdata.jd3_gpio <<
|
||||
RT5677_SEL_GPIO_JD3_SFT);
|
||||
}
|
||||
|
||||
mutex_init(&rt5677->dsp_cmd_lock);
|
||||
mutex_init(&rt5677->dsp_pri_lock);
|
||||
|
||||
|
@ -4955,6 +4935,7 @@ static struct snd_soc_dai_driver rt5677_dai[] = {
|
|||
};
|
||||
|
||||
static const struct snd_soc_component_driver soc_component_dev_rt5677 = {
|
||||
.name = RT5677_DRV_NAME,
|
||||
.probe = rt5677_probe,
|
||||
.remove = rt5677_remove,
|
||||
.suspend = rt5677_suspend,
|
||||
|
@ -5016,80 +4997,202 @@ static const struct acpi_device_id rt5677_acpi_match[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(acpi, rt5677_acpi_match);
|
||||
|
||||
static void rt5677_read_acpi_properties(struct rt5677_priv *rt5677,
|
||||
static void rt5677_read_device_properties(struct rt5677_priv *rt5677,
|
||||
struct device *dev)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (!device_property_read_u32(dev, "DCLK", &val))
|
||||
rt5677->pdata.dmic2_clk_pin = val;
|
||||
rt5677->pdata.in1_diff =
|
||||
device_property_read_bool(dev, "IN1") ||
|
||||
device_property_read_bool(dev, "realtek,in1-differential");
|
||||
|
||||
rt5677->pdata.in1_diff = device_property_read_bool(dev, "IN1");
|
||||
rt5677->pdata.in2_diff = device_property_read_bool(dev, "IN2");
|
||||
rt5677->pdata.lout1_diff = device_property_read_bool(dev, "OUT1");
|
||||
rt5677->pdata.lout2_diff = device_property_read_bool(dev, "OUT2");
|
||||
rt5677->pdata.lout3_diff = device_property_read_bool(dev, "OUT3");
|
||||
rt5677->pdata.in2_diff =
|
||||
device_property_read_bool(dev, "IN2") ||
|
||||
device_property_read_bool(dev, "realtek,in2-differential");
|
||||
|
||||
device_property_read_u32(dev, "JD1", &rt5677->pdata.jd1_gpio);
|
||||
device_property_read_u32(dev, "JD2", &rt5677->pdata.jd2_gpio);
|
||||
device_property_read_u32(dev, "JD3", &rt5677->pdata.jd3_gpio);
|
||||
}
|
||||
rt5677->pdata.lout1_diff =
|
||||
device_property_read_bool(dev, "OUT1") ||
|
||||
device_property_read_bool(dev, "realtek,lout1-differential");
|
||||
|
||||
static void rt5677_read_device_properties(struct rt5677_priv *rt5677,
|
||||
struct device *dev)
|
||||
{
|
||||
rt5677->pdata.in1_diff = device_property_read_bool(dev,
|
||||
"realtek,in1-differential");
|
||||
rt5677->pdata.in2_diff = device_property_read_bool(dev,
|
||||
"realtek,in2-differential");
|
||||
rt5677->pdata.lout1_diff = device_property_read_bool(dev,
|
||||
"realtek,lout1-differential");
|
||||
rt5677->pdata.lout2_diff = device_property_read_bool(dev,
|
||||
"realtek,lout2-differential");
|
||||
rt5677->pdata.lout3_diff = device_property_read_bool(dev,
|
||||
"realtek,lout3-differential");
|
||||
rt5677->pdata.lout2_diff =
|
||||
device_property_read_bool(dev, "OUT2") ||
|
||||
device_property_read_bool(dev, "realtek,lout2-differential");
|
||||
|
||||
rt5677->pdata.lout3_diff =
|
||||
device_property_read_bool(dev, "OUT3") ||
|
||||
device_property_read_bool(dev, "realtek,lout3-differential");
|
||||
|
||||
device_property_read_u8_array(dev, "realtek,gpio-config",
|
||||
rt5677->pdata.gpio_config, RT5677_GPIO_NUM);
|
||||
rt5677->pdata.gpio_config,
|
||||
RT5677_GPIO_NUM);
|
||||
|
||||
device_property_read_u32(dev, "realtek,jd1-gpio",
|
||||
&rt5677->pdata.jd1_gpio);
|
||||
device_property_read_u32(dev, "realtek,jd2-gpio",
|
||||
&rt5677->pdata.jd2_gpio);
|
||||
device_property_read_u32(dev, "realtek,jd3-gpio",
|
||||
&rt5677->pdata.jd3_gpio);
|
||||
if (!device_property_read_u32(dev, "DCLK", &val) ||
|
||||
!device_property_read_u32(dev, "realtek,dmic2_clk_pin", &val))
|
||||
rt5677->pdata.dmic2_clk_pin = val;
|
||||
|
||||
if (!device_property_read_u32(dev, "JD1", &val) ||
|
||||
!device_property_read_u32(dev, "realtek,jd1-gpio", &val))
|
||||
rt5677->pdata.jd1_gpio = val;
|
||||
|
||||
if (!device_property_read_u32(dev, "JD2", &val) ||
|
||||
!device_property_read_u32(dev, "realtek,jd2-gpio", &val))
|
||||
rt5677->pdata.jd2_gpio = val;
|
||||
|
||||
if (!device_property_read_u32(dev, "JD3", &val) ||
|
||||
!device_property_read_u32(dev, "realtek,jd3-gpio", &val))
|
||||
rt5677->pdata.jd3_gpio = val;
|
||||
}
|
||||
|
||||
static struct regmap_irq rt5677_irqs[] = {
|
||||
struct rt5677_irq_desc {
|
||||
unsigned int enable_mask;
|
||||
unsigned int status_mask;
|
||||
unsigned int polarity_mask;
|
||||
};
|
||||
|
||||
static const struct rt5677_irq_desc rt5677_irq_descs[] = {
|
||||
[RT5677_IRQ_JD1] = {
|
||||
.reg_offset = 0,
|
||||
.mask = RT5677_EN_IRQ_GPIO_JD1,
|
||||
.enable_mask = RT5677_EN_IRQ_GPIO_JD1,
|
||||
.status_mask = RT5677_STA_GPIO_JD1,
|
||||
.polarity_mask = RT5677_INV_GPIO_JD1,
|
||||
},
|
||||
[RT5677_IRQ_JD2] = {
|
||||
.reg_offset = 0,
|
||||
.mask = RT5677_EN_IRQ_GPIO_JD2,
|
||||
.enable_mask = RT5677_EN_IRQ_GPIO_JD2,
|
||||
.status_mask = RT5677_STA_GPIO_JD2,
|
||||
.polarity_mask = RT5677_INV_GPIO_JD2,
|
||||
},
|
||||
[RT5677_IRQ_JD3] = {
|
||||
.reg_offset = 0,
|
||||
.mask = RT5677_EN_IRQ_GPIO_JD3,
|
||||
.enable_mask = RT5677_EN_IRQ_GPIO_JD3,
|
||||
.status_mask = RT5677_STA_GPIO_JD3,
|
||||
.polarity_mask = RT5677_INV_GPIO_JD3,
|
||||
},
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip rt5677_irq_chip = {
|
||||
.name = "rt5677",
|
||||
.irqs = rt5677_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rt5677_irqs),
|
||||
static irqreturn_t rt5677_irq(int unused, void *data)
|
||||
{
|
||||
struct rt5677_priv *rt5677 = data;
|
||||
int ret = 0, loop, i, reg_irq, virq;
|
||||
bool irq_fired = false;
|
||||
|
||||
.num_regs = 1,
|
||||
.status_base = RT5677_IRQ_CTRL1,
|
||||
.mask_base = RT5677_IRQ_CTRL1,
|
||||
.mask_invert = 1,
|
||||
mutex_lock(&rt5677->irq_lock);
|
||||
|
||||
/*
|
||||
* Loop to handle interrupts until the last i2c read shows no pending
|
||||
* irqs. The interrupt line is shared by multiple interrupt sources.
|
||||
* After the regmap_read() below, a new interrupt source line may
|
||||
* become high before the regmap_write() finishes, so there isn't a
|
||||
* rising edge on the shared interrupt line for the new interrupt. Thus,
|
||||
* the loop is needed to avoid missing irqs.
|
||||
*
|
||||
* A safeguard of 20 loops is used to avoid hanging in the irq handler
|
||||
* if there is something wrong with the interrupt status update. The
|
||||
* interrupt sources here are audio jack plug/unplug events which
|
||||
* shouldn't happen at a high frequency for a long period of time.
|
||||
* Empirically, more than 3 loops have never been seen.
|
||||
*/
|
||||
for (loop = 0; loop < 20; loop++) {
|
||||
/* Read interrupt status */
|
||||
ret = regmap_read(rt5677->regmap, RT5677_IRQ_CTRL1, ®_irq);
|
||||
if (ret) {
|
||||
dev_err(rt5677->dev, "failed reading IRQ status: %d\n",
|
||||
ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
irq_fired = false;
|
||||
for (i = 0; i < RT5677_IRQ_NUM; i++) {
|
||||
if (reg_irq & rt5677_irq_descs[i].status_mask) {
|
||||
irq_fired = true;
|
||||
virq = irq_find_mapping(rt5677->domain, i);
|
||||
if (virq)
|
||||
handle_nested_irq(virq);
|
||||
|
||||
/* Clear the interrupt by flipping the polarity
|
||||
* of the interrupt source line that fired
|
||||
*/
|
||||
reg_irq ^= rt5677_irq_descs[i].polarity_mask;
|
||||
}
|
||||
}
|
||||
if (!irq_fired)
|
||||
goto exit;
|
||||
|
||||
ret = regmap_write(rt5677->regmap, RT5677_IRQ_CTRL1, reg_irq);
|
||||
if (ret) {
|
||||
dev_err(rt5677->dev, "failed updating IRQ status: %d\n",
|
||||
ret);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
exit:
|
||||
mutex_unlock(&rt5677->irq_lock);
|
||||
if (irq_fired)
|
||||
return IRQ_HANDLED;
|
||||
else
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static void rt5677_irq_bus_lock(struct irq_data *data)
|
||||
{
|
||||
struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data);
|
||||
|
||||
mutex_lock(&rt5677->irq_lock);
|
||||
}
|
||||
|
||||
static void rt5677_irq_bus_sync_unlock(struct irq_data *data)
|
||||
{
|
||||
struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data);
|
||||
|
||||
// Set the enable/disable bits for the jack detect IRQs.
|
||||
regmap_update_bits(rt5677->regmap, RT5677_IRQ_CTRL1,
|
||||
RT5677_EN_IRQ_GPIO_JD1 | RT5677_EN_IRQ_GPIO_JD2 |
|
||||
RT5677_EN_IRQ_GPIO_JD3, rt5677->irq_en);
|
||||
mutex_unlock(&rt5677->irq_lock);
|
||||
}
|
||||
|
||||
static void rt5677_irq_enable(struct irq_data *data)
|
||||
{
|
||||
struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data);
|
||||
|
||||
rt5677->irq_en |= rt5677_irq_descs[data->hwirq].enable_mask;
|
||||
}
|
||||
|
||||
static void rt5677_irq_disable(struct irq_data *data)
|
||||
{
|
||||
struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data);
|
||||
|
||||
rt5677->irq_en &= ~rt5677_irq_descs[data->hwirq].enable_mask;
|
||||
}
|
||||
|
||||
static struct irq_chip rt5677_irq_chip = {
|
||||
.name = "rt5677_irq_chip",
|
||||
.irq_bus_lock = rt5677_irq_bus_lock,
|
||||
.irq_bus_sync_unlock = rt5677_irq_bus_sync_unlock,
|
||||
.irq_disable = rt5677_irq_disable,
|
||||
.irq_enable = rt5677_irq_enable,
|
||||
};
|
||||
|
||||
static int rt5677_irq_map(struct irq_domain *h, unsigned int virq,
|
||||
irq_hw_number_t hw)
|
||||
{
|
||||
struct rt5677_priv *rt5677 = h->host_data;
|
||||
|
||||
irq_set_chip_data(virq, rt5677);
|
||||
irq_set_chip(virq, &rt5677_irq_chip);
|
||||
irq_set_nested_thread(virq, 1);
|
||||
irq_set_noprobe(virq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct irq_domain_ops rt5677_domain_ops = {
|
||||
.map = rt5677_irq_map,
|
||||
.xlate = irq_domain_xlate_twocell,
|
||||
};
|
||||
|
||||
static int rt5677_init_irq(struct i2c_client *i2c)
|
||||
{
|
||||
int ret;
|
||||
struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c);
|
||||
unsigned int jd_mask = 0, jd_val = 0;
|
||||
|
||||
if (!rt5677->pdata.jd1_gpio &&
|
||||
!rt5677->pdata.jd2_gpio &&
|
||||
|
@ -5101,24 +5204,53 @@ static int rt5677_init_irq(struct i2c_client *i2c)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(rt5677->regmap, i2c->irq,
|
||||
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 0,
|
||||
&rt5677_irq_chip, &rt5677->irq_data);
|
||||
mutex_init(&rt5677->irq_lock);
|
||||
|
||||
if (ret != 0) {
|
||||
dev_err(&i2c->dev, "Failed to register IRQ chip: %d\n", ret);
|
||||
return ret;
|
||||
/*
|
||||
* Select RC as the debounce clock so that GPIO works even when
|
||||
* MCLK is gated which happens when there is no audio stream
|
||||
* (SND_SOC_BIAS_OFF).
|
||||
*/
|
||||
regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC,
|
||||
RT5677_IRQ_DEBOUNCE_SEL_MASK,
|
||||
RT5677_IRQ_DEBOUNCE_SEL_RC);
|
||||
/* Enable auto power on RC when GPIO states are changed */
|
||||
regmap_update_bits(rt5677->regmap, RT5677_GEN_CTRL1, 0xff, 0xff);
|
||||
|
||||
/* Select and enable jack detection sources per platform data */
|
||||
if (rt5677->pdata.jd1_gpio) {
|
||||
jd_mask |= RT5677_SEL_GPIO_JD1_MASK;
|
||||
jd_val |= rt5677->pdata.jd1_gpio << RT5677_SEL_GPIO_JD1_SFT;
|
||||
}
|
||||
if (rt5677->pdata.jd2_gpio) {
|
||||
jd_mask |= RT5677_SEL_GPIO_JD2_MASK;
|
||||
jd_val |= rt5677->pdata.jd2_gpio << RT5677_SEL_GPIO_JD2_SFT;
|
||||
}
|
||||
if (rt5677->pdata.jd3_gpio) {
|
||||
jd_mask |= RT5677_SEL_GPIO_JD3_MASK;
|
||||
jd_val |= rt5677->pdata.jd3_gpio << RT5677_SEL_GPIO_JD3_SFT;
|
||||
}
|
||||
regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1, jd_mask, jd_val);
|
||||
|
||||
/* Set GPIO1 pin to be IRQ output */
|
||||
regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1,
|
||||
RT5677_GPIO1_PIN_MASK, RT5677_GPIO1_PIN_IRQ);
|
||||
|
||||
/* Ready to listen for interrupts */
|
||||
rt5677->domain = irq_domain_add_linear(i2c->dev.of_node,
|
||||
RT5677_IRQ_NUM, &rt5677_domain_ops, rt5677);
|
||||
if (!rt5677->domain) {
|
||||
dev_err(&i2c->dev, "Failed to create IRQ domain\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, rt5677_irq,
|
||||
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
||||
"rt5677", rt5677);
|
||||
if (ret)
|
||||
dev_err(&i2c->dev, "Failed to request IRQ: %d\n", ret);
|
||||
|
||||
static void rt5677_free_irq(struct i2c_client *i2c)
|
||||
{
|
||||
struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c);
|
||||
|
||||
if (rt5677->irq_data)
|
||||
regmap_del_irq_chip(i2c->irq, rt5677->irq_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rt5677_i2c_probe(struct i2c_client *i2c)
|
||||
|
@ -5132,6 +5264,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
|
|||
if (rt5677 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
rt5677->dev = &i2c->dev;
|
||||
i2c_set_clientdata(i2c, rt5677);
|
||||
|
||||
if (i2c->dev.of_node) {
|
||||
|
@ -5140,20 +5273,18 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
|
|||
match_id = of_match_device(rt5677_of_match, &i2c->dev);
|
||||
if (match_id)
|
||||
rt5677->type = (enum rt5677_type)match_id->data;
|
||||
|
||||
rt5677_read_device_properties(rt5677, &i2c->dev);
|
||||
} else if (ACPI_HANDLE(&i2c->dev)) {
|
||||
const struct acpi_device_id *acpi_id;
|
||||
|
||||
acpi_id = acpi_match_device(rt5677_acpi_match, &i2c->dev);
|
||||
if (acpi_id)
|
||||
rt5677->type = (enum rt5677_type)acpi_id->driver_data;
|
||||
|
||||
rt5677_read_acpi_properties(rt5677, &i2c->dev);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rt5677_read_device_properties(rt5677, &i2c->dev);
|
||||
|
||||
/* pow-ldo2 and reset are optional. The codec pins may be statically
|
||||
* connected on the board without gpios. If the gpio device property
|
||||
* isn't specified, devm_gpiod_get_optional returns NULL.
|
||||
|
@ -5247,7 +5378,9 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
|
|||
RT5677_MICBIAS1_CTRL_VDD_3_3V);
|
||||
|
||||
rt5677_init_gpio(i2c);
|
||||
rt5677_init_irq(i2c);
|
||||
ret = rt5677_init_irq(i2c);
|
||||
if (ret)
|
||||
dev_err(&i2c->dev, "Failed to initialize irq: %d\n", ret);
|
||||
|
||||
return devm_snd_soc_register_component(&i2c->dev,
|
||||
&soc_component_dev_rt5677,
|
||||
|
@ -5256,7 +5389,6 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
|
|||
|
||||
static int rt5677_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
rt5677_free_irq(i2c);
|
||||
rt5677_free_gpio(i2c);
|
||||
|
||||
return 0;
|
||||
|
@ -5264,7 +5396,7 @@ static int rt5677_i2c_remove(struct i2c_client *i2c)
|
|||
|
||||
static struct i2c_driver rt5677_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "rt5677",
|
||||
.name = RT5677_DRV_NAME,
|
||||
.of_match_table = rt5677_of_match,
|
||||
.acpi_match_table = ACPI_PTR(rt5677_acpi_match),
|
||||
},
|
||||
|
|
|
@ -1453,9 +1453,37 @@
|
|||
#define RT5677_I2S4_CLK_SEL_MASK (0xf)
|
||||
#define RT5677_I2S4_CLK_SEL_SFT 0
|
||||
|
||||
/* VAD Function Control 1 (0x9c) */
|
||||
#define RT5677_VAD_MIN_DUR_MASK (0x3 << 13)
|
||||
#define RT5677_VAD_MIN_DUR_SFT 13
|
||||
#define RT5677_VAD_ADPCM_BYPASS (1 << 10)
|
||||
#define RT5677_VAD_ADPCM_BYPASS_BIT 10
|
||||
#define RT5677_VAD_FG2ENC (1 << 9)
|
||||
#define RT5677_VAD_FG2ENC_BIT 9
|
||||
#define RT5677_VAD_BUF_OW (1 << 8)
|
||||
#define RT5677_VAD_BUF_OW_BIT 8
|
||||
#define RT5677_VAD_CLR_FLAG (1 << 7)
|
||||
#define RT5677_VAD_CLR_FLAG_BIT 7
|
||||
#define RT5677_VAD_BUF_POP (1 << 6)
|
||||
#define RT5677_VAD_BUF_POP_BIT 6
|
||||
#define RT5677_VAD_BUF_PUSH (1 << 5)
|
||||
#define RT5677_VAD_BUF_PUSH_BIT 5
|
||||
#define RT5677_VAD_DET_ENABLE (1 << 4)
|
||||
#define RT5677_VAD_DET_ENABLE_BIT 4
|
||||
#define RT5677_VAD_FUNC_ENABLE (1 << 3)
|
||||
#define RT5677_VAD_FUNC_ENABLE_BIT 3
|
||||
#define RT5677_VAD_FUNC_RESET (1 << 2)
|
||||
#define RT5677_VAD_FUNC_RESET_BIT 2
|
||||
|
||||
/* VAD Function Control 4 (0x9f) */
|
||||
#define RT5677_VAD_SRC_MASK (0x7 << 8)
|
||||
#define RT5677_VAD_OUT_SRC_RATE_MASK (0x1 << 11)
|
||||
#define RT5677_VAD_OUT_SRC_RATE_SFT 11
|
||||
#define RT5677_VAD_OUT_SRC_MASK (0x1 << 10)
|
||||
#define RT5677_VAD_OUT_SRC_SFT 10
|
||||
#define RT5677_VAD_SRC_MASK (0x3 << 8)
|
||||
#define RT5677_VAD_SRC_SFT 8
|
||||
#define RT5677_VAD_LV_DIFF_MASK (0xff << 0)
|
||||
#define RT5677_VAD_LV_DIFF_SFT 0
|
||||
|
||||
/* DSP InBound Control (0xa3) */
|
||||
#define RT5677_IB01_SRC_MASK (0x7 << 12)
|
||||
|
@ -1633,6 +1661,12 @@
|
|||
#define RT5677_GPIO6_P_NOR (0x0 << 0)
|
||||
#define RT5677_GPIO6_P_INV (0x1 << 0)
|
||||
|
||||
/* General Control (0xfa) */
|
||||
#define RT5677_IRQ_DEBOUNCE_SEL_MASK (0x3 << 3)
|
||||
#define RT5677_IRQ_DEBOUNCE_SEL_MCLK (0x0 << 3)
|
||||
#define RT5677_IRQ_DEBOUNCE_SEL_RC (0x1 << 3)
|
||||
#define RT5677_IRQ_DEBOUNCE_SEL_SLIM (0x2 << 3)
|
||||
|
||||
/* Virtual DSP Mixer Control (0xf7 0xf8 0xf9) */
|
||||
#define RT5677_DSP_IB_01_H (0x1 << 15)
|
||||
#define RT5677_DSP_IB_01_H_SFT 15
|
||||
|
@ -1671,6 +1705,8 @@
|
|||
#define RT5677_FIRMWARE1 "rt5677_dsp_fw1.bin"
|
||||
#define RT5677_FIRMWARE2 "rt5677_dsp_fw2.bin"
|
||||
|
||||
#define RT5677_DRV_NAME "rt5677"
|
||||
|
||||
/* System Clock Source */
|
||||
enum {
|
||||
RT5677_SCLK_S_MCLK,
|
||||
|
@ -1710,6 +1746,7 @@ enum {
|
|||
RT5677_IRQ_JD1,
|
||||
RT5677_IRQ_JD2,
|
||||
RT5677_IRQ_JD3,
|
||||
RT5677_IRQ_NUM,
|
||||
};
|
||||
|
||||
enum rt5677_type {
|
||||
|
@ -1788,6 +1825,7 @@ struct rt5677_platform_data {
|
|||
|
||||
struct rt5677_priv {
|
||||
struct snd_soc_component *component;
|
||||
struct device *dev;
|
||||
struct rt5677_platform_data pdata;
|
||||
struct regmap *regmap, *regmap_physical;
|
||||
const struct firmware *fw1, *fw2;
|
||||
|
@ -1808,9 +1846,13 @@ struct rt5677_priv {
|
|||
struct gpio_chip gpio_chip;
|
||||
#endif
|
||||
bool dsp_vad_en;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
bool is_dsp_mode;
|
||||
bool is_vref_slow;
|
||||
|
||||
/* Interrupt handling */
|
||||
struct irq_domain *domain;
|
||||
struct mutex irq_lock;
|
||||
unsigned int irq_en;
|
||||
};
|
||||
|
||||
int rt5677_sel_asrc_clk_src(struct snd_soc_component *component,
|
||||
|
|
|
@ -2662,15 +2662,9 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
|
|||
|
||||
}
|
||||
|
||||
return snd_soc_register_component(&i2c->dev, &soc_component_dev_rt5682,
|
||||
rt5682_dai, ARRAY_SIZE(rt5682_dai));
|
||||
}
|
||||
|
||||
static int rt5682_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
snd_soc_unregister_component(&i2c->dev);
|
||||
|
||||
return 0;
|
||||
return devm_snd_soc_register_component(&i2c->dev,
|
||||
&soc_component_dev_rt5682,
|
||||
rt5682_dai, ARRAY_SIZE(rt5682_dai));
|
||||
}
|
||||
|
||||
static void rt5682_i2c_shutdown(struct i2c_client *client)
|
||||
|
@ -2703,7 +2697,6 @@ static struct i2c_driver rt5682_i2c_driver = {
|
|||
.acpi_match_table = ACPI_PTR(rt5682_acpi_match),
|
||||
},
|
||||
.probe = rt5682_i2c_probe,
|
||||
.remove = rt5682_i2c_remove,
|
||||
.shutdown = rt5682_i2c_shutdown,
|
||||
.id_table = rt5682_i2c_id,
|
||||
};
|
||||
|
|
|
@ -721,8 +721,8 @@ static const struct regmap_config tas5721_regmap_config = {
|
|||
static const struct tas571x_chip tas5721_chip = {
|
||||
.supply_names = tas5721_supply_names,
|
||||
.num_supply_names = ARRAY_SIZE(tas5721_supply_names),
|
||||
.controls = tas5711_controls,
|
||||
.num_controls = ARRAY_SIZE(tas5711_controls),
|
||||
.controls = tas5721_controls,
|
||||
.num_controls = ARRAY_SIZE(tas5721_controls),
|
||||
.regmap_config = &tas5721_regmap_config,
|
||||
.vol_reg_size = 1,
|
||||
};
|
||||
|
|
|
@ -321,6 +321,9 @@ static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 50, 0);
|
|||
*/
|
||||
static DECLARE_TLV_DB_SCALE(output_stage_tlv, -5900, 50, 1);
|
||||
|
||||
/* Output volumes. From 0 to 9 dB in 1 dB steps */
|
||||
static const DECLARE_TLV_DB_SCALE(out_tlv, 0, 100, 0);
|
||||
|
||||
static const struct snd_kcontrol_new aic3x_snd_controls[] = {
|
||||
/* Output */
|
||||
SOC_DOUBLE_R_TLV("PCM Playback Volume",
|
||||
|
@ -383,11 +386,17 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
|
|||
DACL1_2_HPLCOM_VOL, DACR1_2_HPRCOM_VOL,
|
||||
0, 118, 1, output_stage_tlv),
|
||||
|
||||
/* Output pin mute controls */
|
||||
/* Output pin controls */
|
||||
SOC_DOUBLE_R_TLV("Line Playback Volume", LLOPM_CTRL, RLOPM_CTRL, 4,
|
||||
9, 0, out_tlv),
|
||||
SOC_DOUBLE_R("Line Playback Switch", LLOPM_CTRL, RLOPM_CTRL, 3,
|
||||
0x01, 0),
|
||||
SOC_DOUBLE_R_TLV("HP Playback Volume", HPLOUT_CTRL, HPROUT_CTRL, 4,
|
||||
9, 0, out_tlv),
|
||||
SOC_DOUBLE_R("HP Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3,
|
||||
0x01, 0),
|
||||
SOC_DOUBLE_R_TLV("HPCOM Playback Volume", HPLCOM_CTRL, HPRCOM_CTRL,
|
||||
4, 9, 0, out_tlv),
|
||||
SOC_DOUBLE_R("HPCOM Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3,
|
||||
0x01, 0),
|
||||
|
||||
|
@ -469,6 +478,9 @@ static const struct snd_kcontrol_new aic3x_mono_controls[] = {
|
|||
0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_SINGLE("Mono Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0),
|
||||
SOC_SINGLE_TLV("Mono Playback Volume", MONOLOPM_CTRL, 4, 9, 0,
|
||||
out_tlv),
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -86,11 +86,6 @@
|
|||
#define WCD9335_DEC_PWR_LVL_HP 0x04
|
||||
#define WCD9335_DEC_PWR_LVL_DF 0x00
|
||||
|
||||
#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
|
||||
#define CF_MIN_3DB_4HZ 0x0
|
||||
#define CF_MIN_3DB_75HZ 0x1
|
||||
#define CF_MIN_3DB_150HZ 0x2
|
||||
|
||||
#define WCD9335_SLIM_RX_CH(p) \
|
||||
{.port = p + WCD9335_RX_START, .shift = p,}
|
||||
|
||||
|
@ -2734,7 +2729,7 @@ static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w,
|
|||
char *dec;
|
||||
u8 hpf_coff_freq;
|
||||
|
||||
widget_name = kstrndup(w->name, 15, GFP_KERNEL);
|
||||
widget_name = kmemdup_nul(w->name, 15, GFP_KERNEL);
|
||||
if (!widget_name)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -728,41 +728,18 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
|
|||
struct dentry *root = NULL;
|
||||
int i;
|
||||
|
||||
if (!component->debugfs_root) {
|
||||
adsp_err(dsp, "No codec debugfs root\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
root = debugfs_create_dir(dsp->name, component->debugfs_root);
|
||||
|
||||
if (!root)
|
||||
goto err;
|
||||
debugfs_create_bool("booted", 0444, root, &dsp->booted);
|
||||
debugfs_create_bool("running", 0444, root, &dsp->running);
|
||||
debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id);
|
||||
debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version);
|
||||
|
||||
if (!debugfs_create_bool("booted", 0444, root, &dsp->booted))
|
||||
goto err;
|
||||
|
||||
if (!debugfs_create_bool("running", 0444, root, &dsp->running))
|
||||
goto err;
|
||||
|
||||
if (!debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id))
|
||||
goto err;
|
||||
|
||||
if (!debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version))
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i) {
|
||||
if (!debugfs_create_file(wm_adsp_debugfs_fops[i].name,
|
||||
0444, root, dsp,
|
||||
&wm_adsp_debugfs_fops[i].fops))
|
||||
goto err;
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i)
|
||||
debugfs_create_file(wm_adsp_debugfs_fops[i].name, 0444, root,
|
||||
dsp, &wm_adsp_debugfs_fops[i].fops);
|
||||
|
||||
dsp->debugfs_root = root;
|
||||
return;
|
||||
|
||||
err:
|
||||
debugfs_remove_recursive(root);
|
||||
adsp_err(dsp, "Failed to create debugfs\n");
|
||||
}
|
||||
|
||||
static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp)
|
||||
|
|
|
@ -29,22 +29,28 @@
|
|||
|
||||
#define DRV_NAME "efika-audio-fabric"
|
||||
|
||||
SND_SOC_DAILINK_DEFS(analog,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("mpc5200-psc-ac97.0")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("stac9766-codec",
|
||||
"stac9766-hifi-analog")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("mpc5200-pcm-audio")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(iec958,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("mpc5200-psc-ac97.1")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("stac9766-codec",
|
||||
"stac9766-hifi-IEC958")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("mpc5200-pcm-audio")));
|
||||
|
||||
static struct snd_soc_dai_link efika_fabric_dai[] = {
|
||||
{
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 Analog",
|
||||
.codec_dai_name = "stac9766-hifi-analog",
|
||||
.cpu_dai_name = "mpc5200-psc-ac97.0",
|
||||
.platform_name = "mpc5200-pcm-audio",
|
||||
.codec_name = "stac9766-codec",
|
||||
SND_SOC_DAILINK_REG(analog),
|
||||
},
|
||||
{
|
||||
.name = "AC97",
|
||||
.stream_name = "AC97 IEC958",
|
||||
.codec_dai_name = "stac9766-hifi-IEC958",
|
||||
.cpu_dai_name = "mpc5200-psc-ac97.1",
|
||||
.platform_name = "mpc5200-pcm-audio",
|
||||
.codec_name = "stac9766-codec",
|
||||
SND_SOC_DAILINK_REG(iec958),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -61,13 +61,18 @@ static const struct snd_soc_ops eukrea_tlv320_snd_ops = {
|
|||
.hw_params = eukrea_tlv320_hw_params,
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEFS(hifi,
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "tlv320aic23-hifi")),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
|
||||
static struct snd_soc_dai_link eukrea_tlv320_dai = {
|
||||
.name = "tlv320aic23",
|
||||
.stream_name = "TLV320AIC23",
|
||||
.codec_dai_name = "tlv320aic23-hifi",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM,
|
||||
.ops = &eukrea_tlv320_snd_ops,
|
||||
SND_SOC_DAILINK_REG(hifi),
|
||||
};
|
||||
|
||||
static struct snd_soc_card eukrea_tlv320 = {
|
||||
|
@ -104,7 +109,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
|
|||
|
||||
codec_np = of_parse_phandle(ssi_np, "codec-handle", 0);
|
||||
if (codec_np)
|
||||
eukrea_tlv320_dai.codec_of_node = codec_np;
|
||||
eukrea_tlv320_dai.codecs->of_node = codec_np;
|
||||
else
|
||||
dev_err(&pdev->dev, "codec-handle node missing or invalid.\n");
|
||||
|
||||
|
@ -128,12 +133,12 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
|
|||
int_port--;
|
||||
ext_port--;
|
||||
|
||||
eukrea_tlv320_dai.cpu_of_node = ssi_np;
|
||||
eukrea_tlv320_dai.platform_of_node = ssi_np;
|
||||
eukrea_tlv320_dai.cpus->of_node = ssi_np;
|
||||
eukrea_tlv320_dai.platforms->of_node = ssi_np;
|
||||
} else {
|
||||
eukrea_tlv320_dai.cpu_dai_name = "imx-ssi.0";
|
||||
eukrea_tlv320_dai.platform_name = "imx-ssi.0";
|
||||
eukrea_tlv320_dai.codec_name = "tlv320aic23-codec.0-001a";
|
||||
eukrea_tlv320_dai.cpus->dai_name = "imx-ssi.0";
|
||||
eukrea_tlv320_dai.platforms->name = "imx-ssi.0";
|
||||
eukrea_tlv320_dai.codecs->name = "tlv320aic23-codec.0-001a";
|
||||
eukrea_tlv320.name = "cpuimx-audio";
|
||||
}
|
||||
|
||||
|
|
|
@ -200,32 +200,47 @@ static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
SND_SOC_DAILINK_DEFS(hifi,
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(hifi_fe,
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_DUMMY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(hifi_be,
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_EMPTY()),
|
||||
DAILINK_COMP_ARRAY(COMP_DUMMY()));
|
||||
|
||||
static struct snd_soc_dai_link fsl_asoc_card_dai[] = {
|
||||
/* Default ASoC DAI Link*/
|
||||
{
|
||||
.name = "HiFi",
|
||||
.stream_name = "HiFi",
|
||||
.ops = &fsl_asoc_card_ops,
|
||||
SND_SOC_DAILINK_REG(hifi),
|
||||
},
|
||||
/* DPCM Link between Front-End and Back-End (Optional) */
|
||||
{
|
||||
.name = "HiFi-ASRC-FE",
|
||||
.stream_name = "HiFi-ASRC-FE",
|
||||
.codec_name = "snd-soc-dummy",
|
||||
.codec_dai_name = "snd-soc-dummy-dai",
|
||||
.dpcm_playback = 1,
|
||||
.dpcm_capture = 1,
|
||||
.dynamic = 1,
|
||||
SND_SOC_DAILINK_REG(hifi_fe),
|
||||
},
|
||||
{
|
||||
.name = "HiFi-ASRC-BE",
|
||||
.stream_name = "HiFi-ASRC-BE",
|
||||
.platform_name = "snd-soc-dummy",
|
||||
.be_hw_params_fixup = be_hw_params_fixup,
|
||||
.ops = &fsl_asoc_card_ops,
|
||||
.dpcm_playback = 1,
|
||||
.dpcm_capture = 1,
|
||||
.no_pcm = 1,
|
||||
SND_SOC_DAILINK_REG(hifi_be),
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -616,11 +631,11 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
/* Normal DAI Link */
|
||||
priv->dai_link[0].cpu_of_node = cpu_np;
|
||||
priv->dai_link[0].codec_dai_name = codec_dai_name;
|
||||
priv->dai_link[0].cpus->of_node = cpu_np;
|
||||
priv->dai_link[0].codecs->dai_name = codec_dai_name;
|
||||
|
||||
if (!fsl_asoc_card_is_ac97(priv))
|
||||
priv->dai_link[0].codec_of_node = codec_np;
|
||||
priv->dai_link[0].codecs->of_node = codec_np;
|
||||
else {
|
||||
u32 idx;
|
||||
|
||||
|
@ -631,29 +646,29 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
|
|||
goto asrc_fail;
|
||||
}
|
||||
|
||||
priv->dai_link[0].codec_name =
|
||||
priv->dai_link[0].codecs->name =
|
||||
devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
||||
"ac97-codec.%u",
|
||||
(unsigned int)idx);
|
||||
if (!priv->dai_link[0].codec_name) {
|
||||
if (!priv->dai_link[0].codecs->name) {
|
||||
ret = -ENOMEM;
|
||||
goto asrc_fail;
|
||||
}
|
||||
}
|
||||
|
||||
priv->dai_link[0].platform_of_node = cpu_np;
|
||||
priv->dai_link[0].platforms->of_node = cpu_np;
|
||||
priv->dai_link[0].dai_fmt = priv->dai_fmt;
|
||||
priv->card.num_links = 1;
|
||||
|
||||
if (asrc_pdev) {
|
||||
/* DPCM DAI Links only if ASRC exsits */
|
||||
priv->dai_link[1].cpu_of_node = asrc_np;
|
||||
priv->dai_link[1].platform_of_node = asrc_np;
|
||||
priv->dai_link[2].codec_dai_name = codec_dai_name;
|
||||
priv->dai_link[2].codec_of_node = codec_np;
|
||||
priv->dai_link[2].codec_name =
|
||||
priv->dai_link[0].codec_name;
|
||||
priv->dai_link[2].cpu_of_node = cpu_np;
|
||||
priv->dai_link[1].cpus->of_node = asrc_np;
|
||||
priv->dai_link[1].platforms->of_node = asrc_np;
|
||||
priv->dai_link[2].codecs->dai_name = codec_dai_name;
|
||||
priv->dai_link[2].codecs->of_node = codec_np;
|
||||
priv->dai_link[2].codecs->name =
|
||||
priv->dai_link[0].codecs->name;
|
||||
priv->dai_link[2].cpus->of_node = cpu_np;
|
||||
priv->dai_link[2].dai_fmt = priv->dai_fmt;
|
||||
priv->card.num_links = 3;
|
||||
|
||||
|
|
|
@ -26,32 +26,15 @@
|
|||
#define pair_dbg(fmt, ...) \
|
||||
dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
|
||||
|
||||
/* Sample rates are aligned with that defined in pcm.h file */
|
||||
static const u8 process_option[][12][2] = {
|
||||
/* 8kHz 11.025kHz 16kHz 22.05kHz 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */
|
||||
{{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 5512Hz */
|
||||
{{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 8kHz */
|
||||
{{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 11025Hz */
|
||||
{{1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 16kHz */
|
||||
{{1, 2}, {1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 22050Hz */
|
||||
{{1, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},}, /* 32kHz */
|
||||
{{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 44.1kHz */
|
||||
{{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 48kHz */
|
||||
{{2, 2}, {2, 2}, {2, 2}, {2, 1}, {1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},}, /* 64kHz */
|
||||
{{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 88.2kHz */
|
||||
{{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 96kHz */
|
||||
{{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 176kHz */
|
||||
{{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 192kHz */
|
||||
};
|
||||
|
||||
/* Corresponding to process_option */
|
||||
static int supported_input_rate[] = {
|
||||
5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200,
|
||||
96000, 176400, 192000,
|
||||
static unsigned int supported_asrc_rate[] = {
|
||||
5512, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
|
||||
64000, 88200, 96000, 128000, 176400, 192000,
|
||||
};
|
||||
|
||||
static int supported_asrc_rate[] = {
|
||||
8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000,
|
||||
static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints = {
|
||||
.count = ARRAY_SIZE(supported_asrc_rate),
|
||||
.list = supported_asrc_rate,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -79,6 +62,52 @@ static unsigned char output_clk_map_imx53[] = {
|
|||
|
||||
static unsigned char *clk_map[2];
|
||||
|
||||
/**
|
||||
* Select the pre-processing and post-processing options
|
||||
* Make sure to exclude following unsupported cases before
|
||||
* calling this function:
|
||||
* 1) inrate > 8.125 * outrate
|
||||
* 2) inrate > 16.125 * outrate
|
||||
*
|
||||
* inrate: input sample rate
|
||||
* outrate: output sample rate
|
||||
* pre_proc: return value for pre-processing option
|
||||
* post_proc: return value for post-processing option
|
||||
*/
|
||||
static void fsl_asrc_sel_proc(int inrate, int outrate,
|
||||
int *pre_proc, int *post_proc)
|
||||
{
|
||||
bool post_proc_cond2;
|
||||
bool post_proc_cond0;
|
||||
|
||||
/* select pre_proc between [0, 2] */
|
||||
if (inrate * 8 > 33 * outrate)
|
||||
*pre_proc = 2;
|
||||
else if (inrate * 8 > 15 * outrate) {
|
||||
if (inrate > 152000)
|
||||
*pre_proc = 2;
|
||||
else
|
||||
*pre_proc = 1;
|
||||
} else if (inrate < 76000)
|
||||
*pre_proc = 0;
|
||||
else if (inrate > 152000)
|
||||
*pre_proc = 2;
|
||||
else
|
||||
*pre_proc = 1;
|
||||
|
||||
/* Condition for selection of post-processing */
|
||||
post_proc_cond2 = (inrate * 15 > outrate * 16 && outrate < 56000) ||
|
||||
(inrate > 56000 && outrate < 56000);
|
||||
post_proc_cond0 = inrate * 23 < outrate * 8;
|
||||
|
||||
if (post_proc_cond2)
|
||||
*post_proc = 2;
|
||||
else if (post_proc_cond0)
|
||||
*post_proc = 0;
|
||||
else
|
||||
*post_proc = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request ASRC pair
|
||||
*
|
||||
|
@ -239,6 +268,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
|
|||
u32 inrate, outrate, indiv, outdiv;
|
||||
u32 clk_index[2], div[2];
|
||||
int in, out, channels;
|
||||
int pre_proc, post_proc;
|
||||
struct clk *clk;
|
||||
bool ideal;
|
||||
|
||||
|
@ -264,11 +294,11 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
|
|||
ideal = config->inclk == INCLK_NONE;
|
||||
|
||||
/* Validate input and output sample rates */
|
||||
for (in = 0; in < ARRAY_SIZE(supported_input_rate); in++)
|
||||
if (inrate == supported_input_rate[in])
|
||||
for (in = 0; in < ARRAY_SIZE(supported_asrc_rate); in++)
|
||||
if (inrate == supported_asrc_rate[in])
|
||||
break;
|
||||
|
||||
if (in == ARRAY_SIZE(supported_input_rate)) {
|
||||
if (in == ARRAY_SIZE(supported_asrc_rate)) {
|
||||
pair_err("unsupported input sample rate: %dHz\n", inrate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -282,7 +312,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((outrate >= 8000 && outrate <= 30000) &&
|
||||
if ((outrate >= 5512 && outrate <= 30000) &&
|
||||
(outrate > 24 * inrate || inrate > 8 * outrate)) {
|
||||
pair_err("exceed supported ratio range [1/24, 8] for \
|
||||
inrate/outrate: %d/%d\n", inrate, outrate);
|
||||
|
@ -377,11 +407,13 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
|
|||
ASRCTR_IDRi_MASK(index) | ASRCTR_USRi_MASK(index),
|
||||
ASRCTR_IDR(index) | ASRCTR_USR(index));
|
||||
|
||||
fsl_asrc_sel_proc(inrate, outrate, &pre_proc, &post_proc);
|
||||
|
||||
/* Apply configurations for pre- and post-processing */
|
||||
regmap_update_bits(asrc_priv->regmap, REG_ASRCFG,
|
||||
ASRCFG_PREMODi_MASK(index) | ASRCFG_POSTMODi_MASK(index),
|
||||
ASRCFG_PREMOD(index, process_option[in][out][0]) |
|
||||
ASRCFG_POSTMOD(index, process_option[in][out][1]));
|
||||
ASRCFG_PREMOD(index, pre_proc) |
|
||||
ASRCFG_POSTMOD(index, post_proc));
|
||||
|
||||
return fsl_asrc_set_ideal_ratio(pair, inrate, outrate);
|
||||
}
|
||||
|
@ -455,7 +487,9 @@ static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream,
|
|||
snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_CHANNELS, 2);
|
||||
|
||||
return 0;
|
||||
|
||||
return snd_pcm_hw_constraint_list(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_RATE, &fsl_asrc_rate_constraints);
|
||||
}
|
||||
|
||||
static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
|
||||
|
@ -568,7 +602,6 @@ static int fsl_asrc_dai_probe(struct snd_soc_dai *dai)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define FSL_ASRC_RATES SNDRV_PCM_RATE_8000_192000
|
||||
#define FSL_ASRC_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | \
|
||||
SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
SNDRV_PCM_FMTBIT_S20_3LE)
|
||||
|
@ -579,14 +612,18 @@ static struct snd_soc_dai_driver fsl_asrc_dai = {
|
|||
.stream_name = "ASRC-Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 10,
|
||||
.rates = FSL_ASRC_RATES,
|
||||
.rate_min = 5512,
|
||||
.rate_max = 192000,
|
||||
.rates = SNDRV_PCM_RATE_KNOT,
|
||||
.formats = FSL_ASRC_FORMATS,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "ASRC-Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 10,
|
||||
.rates = FSL_ASRC_RATES,
|
||||
.rate_min = 5512,
|
||||
.rate_max = 192000,
|
||||
.rates = SNDRV_PCM_RATE_KNOT,
|
||||
.formats = FSL_ASRC_FORMATS,
|
||||
},
|
||||
.ops = &fsl_asrc_dai_ops,
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
|
||||
|
@ -466,30 +467,6 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Some platforms might use the same bit to gate all three or two of
|
||||
* clocks, so keep all clocks open/close at the same time for safety
|
||||
*/
|
||||
ret = clk_prepare_enable(esai_priv->coreclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!IS_ERR(esai_priv->spbaclk)) {
|
||||
ret = clk_prepare_enable(esai_priv->spbaclk);
|
||||
if (ret)
|
||||
goto err_spbaclk;
|
||||
}
|
||||
if (!IS_ERR(esai_priv->extalclk)) {
|
||||
ret = clk_prepare_enable(esai_priv->extalclk);
|
||||
if (ret)
|
||||
goto err_extalck;
|
||||
}
|
||||
if (!IS_ERR(esai_priv->fsysclk)) {
|
||||
ret = clk_prepare_enable(esai_priv->fsysclk);
|
||||
if (ret)
|
||||
goto err_fsysclk;
|
||||
}
|
||||
|
||||
if (!dai->active) {
|
||||
/* Set synchronous mode */
|
||||
|
@ -506,16 +483,6 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
|
|||
|
||||
return 0;
|
||||
|
||||
err_fsysclk:
|
||||
if (!IS_ERR(esai_priv->extalclk))
|
||||
clk_disable_unprepare(esai_priv->extalclk);
|
||||
err_extalck:
|
||||
if (!IS_ERR(esai_priv->spbaclk))
|
||||
clk_disable_unprepare(esai_priv->spbaclk);
|
||||
err_spbaclk:
|
||||
clk_disable_unprepare(esai_priv->coreclk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
|
||||
|
@ -576,20 +543,6 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void fsl_esai_shutdown(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (!IS_ERR(esai_priv->fsysclk))
|
||||
clk_disable_unprepare(esai_priv->fsysclk);
|
||||
if (!IS_ERR(esai_priv->extalclk))
|
||||
clk_disable_unprepare(esai_priv->extalclk);
|
||||
if (!IS_ERR(esai_priv->spbaclk))
|
||||
clk_disable_unprepare(esai_priv->spbaclk);
|
||||
clk_disable_unprepare(esai_priv->coreclk);
|
||||
}
|
||||
|
||||
static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
|
@ -658,7 +611,6 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||
|
||||
static const struct snd_soc_dai_ops fsl_esai_dai_ops = {
|
||||
.startup = fsl_esai_startup,
|
||||
.shutdown = fsl_esai_shutdown,
|
||||
.trigger = fsl_esai_trigger,
|
||||
.hw_params = fsl_esai_hw_params,
|
||||
.set_sysclk = fsl_esai_set_dai_sysclk,
|
||||
|
@ -947,6 +899,10 @@ static int fsl_esai_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
regcache_cache_only(esai_priv->regmap, true);
|
||||
|
||||
ret = imx_pcm_dma_init(pdev, IMX_ESAI_DMABUF_SIZE);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
|
||||
|
@ -954,6 +910,13 @@ static int fsl_esai_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int fsl_esai_remove(struct platform_device *pdev)
|
||||
{
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id fsl_esai_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx35-esai", },
|
||||
{ .compatible = "fsl,vf610-esai", },
|
||||
|
@ -961,22 +924,35 @@ static const struct of_device_id fsl_esai_dt_ids[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int fsl_esai_suspend(struct device *dev)
|
||||
{
|
||||
struct fsl_esai *esai = dev_get_drvdata(dev);
|
||||
|
||||
regcache_cache_only(esai->regmap, true);
|
||||
regcache_mark_dirty(esai->regmap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsl_esai_resume(struct device *dev)
|
||||
#ifdef CONFIG_PM
|
||||
static int fsl_esai_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct fsl_esai *esai = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Some platforms might use the same bit to gate all three or two of
|
||||
* clocks, so keep all clocks open/close at the same time for safety
|
||||
*/
|
||||
ret = clk_prepare_enable(esai->coreclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!IS_ERR(esai->spbaclk)) {
|
||||
ret = clk_prepare_enable(esai->spbaclk);
|
||||
if (ret)
|
||||
goto err_spbaclk;
|
||||
}
|
||||
if (!IS_ERR(esai->extalclk)) {
|
||||
ret = clk_prepare_enable(esai->extalclk);
|
||||
if (ret)
|
||||
goto err_extalclk;
|
||||
}
|
||||
if (!IS_ERR(esai->fsysclk)) {
|
||||
ret = clk_prepare_enable(esai->fsysclk);
|
||||
if (ret)
|
||||
goto err_fsysclk;
|
||||
}
|
||||
|
||||
regcache_cache_only(esai->regmap, false);
|
||||
|
||||
/* FIFO reset for safety */
|
||||
|
@ -987,22 +963,59 @@ static int fsl_esai_resume(struct device *dev)
|
|||
|
||||
ret = regcache_sync(esai->regmap);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_regcache_sync;
|
||||
|
||||
/* FIFO reset done */
|
||||
regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
|
||||
regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
|
||||
|
||||
return 0;
|
||||
|
||||
err_regcache_sync:
|
||||
if (!IS_ERR(esai->fsysclk))
|
||||
clk_disable_unprepare(esai->fsysclk);
|
||||
err_fsysclk:
|
||||
if (!IS_ERR(esai->extalclk))
|
||||
clk_disable_unprepare(esai->extalclk);
|
||||
err_extalclk:
|
||||
if (!IS_ERR(esai->spbaclk))
|
||||
clk_disable_unprepare(esai->spbaclk);
|
||||
err_spbaclk:
|
||||
clk_disable_unprepare(esai->coreclk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static int fsl_esai_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct fsl_esai *esai = dev_get_drvdata(dev);
|
||||
|
||||
regcache_cache_only(esai->regmap, true);
|
||||
regcache_mark_dirty(esai->regmap);
|
||||
|
||||
if (!IS_ERR(esai->fsysclk))
|
||||
clk_disable_unprepare(esai->fsysclk);
|
||||
if (!IS_ERR(esai->extalclk))
|
||||
clk_disable_unprepare(esai->extalclk);
|
||||
if (!IS_ERR(esai->spbaclk))
|
||||
clk_disable_unprepare(esai->spbaclk);
|
||||
clk_disable_unprepare(esai->coreclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static const struct dev_pm_ops fsl_esai_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(fsl_esai_suspend, fsl_esai_resume)
|
||||
SET_RUNTIME_PM_OPS(fsl_esai_runtime_suspend,
|
||||
fsl_esai_runtime_resume,
|
||||
NULL)
|
||||
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
|
||||
pm_runtime_force_resume)
|
||||
};
|
||||
|
||||
static struct platform_driver fsl_esai_driver = {
|
||||
.probe = fsl_esai_probe,
|
||||
.remove = fsl_esai_remove,
|
||||
.driver = {
|
||||
.name = "fsl-esai-dai",
|
||||
.pm = &fsl_esai_pm_ops,
|
||||
|
|
|
@ -596,15 +596,8 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
|
||||
struct device *dev = &sai->pdev->dev;
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(sai->bus_clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable bus clock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE,
|
||||
FSL_SAI_CR3_TRCE);
|
||||
|
||||
|
@ -621,8 +614,6 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
|
|||
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
|
||||
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0);
|
||||
|
||||
clk_disable_unprepare(sai->bus_clk);
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
|
||||
|
@ -935,6 +926,14 @@ static int fsl_sai_runtime_suspend(struct device *dev)
|
|||
{
|
||||
struct fsl_sai *sai = dev_get_drvdata(dev);
|
||||
|
||||
if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
|
||||
clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
|
||||
|
||||
if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
|
||||
clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
|
||||
|
||||
clk_disable_unprepare(sai->bus_clk);
|
||||
|
||||
regcache_cache_only(sai->regmap, true);
|
||||
regcache_mark_dirty(sai->regmap);
|
||||
|
||||
|
@ -944,6 +943,25 @@ static int fsl_sai_runtime_suspend(struct device *dev)
|
|||
static int fsl_sai_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct fsl_sai *sai = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(sai->bus_clk);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable bus clock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) {
|
||||
ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]);
|
||||
if (ret)
|
||||
goto disable_bus_clk;
|
||||
}
|
||||
|
||||
if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) {
|
||||
ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]);
|
||||
if (ret)
|
||||
goto disable_tx_clk;
|
||||
}
|
||||
|
||||
regcache_cache_only(sai->regmap, false);
|
||||
regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
|
||||
|
@ -951,7 +969,23 @@ static int fsl_sai_runtime_resume(struct device *dev)
|
|||
usleep_range(1000, 2000);
|
||||
regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
|
||||
regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
|
||||
return regcache_sync(sai->regmap);
|
||||
|
||||
ret = regcache_sync(sai->regmap);
|
||||
if (ret)
|
||||
goto disable_rx_clk;
|
||||
|
||||
return 0;
|
||||
|
||||
disable_rx_clk:
|
||||
if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
|
||||
clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
|
||||
disable_tx_clk:
|
||||
if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
|
||||
clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
|
||||
disable_bus_clk:
|
||||
clk_disable_unprepare(sai->bus_clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
|
|
|
@ -1582,9 +1582,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
|
|||
}
|
||||
}
|
||||
|
||||
ret = fsl_ssi_debugfs_create(&ssi->dbg_stats, dev);
|
||||
if (ret)
|
||||
goto error_asoc_register;
|
||||
fsl_ssi_debugfs_create(&ssi->dbg_stats, dev);
|
||||
|
||||
/* Initially configures SSI registers */
|
||||
fsl_ssi_hw_init(ssi);
|
||||
|
|
|
@ -270,7 +270,6 @@ struct device;
|
|||
|
||||
struct fsl_ssi_dbg {
|
||||
struct dentry *dbg_dir;
|
||||
struct dentry *dbg_stats;
|
||||
|
||||
struct {
|
||||
unsigned int rfrc;
|
||||
|
@ -299,7 +298,7 @@ struct fsl_ssi_dbg {
|
|||
|
||||
void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *ssi_dbg, u32 sisr);
|
||||
|
||||
int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev);
|
||||
void fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev);
|
||||
|
||||
void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg);
|
||||
|
||||
|
@ -312,10 +311,9 @@ static inline void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *stats, u32 sisr)
|
|||
{
|
||||
}
|
||||
|
||||
static inline int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg,
|
||||
struct device *dev)
|
||||
static inline void fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg,
|
||||
struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg)
|
||||
|
|
|
@ -126,25 +126,15 @@ static int fsl_ssi_stats_show(struct seq_file *s, void *unused)
|
|||
|
||||
DEFINE_SHOW_ATTRIBUTE(fsl_ssi_stats);
|
||||
|
||||
int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev)
|
||||
void fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev)
|
||||
{
|
||||
ssi_dbg->dbg_dir = debugfs_create_dir(dev_name(dev), NULL);
|
||||
if (!ssi_dbg->dbg_dir)
|
||||
return -ENOMEM;
|
||||
|
||||
ssi_dbg->dbg_stats = debugfs_create_file("stats", 0444,
|
||||
ssi_dbg->dbg_dir, ssi_dbg,
|
||||
&fsl_ssi_stats_fops);
|
||||
if (!ssi_dbg->dbg_stats) {
|
||||
debugfs_remove(ssi_dbg->dbg_dir);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
debugfs_create_file("stats", 0444, ssi_dbg->dbg_dir, ssi_dbg,
|
||||
&fsl_ssi_stats_fops);
|
||||
}
|
||||
|
||||
void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg)
|
||||
{
|
||||
debugfs_remove(ssi_dbg->dbg_stats);
|
||||
debugfs_remove(ssi_dbg->dbg_dir);
|
||||
debugfs_remove_recursive(ssi_dbg->dbg_dir);
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np,
|
|||
of_node_put(dma_channel_np);
|
||||
return ret;
|
||||
}
|
||||
snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%pOFn",
|
||||
snprintf((char *)dai->platforms->name, DAI_NAME_SIZE, "%llx.%pOFn",
|
||||
(unsigned long long) res.start, dma_channel_np);
|
||||
|
||||
iprop = of_get_property(dma_channel_np, "cell-index", NULL);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue