Merge remote-tracking branch 'asoc/for-5.14' into asoc-next
This commit is contained in:
commit
1926645281
@ -23,6 +23,7 @@ Optional properties:
|
||||
default output clock name
|
||||
- rockchip,system-power-controller: Telling whether or not this pmic is controlling
|
||||
the system power.
|
||||
- wakeup-source: Device can be used as a wakeup source.
|
||||
|
||||
Optional RK805 properties:
|
||||
- vcc1-supply: The input supply for DCDC_REG1
|
||||
@ -63,8 +64,18 @@ Optional RK809 properties:
|
||||
- vcc9-supply: The input supply for DCDC_REG5, SWITCH_REG2
|
||||
|
||||
Optional RK817 properties:
|
||||
- clocks: The input clock for the audio codec
|
||||
- clock-names: The clock name for the codec clock. Should be "mclk".
|
||||
- #sound-dai-cells: Needed for the interpretation of sound dais. Should be 0.
|
||||
|
||||
- vcc8-supply: The input supply for BOOST
|
||||
- vcc9-supply: The input supply for OTG_SWITCH
|
||||
- codec: The child node for the codec to hold additional properties.
|
||||
If no additional properties are required for the codec, this
|
||||
node can be omitted.
|
||||
|
||||
- rockchip,mic-in-differential: Telling if the microphone uses differential
|
||||
mode. Should be under the codec child node.
|
||||
|
||||
Optional RK818 properties:
|
||||
- vcc1-supply: The input supply for DCDC_REG1
|
||||
@ -275,3 +286,180 @@ Example:
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
rk817: pmic@20 {
|
||||
compatible = "rockchip,rk817";
|
||||
reg = <0x20>;
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <RK_PB2 IRQ_TYPE_LEVEL_LOW>;
|
||||
clock-output-names = "rk808-clkout1", "xin32k";
|
||||
clock-names = "mclk";
|
||||
clocks = <&cru SCLK_I2S1_OUT>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>;
|
||||
wakeup-source;
|
||||
#clock-cells = <1>;
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
vcc1-supply = <&vccsys>;
|
||||
vcc2-supply = <&vccsys>;
|
||||
vcc3-supply = <&vccsys>;
|
||||
vcc4-supply = <&vccsys>;
|
||||
vcc5-supply = <&vccsys>;
|
||||
vcc6-supply = <&vccsys>;
|
||||
vcc7-supply = <&vccsys>;
|
||||
|
||||
regulators {
|
||||
vdd_logic: DCDC_REG1 {
|
||||
regulator-name = "vdd_logic";
|
||||
regulator-min-microvolt = <950000>;
|
||||
regulator-max-microvolt = <1150000>;
|
||||
regulator-ramp-delay = <6001>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <950000>;
|
||||
};
|
||||
};
|
||||
|
||||
vdd_arm: DCDC_REG2 {
|
||||
regulator-name = "vdd_arm";
|
||||
regulator-min-microvolt = <950000>;
|
||||
regulator-max-microvolt = <1350000>;
|
||||
regulator-ramp-delay = <6001>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <950000>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc_ddr: DCDC_REG3 {
|
||||
regulator-name = "vcc_ddr";
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
};
|
||||
};
|
||||
|
||||
vcc_3v3: DCDC_REG4 {
|
||||
regulator-name = "vcc_3v3";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc_1v8: LDO_REG2 {
|
||||
regulator-name = "vcc_1v8";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <1800000>;
|
||||
};
|
||||
};
|
||||
|
||||
vdd_1v0: LDO_REG3 {
|
||||
regulator-name = "vdd_1v0";
|
||||
regulator-min-microvolt = <1000000>;
|
||||
regulator-max-microvolt = <1000000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <1000000>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc3v3_pmu: LDO_REG4 {
|
||||
regulator-name = "vcc3v3_pmu";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
|
||||
vccio_sd: LDO_REG5 {
|
||||
regulator-name = "vccio_sd";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc_sd: LDO_REG6 {
|
||||
regulator-name = "vcc_sd";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-boot-on;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc_bl: LDO_REG7 {
|
||||
regulator-name = "vcc_bl";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc_lcd: LDO_REG8 {
|
||||
regulator-name = "vcc_lcd";
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <2800000>;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <2800000>;
|
||||
};
|
||||
};
|
||||
|
||||
vcc_cam: LDO_REG9 {
|
||||
regulator-name = "vcc_cam";
|
||||
regulator-min-microvolt = <3000000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
|
||||
regulator-state-mem {
|
||||
regulator-off-in-suspend;
|
||||
regulator-suspend-microvolt = <3000000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
rk817_codec: codec {
|
||||
rockchip,mic-in-differential;
|
||||
};
|
||||
};
|
||||
|
@ -12,7 +12,11 @@ maintainers:
|
||||
|
||||
properties:
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
description:
|
||||
A value of 0 is deprecated. When used, it only allows access to
|
||||
the ADC/DAC and AIF1 (the CPU DAI), not the other two AIFs/DAIs.
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
@ -50,7 +54,7 @@ additionalProperties: false
|
||||
examples:
|
||||
- |
|
||||
audio-codec@1c22e00 {
|
||||
#sound-dai-cells = <0>;
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "allwinner,sun8i-a33-codec";
|
||||
reg = <0x01c22e00 0x400>;
|
||||
interrupts = <0 29 4>;
|
||||
|
@ -81,6 +81,13 @@ Optional properties:
|
||||
< x1 x2 x3 x4 >
|
||||
Default = < 15 8 4 1>
|
||||
|
||||
- cirrus,hs-bias-sense-disable: This is boolean property. If present the
|
||||
HSBIAS sense is disabled. Configures HSBIAS output current sense through
|
||||
the external 2.21-k resistor. HSBIAS_SENSE is hardware feature to reduce
|
||||
the potential pop noise during the headset plug out slowly. But on some
|
||||
platforms ESD voltage will affect it causing test to fail, especially
|
||||
with CTIA headset type. For different hardware setups, a designer might
|
||||
want to tweak default behavior.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -25,6 +25,7 @@ properties:
|
||||
- fsl,imx8mq-spdif
|
||||
- fsl,imx8mm-spdif
|
||||
- fsl,imx8mn-spdif
|
||||
- fsl,imx8ulp-spdif
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -9,8 +9,10 @@ Required properties:
|
||||
|
||||
- compatible : Compatible list, contains "fsl,vf610-sai",
|
||||
"fsl,imx6sx-sai", "fsl,imx6ul-sai",
|
||||
"fsl,imx7ulp-sai", "fsl,imx8mq-sai" or
|
||||
"fsl,imx8qm-sai".
|
||||
"fsl,imx7ulp-sai", "fsl,imx8mq-sai",
|
||||
"fsl,imx8qm-sai", "fsl,imx8mm-sai",
|
||||
"fsl,imx8mn-sai", "fsl,imx8mp-sai", or
|
||||
"fsl,imx8ulp-sai".
|
||||
|
||||
- reg : Offset and length of the register set for the device.
|
||||
|
||||
|
122
Documentation/devicetree/bindings/sound/imx-audio-card.yaml
Normal file
122
Documentation/devicetree/bindings/sound/imx-audio-card.yaml
Normal file
@ -0,0 +1,122 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/imx-audio-card.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP i.MX audio sound card.
|
||||
|
||||
maintainers:
|
||||
- Shengjiu Wang <shengjiu.wang@nxp.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx-audio-card
|
||||
|
||||
model:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: User specified audio sound card name
|
||||
|
||||
audio-routing:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
description:
|
||||
A list of the connections between audio components. Each entry is a
|
||||
pair of strings, the first being the connection's sink, the second
|
||||
being the connection's source. Valid names could be power supplies,
|
||||
MicBias of codec and the jacks on the board.
|
||||
|
||||
patternProperties:
|
||||
".*-dai-link$":
|
||||
description:
|
||||
Each subnode represents a dai link. Subnodes of each dai links would be
|
||||
cpu/codec dais.
|
||||
|
||||
type: object
|
||||
|
||||
properties:
|
||||
link-name:
|
||||
description: Indicates dai-link name and PCM stream name.
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
maxItems: 1
|
||||
|
||||
format:
|
||||
description: audio format.
|
||||
items:
|
||||
enum:
|
||||
- i2s
|
||||
- dsp_b
|
||||
|
||||
dai-tdm-slot-num:
|
||||
description: see tdm-slot.txt.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
dai-tdm-slot-width:
|
||||
description: see tdm-slot.txt.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
cpu:
|
||||
description: Holds subnode which indicates cpu dai.
|
||||
type: object
|
||||
properties:
|
||||
sound-dai: true
|
||||
|
||||
codec:
|
||||
description: Holds subnode which indicates codec dai.
|
||||
type: object
|
||||
properties:
|
||||
sound-dai: true
|
||||
|
||||
fsl,mclk-equal-bclk:
|
||||
description: Indicates mclk can be equal to bclk, especially for sai interface
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
|
||||
required:
|
||||
- link-name
|
||||
- cpu
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- model
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sound-ak4458 {
|
||||
compatible = "fsl,imx-audio-card";
|
||||
model = "ak4458-audio";
|
||||
pri-dai-link {
|
||||
link-name = "akcodec";
|
||||
format = "i2s";
|
||||
fsl,mclk-equal-bclk;
|
||||
cpu {
|
||||
sound-dai = <&sai1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&ak4458_1>, <&ak4458_2>;
|
||||
};
|
||||
};
|
||||
fe-dai-link {
|
||||
link-name = "HiFi-ASRC-FE";
|
||||
format = "i2s";
|
||||
cpu {
|
||||
sound-dai = <&easrc>;
|
||||
};
|
||||
};
|
||||
be-dai-link {
|
||||
link-name = "HiFi-ASRC-BE";
|
||||
format = "dsp_b";
|
||||
dai-tdm-slot-num = <8>;
|
||||
dai-tdm-slot-width = <32>;
|
||||
fsl,mclk-equal-bclk;
|
||||
cpu {
|
||||
sound-dai = <&sai1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&ak4458_1>, <&ak4458_2>;
|
||||
};
|
||||
};
|
||||
};
|
@ -1,28 +0,0 @@
|
||||
Freescale Digital Audio Mux (AUDMUX) device
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "fsl,imx21-audmux" for AUDMUX version firstly used
|
||||
on i.MX21, or "fsl,imx31-audmux" for the version
|
||||
firstly used on i.MX31.
|
||||
|
||||
- reg : Should contain AUDMUX registers location and length.
|
||||
|
||||
An initial configuration can be setup using child nodes.
|
||||
|
||||
Required properties of optional child nodes:
|
||||
|
||||
- fsl,audmux-port : Integer of the audmux port that is configured by this
|
||||
child node.
|
||||
|
||||
- fsl,port-config : List of configuration options for the specific port.
|
||||
For imx31-audmux and above, it is a list of tuples
|
||||
<ptcr pdcr>. For imx21-audmux it is a list of pcr
|
||||
values.
|
||||
|
||||
Example:
|
||||
|
||||
audmux@21d8000 {
|
||||
compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
|
||||
reg = <0x021d8000 0x4000>;
|
||||
};
|
119
Documentation/devicetree/bindings/sound/imx-audmux.yaml
Normal file
119
Documentation/devicetree/bindings/sound/imx-audmux.yaml
Normal file
@ -0,0 +1,119 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/imx-audmux.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale Digital Audio Mux device
|
||||
|
||||
maintainers:
|
||||
- Oleksij Rempel <o.rempel@pengutronix.de>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,imx27-audmux
|
||||
- const: fsl,imx21-audmux
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,imx25-audmux
|
||||
- fsl,imx35-audmux
|
||||
- fsl,imx50-audmux
|
||||
- fsl,imx51-audmux
|
||||
- fsl,imx53-audmux
|
||||
- fsl,imx6q-audmux
|
||||
- fsl,imx6sl-audmux
|
||||
- fsl,imx6sll-audmux
|
||||
- fsl,imx6sx-audmux
|
||||
- const: fsl,imx31-audmux
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: audmux
|
||||
|
||||
patternProperties:
|
||||
"^mux-[0-9a-z]*$":
|
||||
type: object
|
||||
properties:
|
||||
fsl,audmux-port:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
Integer of the audmux port that is configured by this child node
|
||||
|
||||
fsl,port-config:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description: |
|
||||
List of configuration options for the specific port.
|
||||
For imx31-audmux and above, it is a list of tuples ptcr pdcr.
|
||||
For imx21-audmux it is a list of pcr values.
|
||||
|
||||
required:
|
||||
- fsl,audmux-port
|
||||
- fsl,port-config
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
audmux@21d8000 {
|
||||
compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
|
||||
reg = <0x021d8000 0x4000>;
|
||||
};
|
||||
- |
|
||||
audmux@10016000 {
|
||||
compatible = "fsl,imx27-audmux", "fsl,imx21-audmux";
|
||||
reg = <0x10016000 0x1000>;
|
||||
clocks = <&clks 1>;
|
||||
clock-names = "audmux";
|
||||
|
||||
mux-ssi0 {
|
||||
fsl,audmux-port = <0>;
|
||||
fsl,port-config = <0xcb205000>;
|
||||
};
|
||||
|
||||
mux-pins4 {
|
||||
fsl,audmux-port = <2>;
|
||||
fsl,port-config = <0x00001000>;
|
||||
};
|
||||
};
|
||||
- |
|
||||
#include <dt-bindings/sound/fsl-imx-audmux.h>
|
||||
audmux@21d8000 {
|
||||
compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
|
||||
reg = <0x021d8000 0x4000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_audmux>;
|
||||
|
||||
mux-ssi1 {
|
||||
fsl,audmux-port = <0>;
|
||||
fsl,port-config = <
|
||||
IMX_AUDMUX_V2_PTCR_SYN 0
|
||||
IMX_AUDMUX_V2_PTCR_TFSEL(2) 0
|
||||
IMX_AUDMUX_V2_PTCR_TCSEL(2) 0
|
||||
IMX_AUDMUX_V2_PTCR_TFSDIR 0
|
||||
IMX_AUDMUX_V2_PTCR_TCLKDIR IMX_AUDMUX_V2_PDCR_RXDSEL(2)
|
||||
>;
|
||||
};
|
||||
|
||||
mux-pins3 {
|
||||
fsl,audmux-port = <2>;
|
||||
fsl,port-config = <
|
||||
IMX_AUDMUX_V2_PTCR_SYN IMX_AUDMUX_V2_PDCR_RXDSEL(0)
|
||||
0 IMX_AUDMUX_V2_PDCR_TXRXEN
|
||||
>;
|
||||
};
|
||||
};
|
58
Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml
Normal file
58
Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml
Normal file
@ -0,0 +1,58 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nxp,tfa989x.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP/Goodix TFA989X (TFA1) Audio Amplifiers
|
||||
|
||||
maintainers:
|
||||
- Stephan Gerhold <stephan@gerhold.net>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nxp,tfa9895
|
||||
- nxp,tfa9897
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
sound-name-prefix:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
Used as prefix for sink/source names of the component. Must be a
|
||||
unique string among multiple instances of the same component.
|
||||
|
||||
vddd-supply:
|
||||
description: regulator phandle for the VDDD power supply.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#sound-dai-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
audio-codec@34 {
|
||||
compatible = "nxp,tfa9895";
|
||||
reg = <0x34>;
|
||||
sound-name-prefix = "Speaker Left";
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
audio-codec@36 {
|
||||
compatible = "nxp,tfa9895";
|
||||
reg = <0x36>;
|
||||
sound-name-prefix = "Speaker Right";
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
};
|
@ -77,6 +77,31 @@ properties:
|
||||
minimum: 1800000
|
||||
maximum: 2850000
|
||||
|
||||
qcom,hphl-jack-type-normally-closed:
|
||||
description: Indicates that HPHL jack switch type is normally closed
|
||||
type: boolean
|
||||
|
||||
qcom,ground-jack-type-normally-closed:
|
||||
description: Indicates that Headset Ground switch type is normally closed
|
||||
type: boolean
|
||||
|
||||
qcom,mbhc-headset-vthreshold-microvolt:
|
||||
description: Voltage threshold value for headset detection
|
||||
minimum: 0
|
||||
maximum: 2850000
|
||||
|
||||
qcom,mbhc-headphone-vthreshold-microvolt:
|
||||
description: Voltage threshold value for headphone detection
|
||||
minimum: 0
|
||||
maximum: 2850000
|
||||
|
||||
qcom,mbhc-buttons-vthreshold-microvolt:
|
||||
description:
|
||||
Array of 8 Voltage threshold values corresponding to headset
|
||||
button0 - button7
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
|
||||
clock-output-names:
|
||||
const: mclk
|
||||
|
||||
@ -159,6 +184,11 @@ examples:
|
||||
qcom,micbias2-microvolt = <1800000>;
|
||||
qcom,micbias3-microvolt = <1800000>;
|
||||
qcom,micbias4-microvolt = <1800000>;
|
||||
qcom,hphl-jack-type-normally-closed;
|
||||
qcom,ground-jack-type-normally-closed;
|
||||
qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 500000 500000 500000 500000>;
|
||||
qcom,mbhc-headset-vthreshold-microvolt = <1700000>;
|
||||
qcom,mbhc-headphone-vthreshold-microvolt = <50000>;
|
||||
clock-names = "extclk";
|
||||
clocks = <&rpmhcc 2>;
|
||||
|
||||
|
@ -0,0 +1,70 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/qcom,wcd938x-sdw.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Bindings for Qualcomm SoundWire Slave devices on WCD9380/WCD9385
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
description: |
|
||||
Qualcomm WCD9380/WCD9385 Codec is a standalone Hi-Fi audio codec IC.
|
||||
It has RX and TX Soundwire slave devices. This bindings is for the
|
||||
slave devices.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sdw20217010d00
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
qcom,tx-port-mapping:
|
||||
description: |
|
||||
Specifies static port mapping between slave and master tx ports.
|
||||
In the order of slave port index.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
|
||||
qcom,rx-port-mapping:
|
||||
description: |
|
||||
Specifies static port mapping between slave and master rx ports.
|
||||
In the order of slave port index.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 5
|
||||
maxItems: 5
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
soundwire@3210000 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x03210000 0x2000>;
|
||||
wcd938x_rx: codec@0,4 {
|
||||
compatible = "sdw20217010d00";
|
||||
reg = <0 4>;
|
||||
qcom,rx-port-mapping = <1 2 3 4 5>;
|
||||
};
|
||||
};
|
||||
|
||||
soundwire@3230000 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x03230000 0x2000>;
|
||||
wcd938x_tx: codec@0,3 {
|
||||
compatible = "sdw20217010d00";
|
||||
reg = <0 3>;
|
||||
qcom,tx-port-mapping = <2 3 4 5>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
146
Documentation/devicetree/bindings/sound/qcom,wcd938x.yaml
Normal file
146
Documentation/devicetree/bindings/sound/qcom,wcd938x.yaml
Normal file
@ -0,0 +1,146 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/qcom,wcd938x.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Bindings for Qualcomm WCD9380/WCD9385 Audio Codec
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
description: |
|
||||
Qualcomm WCD9380/WCD9385 Codec is a standalone Hi-Fi audio codec IC.
|
||||
It has RX and TX Soundwire slave devices.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,wcd9380-codec
|
||||
- qcom,wcd9385-codec
|
||||
|
||||
reset-gpios:
|
||||
description: GPIO spec for reset line to use
|
||||
maxItems: 1
|
||||
|
||||
vdd-buck-supply:
|
||||
description: A reference to the 1.8V buck supply
|
||||
|
||||
vdd-rxtx-supply:
|
||||
description: A reference to the 1.8V rx supply
|
||||
|
||||
vdd-io-supply:
|
||||
description: A reference to the 1.8V I/O supply
|
||||
|
||||
qcom,tx-device:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: A reference to Soundwire tx device phandle
|
||||
|
||||
qcom,rx-device:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: A reference to Soundwire rx device phandle
|
||||
|
||||
qcom,micbias1-microvolt:
|
||||
description: micbias1 voltage
|
||||
minimum: 1800000
|
||||
maximum: 2850000
|
||||
|
||||
qcom,micbias2-microvolt:
|
||||
description: micbias2 voltage
|
||||
minimum: 1800000
|
||||
maximum: 2850000
|
||||
|
||||
qcom,micbias3-microvolt:
|
||||
description: micbias3 voltage
|
||||
minimum: 1800000
|
||||
maximum: 2850000
|
||||
|
||||
qcom,micbias4-microvolt:
|
||||
description: micbias4 voltage
|
||||
minimum: 1800000
|
||||
maximum: 2850000
|
||||
|
||||
qcom,hphl-jack-type-normally-closed:
|
||||
description: Indicates that HPHL jack switch type is normally closed
|
||||
type: boolean
|
||||
|
||||
qcom,ground-jack-type-normally-closed:
|
||||
description: Indicates that Headset Ground switch type is normally closed
|
||||
type: boolean
|
||||
|
||||
qcom,mbhc-headset-vthreshold-microvolt:
|
||||
description: Voltage threshold value for headset detection
|
||||
minimum: 0
|
||||
maximum: 2850000
|
||||
|
||||
qcom,mbhc-headphone-vthreshold-microvolt:
|
||||
description: Voltage threshold value for headphone detection
|
||||
minimum: 0
|
||||
maximum: 2850000
|
||||
|
||||
qcom,mbhc-buttons-vthreshold-microvolt:
|
||||
description:
|
||||
Array of 8 Voltage threshold values corresponding to headset
|
||||
button0 - button7
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reset-gpios
|
||||
- qcom,tx-device
|
||||
- qcom,rx-device
|
||||
- qcom,micbias1-microvolt
|
||||
- qcom,micbias2-microvolt
|
||||
- qcom,micbias3-microvolt
|
||||
- qcom,micbias4-microvolt
|
||||
- "#sound-dai-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
codec {
|
||||
compatible = "qcom,wcd9380-codec";
|
||||
reset-gpios = <&tlmm 32 0>;
|
||||
#sound-dai-cells = <1>;
|
||||
qcom,tx-device = <&wcd938x_tx>;
|
||||
qcom,rx-device = <&wcd938x_rx>;
|
||||
qcom,micbias1-microvolt = <1800000>;
|
||||
qcom,micbias2-microvolt = <1800000>;
|
||||
qcom,micbias3-microvolt = <1800000>;
|
||||
qcom,micbias4-microvolt = <1800000>;
|
||||
qcom,hphl-jack-type-normally-closed;
|
||||
qcom,ground-jack-type-normally-closed;
|
||||
qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 500000 500000 500000 500000>;
|
||||
qcom,mbhc-headphone-vthreshold-microvolt = <50000>;
|
||||
};
|
||||
|
||||
/* ... */
|
||||
|
||||
soundwire@3210000 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x03210000 0x2000>;
|
||||
wcd938x_rx: codec@0,4 {
|
||||
compatible = "sdw20217010d00";
|
||||
reg = <0 4>;
|
||||
qcom,rx-port-mapping = <1 2 3 4 5>;
|
||||
};
|
||||
};
|
||||
|
||||
soundwire@3230000 {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x03230000 0x2000>;
|
||||
wcd938x_tx: codec@0,3 {
|
||||
compatible = "sdw20217010d00";
|
||||
reg = <0 3>;
|
||||
qcom,tx-port-mapping = <2 3 4 5>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -86,9 +86,11 @@ properties:
|
||||
power-domains: true
|
||||
|
||||
resets:
|
||||
minItems: 1
|
||||
maxItems: 11
|
||||
|
||||
reset-names:
|
||||
minItems: 1
|
||||
maxItems: 11
|
||||
|
||||
clocks:
|
||||
@ -110,6 +112,13 @@ properties:
|
||||
- pattern: '^dvc\.[0-1]$'
|
||||
- pattern: '^clk_(a|b|c|i)$'
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
properties:
|
||||
port(@[0-9a-f]+)?:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
@ -257,7 +266,6 @@ required:
|
||||
- "#sound-dai-cells"
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
@ -6,6 +6,7 @@ Required properties:
|
||||
- compatible - "string" - One of:
|
||||
"ti,tlv320aic32x4" TLV320AIC3204
|
||||
"ti,tlv320aic32x6" TLV320AIC3206, TLV320AIC3256
|
||||
"ti,tas2505" TAS2505, TAS2521
|
||||
- reg: I2C slave address
|
||||
- supply-*: Required supply regulators are:
|
||||
"iov" - digital IO power supply
|
||||
|
@ -1,18 +0,0 @@
|
||||
WM8750 and WM8987 audio CODECs
|
||||
|
||||
These devices support both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8750" or "wlf,wm8987"
|
||||
|
||||
- reg : the I2C address of the device for I2C, the chip select
|
||||
number for SPI.
|
||||
|
||||
Example:
|
||||
|
||||
wm8750: codec@1a {
|
||||
compatible = "wlf,wm8750";
|
||||
reg = <0x1a>;
|
||||
};
|
42
Documentation/devicetree/bindings/sound/wm8750.yaml
Normal file
42
Documentation/devicetree/bindings/sound/wm8750.yaml
Normal file
@ -0,0 +1,42 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/wm8750.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: WM8750 and WM8987 audio CODECs
|
||||
|
||||
description: |
|
||||
These devices support both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
maintainers:
|
||||
- Mark Brown <broonie@kernel.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- wlf,wm8750
|
||||
- wlf,wm8987
|
||||
|
||||
reg:
|
||||
description:
|
||||
The I2C address of the device for I2C, the chip select number for SPI
|
||||
maxItems: 1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
codec@1a {
|
||||
compatible = "wlf,wm8750";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
};
|
@ -3508,14 +3508,15 @@ field must be set, though).
|
||||
|
||||
“IEC958 Playback Con Mask” is used to return the bit-mask for the IEC958
|
||||
status bits of consumer mode. Similarly, “IEC958 Playback Pro Mask”
|
||||
returns the bitmask for professional mode. They are read-only controls,
|
||||
and are defined as MIXER controls (iface =
|
||||
``SNDRV_CTL_ELEM_IFACE_MIXER``).
|
||||
returns the bitmask for professional mode. They are read-only controls.
|
||||
|
||||
Meanwhile, “IEC958 Playback Default” control is defined for getting and
|
||||
setting the current default IEC958 bits. Note that this one is usually
|
||||
defined as a PCM control (iface = ``SNDRV_CTL_ELEM_IFACE_PCM``),
|
||||
although in some places it's defined as a MIXER control.
|
||||
setting the current default IEC958 bits.
|
||||
|
||||
Due to historical reasons, both variants of the Playback Mask and the
|
||||
Playback Default controls can be implemented on either a
|
||||
``SNDRV_CTL_ELEM_IFACE_PCM`` or a ``SNDRV_CTL_ELEM_IFACE_MIXER`` iface.
|
||||
Drivers should expose the mask and default on the same iface though.
|
||||
|
||||
In addition, you can define the control switches to enable/disable or to
|
||||
set the raw bit mode. The implementation will depend on the chip, but
|
||||
|
@ -13213,6 +13213,13 @@ S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/tfa9879.txt
|
||||
F: sound/soc/codecs/tfa9879*
|
||||
|
||||
NXP/Goodix TFA989X (TFA1) DRIVER
|
||||
M: Stephan Gerhold <stephan@gerhold.net>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/nxp,tfa989x.yaml
|
||||
F: sound/soc/codecs/tfa989x.c
|
||||
|
||||
NXP-NCI NFC DRIVER
|
||||
R: Charles Gorand <charles.gorand@effinnov.com>
|
||||
L: linux-nfc@lists.01.org (subscribers-only)
|
||||
|
@ -65,6 +65,7 @@ static bool rk817_is_volatile_reg(struct device *dev, unsigned int reg)
|
||||
switch (reg) {
|
||||
case RK817_SECONDS_REG ... RK817_WEEKS_REG:
|
||||
case RK817_RTC_STATUS_REG:
|
||||
case RK817_CODEC_DTOP_LPT_SRST:
|
||||
case RK817_INT_STS_REG0:
|
||||
case RK817_INT_STS_REG1:
|
||||
case RK817_INT_STS_REG2:
|
||||
@ -163,6 +164,7 @@ static const struct mfd_cell rk817s[] = {
|
||||
.num_resources = ARRAY_SIZE(rk817_rtc_resources),
|
||||
.resources = &rk817_rtc_resources[0],
|
||||
},
|
||||
{ .name = "rk817-codec",},
|
||||
};
|
||||
|
||||
static const struct mfd_cell rk818s[] = {
|
||||
@ -201,6 +203,85 @@ static const struct rk808_reg_data rk808_pre_init_reg[] = {
|
||||
|
||||
static const struct rk808_reg_data rk817_pre_init_reg[] = {
|
||||
{RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
|
||||
/* Codec specific registers */
|
||||
{ RK817_CODEC_DTOP_VUCTL, MASK_ALL, 0x03 },
|
||||
{ RK817_CODEC_DTOP_VUCTIME, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DTOP_LPT_SRST, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DTOP_DIGEN_CLKE, MASK_ALL, 0x00 },
|
||||
/* from vendor driver, CODEC_AREF_RTCFG0 not defined in data sheet */
|
||||
{ RK817_CODEC_AREF_RTCFG0, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_AREF_RTCFG1, MASK_ALL, 0x06 },
|
||||
{ RK817_CODEC_AADC_CFG0, MASK_ALL, 0xc8 },
|
||||
/* from vendor driver, CODEC_AADC_CFG1 not defined in data sheet */
|
||||
{ RK817_CODEC_AADC_CFG1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DADC_VOLL, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DADC_VOLR, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DADC_SR_ACL0, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DADC_ALC1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DADC_ALC2, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DADC_NG, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DADC_HPF, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DADC_RVOLL, MASK_ALL, 0xff },
|
||||
{ RK817_CODEC_DADC_RVOLR, MASK_ALL, 0xff },
|
||||
{ RK817_CODEC_AMIC_CFG0, MASK_ALL, 0x70 },
|
||||
{ RK817_CODEC_AMIC_CFG1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DMIC_PGA_GAIN, MASK_ALL, 0x66 },
|
||||
{ RK817_CODEC_DMIC_LMT1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DMIC_LMT2, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DMIC_NG1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DMIC_NG2, MASK_ALL, 0x00 },
|
||||
/* from vendor driver, CODEC_ADAC_CFG0 not defined in data sheet */
|
||||
{ RK817_CODEC_ADAC_CFG0, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_ADAC_CFG1, MASK_ALL, 0x07 },
|
||||
{ RK817_CODEC_DDAC_POPD_DACST, MASK_ALL, 0x82 },
|
||||
{ RK817_CODEC_DDAC_VOLL, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DDAC_VOLR, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DDAC_SR_LMT0, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DDAC_LMT1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DDAC_LMT2, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DDAC_MUTE_MIXCTL, MASK_ALL, 0xa0 },
|
||||
{ RK817_CODEC_DDAC_RVOLL, MASK_ALL, 0xff },
|
||||
{ RK817_CODEC_DADC_RVOLR, MASK_ALL, 0xff },
|
||||
{ RK817_CODEC_AMIC_CFG0, MASK_ALL, 0x70 },
|
||||
{ RK817_CODEC_AMIC_CFG1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DMIC_PGA_GAIN, MASK_ALL, 0x66 },
|
||||
{ RK817_CODEC_DMIC_LMT1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DMIC_LMT2, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DMIC_NG1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DMIC_NG2, MASK_ALL, 0x00 },
|
||||
/* from vendor driver, CODEC_ADAC_CFG0 not defined in data sheet */
|
||||
{ RK817_CODEC_ADAC_CFG0, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_ADAC_CFG1, MASK_ALL, 0x07 },
|
||||
{ RK817_CODEC_DDAC_POPD_DACST, MASK_ALL, 0x82 },
|
||||
{ RK817_CODEC_DDAC_VOLL, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DDAC_VOLR, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DDAC_SR_LMT0, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DDAC_LMT1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DDAC_LMT2, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DDAC_MUTE_MIXCTL, MASK_ALL, 0xa0 },
|
||||
{ RK817_CODEC_DDAC_RVOLL, MASK_ALL, 0xff },
|
||||
{ RK817_CODEC_DDAC_RVOLR, MASK_ALL, 0xff },
|
||||
{ RK817_CODEC_AHP_ANTI0, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_AHP_ANTI1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_AHP_CFG0, MASK_ALL, 0xe0 },
|
||||
{ RK817_CODEC_AHP_CFG1, MASK_ALL, 0x1f },
|
||||
{ RK817_CODEC_AHP_CP, MASK_ALL, 0x09 },
|
||||
{ RK817_CODEC_ACLASSD_CFG1, MASK_ALL, 0x69 },
|
||||
{ RK817_CODEC_ACLASSD_CFG2, MASK_ALL, 0x44 },
|
||||
{ RK817_CODEC_APLL_CFG0, MASK_ALL, 0x04 },
|
||||
{ RK817_CODEC_APLL_CFG1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_APLL_CFG2, MASK_ALL, 0x30 },
|
||||
{ RK817_CODEC_APLL_CFG3, MASK_ALL, 0x19 },
|
||||
{ RK817_CODEC_APLL_CFG4, MASK_ALL, 0x65 },
|
||||
{ RK817_CODEC_APLL_CFG5, MASK_ALL, 0x01 },
|
||||
{ RK817_CODEC_DI2S_CKM, MASK_ALL, 0x01 },
|
||||
{ RK817_CODEC_DI2S_RSD, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DI2S_RXCR1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DI2S_RXCR2, MASK_ALL, 0x17 },
|
||||
{ RK817_CODEC_DI2S_RXCMD_TSD, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DI2S_TXCR1, MASK_ALL, 0x00 },
|
||||
{ RK817_CODEC_DI2S_TXCR2, MASK_ALL, 0x17 },
|
||||
{ RK817_CODEC_DI2S_TXCR3_TXCMD, MASK_ALL, 0x00 },
|
||||
{RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_L},
|
||||
{RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK,
|
||||
RK817_HOTDIE_105 | RK817_TSD_140},
|
||||
|
@ -129,6 +129,8 @@
|
||||
#define TX_CODEC_DMA_TX_5 124
|
||||
#define RX_CODEC_DMA_RX_6 125
|
||||
#define RX_CODEC_DMA_RX_7 126
|
||||
#define QUINARY_MI2S_RX 127
|
||||
#define QUINARY_MI2S_TX 128
|
||||
|
||||
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
|
||||
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2
|
||||
|
@ -437,6 +437,87 @@ enum rk809_reg_id {
|
||||
#define RK817_RTC_COMP_LSB_REG 0x10
|
||||
#define RK817_RTC_COMP_MSB_REG 0x11
|
||||
|
||||
/* RK817 Codec Registers */
|
||||
#define RK817_CODEC_DTOP_VUCTL 0x12
|
||||
#define RK817_CODEC_DTOP_VUCTIME 0x13
|
||||
#define RK817_CODEC_DTOP_LPT_SRST 0x14
|
||||
#define RK817_CODEC_DTOP_DIGEN_CLKE 0x15
|
||||
#define RK817_CODEC_AREF_RTCFG0 0x16
|
||||
#define RK817_CODEC_AREF_RTCFG1 0x17
|
||||
#define RK817_CODEC_AADC_CFG0 0x18
|
||||
#define RK817_CODEC_AADC_CFG1 0x19
|
||||
#define RK817_CODEC_DADC_VOLL 0x1a
|
||||
#define RK817_CODEC_DADC_VOLR 0x1b
|
||||
#define RK817_CODEC_DADC_SR_ACL0 0x1e
|
||||
#define RK817_CODEC_DADC_ALC1 0x1f
|
||||
#define RK817_CODEC_DADC_ALC2 0x20
|
||||
#define RK817_CODEC_DADC_NG 0x21
|
||||
#define RK817_CODEC_DADC_HPF 0x22
|
||||
#define RK817_CODEC_DADC_RVOLL 0x23
|
||||
#define RK817_CODEC_DADC_RVOLR 0x24
|
||||
#define RK817_CODEC_AMIC_CFG0 0x27
|
||||
#define RK817_CODEC_AMIC_CFG1 0x28
|
||||
#define RK817_CODEC_DMIC_PGA_GAIN 0x29
|
||||
#define RK817_CODEC_DMIC_LMT1 0x2a
|
||||
#define RK817_CODEC_DMIC_LMT2 0x2b
|
||||
#define RK817_CODEC_DMIC_NG1 0x2c
|
||||
#define RK817_CODEC_DMIC_NG2 0x2d
|
||||
#define RK817_CODEC_ADAC_CFG0 0x2e
|
||||
#define RK817_CODEC_ADAC_CFG1 0x2f
|
||||
#define RK817_CODEC_DDAC_POPD_DACST 0x30
|
||||
#define RK817_CODEC_DDAC_VOLL 0x31
|
||||
#define RK817_CODEC_DDAC_VOLR 0x32
|
||||
#define RK817_CODEC_DDAC_SR_LMT0 0x35
|
||||
#define RK817_CODEC_DDAC_LMT1 0x36
|
||||
#define RK817_CODEC_DDAC_LMT2 0x37
|
||||
#define RK817_CODEC_DDAC_MUTE_MIXCTL 0x38
|
||||
#define RK817_CODEC_DDAC_RVOLL 0x39
|
||||
#define RK817_CODEC_DDAC_RVOLR 0x3a
|
||||
#define RK817_CODEC_AHP_ANTI0 0x3b
|
||||
#define RK817_CODEC_AHP_ANTI1 0x3c
|
||||
#define RK817_CODEC_AHP_CFG0 0x3d
|
||||
#define RK817_CODEC_AHP_CFG1 0x3e
|
||||
#define RK817_CODEC_AHP_CP 0x3f
|
||||
#define RK817_CODEC_ACLASSD_CFG1 0x40
|
||||
#define RK817_CODEC_ACLASSD_CFG2 0x41
|
||||
#define RK817_CODEC_APLL_CFG0 0x42
|
||||
#define RK817_CODEC_APLL_CFG1 0x43
|
||||
#define RK817_CODEC_APLL_CFG2 0x44
|
||||
#define RK817_CODEC_APLL_CFG3 0x45
|
||||
#define RK817_CODEC_APLL_CFG4 0x46
|
||||
#define RK817_CODEC_APLL_CFG5 0x47
|
||||
#define RK817_CODEC_DI2S_CKM 0x48
|
||||
#define RK817_CODEC_DI2S_RSD 0x49
|
||||
#define RK817_CODEC_DI2S_RXCR1 0x4a
|
||||
#define RK817_CODEC_DI2S_RXCR2 0x4b
|
||||
#define RK817_CODEC_DI2S_RXCMD_TSD 0x4c
|
||||
#define RK817_CODEC_DI2S_TXCR1 0x4d
|
||||
#define RK817_CODEC_DI2S_TXCR2 0x4e
|
||||
#define RK817_CODEC_DI2S_TXCR3_TXCMD 0x4f
|
||||
|
||||
/* RK817_CODEC_DI2S_CKM */
|
||||
#define RK817_I2S_MODE_MASK (0x1 << 0)
|
||||
#define RK817_I2S_MODE_MST (0x1 << 0)
|
||||
#define RK817_I2S_MODE_SLV (0x0 << 0)
|
||||
|
||||
/* RK817_CODEC_DDAC_MUTE_MIXCTL */
|
||||
#define DACMT_MASK (0x1 << 0)
|
||||
#define DACMT_ENABLE (0x1 << 0)
|
||||
#define DACMT_DISABLE (0x0 << 0)
|
||||
|
||||
/* RK817_CODEC_DI2S_RXCR2 */
|
||||
#define VDW_RX_24BITS (0x17)
|
||||
#define VDW_RX_16BITS (0x0f)
|
||||
|
||||
/* RK817_CODEC_DI2S_TXCR2 */
|
||||
#define VDW_TX_24BITS (0x17)
|
||||
#define VDW_TX_16BITS (0x0f)
|
||||
|
||||
/* RK817_CODEC_AMIC_CFG0 */
|
||||
#define MIC_DIFF_MASK (0x1 << 7)
|
||||
#define MIC_DIFF_DIS (0x0 << 7)
|
||||
#define MIC_DIFF_EN (0x1 << 7)
|
||||
|
||||
#define RK817_POWER_EN_REG(i) (0xb1 + (i))
|
||||
#define RK817_POWER_SLP_EN_REG(i) (0xb5 + (i))
|
||||
|
||||
|
@ -18,6 +18,8 @@
|
||||
#define WCD934X_EFUSE_SENSE_STATE_DEF 0x10
|
||||
#define WCD934X_EFUSE_SENSE_EN_MASK BIT(0)
|
||||
#define WCD934X_EFUSE_SENSE_ENABLE BIT(0)
|
||||
#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT1 0x002a
|
||||
#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT2 0x002b
|
||||
#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT14 0x0037
|
||||
#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT15 0x0038
|
||||
#define WCD934X_CHIP_TIER_CTRL_EFUSE_STATUS 0x0039
|
||||
@ -103,21 +105,58 @@
|
||||
#define WCD934X_ANA_AMIC3 0x0610
|
||||
#define WCD934X_ANA_AMIC4 0x0611
|
||||
#define WCD934X_ANA_MBHC_MECH 0x0614
|
||||
#define WCD934X_MBHC_L_DET_EN_MASK BIT(7)
|
||||
#define WCD934X_MBHC_L_DET_EN BIT(7)
|
||||
#define WCD934X_MBHC_GND_DET_EN_MASK BIT(6)
|
||||
#define WCD934X_MBHC_MECH_DETECT_TYPE_MASK BIT(5)
|
||||
#define WCD934X_MBHC_MECH_DETECT_TYPE_INS 1
|
||||
#define WCD934X_MBHC_HPHL_PLUG_TYPE_MASK BIT(4)
|
||||
#define WCD934X_MBHC_HPHL_PLUG_TYPE_NO 1
|
||||
#define WCD934X_MBHC_GND_PLUG_TYPE_MASK BIT(3)
|
||||
#define WCD934X_MBHC_GND_PLUG_TYPE_NO 1
|
||||
#define WCD934X_MBHC_HSL_PULLUP_COMP_EN BIT(2)
|
||||
#define WCD934X_MBHC_HSG_PULLUP_COMP_EN BIT(1)
|
||||
#define WCD934X_MBHC_HPHL_100K_TO_GND_EN BIT(0)
|
||||
#define WCD934X_ANA_MBHC_ELECT 0x0615
|
||||
#define WCD934X_ANA_MBHC_BIAS_EN_MASK BIT(0)
|
||||
#define WCD934X_ANA_MBHC_BIAS_EN BIT(0)
|
||||
#define WCD934X_ANA_MBHC_ZDET 0x0616
|
||||
#define WCD934X_ANA_MBHC_RESULT_1 0x0617
|
||||
#define WCD934X_ANA_MBHC_RESULT_2 0x0618
|
||||
#define WCD934X_ANA_MBHC_RESULT_3 0x0619
|
||||
#define WCD934X_ANA_MBHC_BTN0 0x061a
|
||||
#define WCD934X_VTH_MASK GENMASK(7, 2)
|
||||
#define WCD934X_ANA_MBHC_BTN1 0x061b
|
||||
#define WCD934X_ANA_MBHC_BTN2 0x061c
|
||||
#define WCD934X_ANA_MBHC_BTN3 0x061d
|
||||
#define WCD934X_ANA_MBHC_BTN4 0x061e
|
||||
#define WCD934X_ANA_MBHC_BTN5 0x061f
|
||||
#define WCD934X_ANA_MBHC_BTN6 0x0620
|
||||
#define WCD934X_ANA_MBHC_BTN7 0x0621
|
||||
#define WCD934X_MBHC_BTN_VTH_MASK GENMASK(7, 2)
|
||||
#define WCD934X_ANA_MICB1 0x0622
|
||||
#define WCD934X_MICB_VAL_MASK GENMASK(5, 0)
|
||||
#define WCD934X_ANA_MICB_EN_MASK GENMASK(7, 6)
|
||||
#define WCD934X_MICB_DISABLE 0
|
||||
#define WCD934X_MICB_ENABLE 1
|
||||
#define WCD934X_MICB_PULL_UP 2
|
||||
#define WCD934X_MICB_PULL_DOWN 3
|
||||
#define WCD934X_ANA_MICB_PULL_UP 0x80
|
||||
#define WCD934X_ANA_MICB_ENABLE 0x40
|
||||
#define WCD934X_ANA_MICB_DISABLE 0x0
|
||||
#define WCD934X_ANA_MICB2 0x0623
|
||||
#define WCD934X_ANA_MICB2_ENABLE BIT(6)
|
||||
#define WCD934X_ANA_MICB2_ENABLE_MASK GENMASK(7, 6)
|
||||
#define WCD934X_ANA_MICB2_VOUT_MASK GENMASK(5, 0)
|
||||
#define WCD934X_ANA_MICB2_RAMP 0x0624
|
||||
#define WCD934X_RAMP_EN_MASK BIT(7)
|
||||
#define WCD934X_RAMP_SHIFT_CTRL_MASK GENMASK(4, 2)
|
||||
#define WCD934X_ANA_MICB3 0x0625
|
||||
#define WCD934X_ANA_MICB4 0x0626
|
||||
#define WCD934X_BIAS_VBG_FINE_ADJ 0x0629
|
||||
#define WCD934X_MBHC_CTL_CLK 0x0656
|
||||
#define WCD934X_MBHC_CTL_BCS 0x065a
|
||||
#define WCD934X_MBHC_STATUS_SPARE_1 0x065b
|
||||
#define WCD934X_MICB1_TEST_CTL_1 0x066b
|
||||
#define WCD934X_MICB1_TEST_CTL_2 0x066c
|
||||
#define WCD934X_MICB2_TEST_CTL_1 0x066e
|
||||
@ -141,7 +180,11 @@
|
||||
#define WCD934X_HPH_CNP_WG_CTL 0x06cc
|
||||
#define WCD934X_HPH_GM3_BOOST_EN_MASK BIT(7)
|
||||
#define WCD934X_HPH_GM3_BOOST_ENABLE BIT(7)
|
||||
#define WCD934X_HPH_CNP_WG_TIME 0x06cd
|
||||
#define WCD934X_HPH_OCP_CTL 0x06ce
|
||||
#define WCD934X_HPH_PA_CTL2 0x06d2
|
||||
#define WCD934X_HPHPA_GND_R_MASK BIT(6)
|
||||
#define WCD934X_HPHPA_GND_L_MASK BIT(4)
|
||||
#define WCD934X_HPH_L_EN 0x06d3
|
||||
#define WCD934X_HPH_GAIN_SRC_SEL_MASK BIT(5)
|
||||
#define WCD934X_HPH_GAIN_SRC_SEL_COMPANDER 0
|
||||
@ -152,6 +195,8 @@
|
||||
#define WCD934X_HPH_OCP_DET_MASK BIT(0)
|
||||
#define WCD934X_HPH_OCP_DET_ENABLE BIT(0)
|
||||
#define WCD934X_HPH_OCP_DET_DISABLE 0
|
||||
#define WCD934X_HPH_R_ATEST 0x06d8
|
||||
#define WCD934X_HPHPA_GND_OVR_MASK BIT(1)
|
||||
#define WCD934X_DIFF_LO_LO2_COMPANDER 0x06ea
|
||||
#define WCD934X_DIFF_LO_LO1_COMPANDER 0x06eb
|
||||
#define WCD934X_CLK_SYS_MCLK_PRG 0x0711
|
||||
@ -172,7 +217,19 @@
|
||||
#define WCD934X_SIDO_NEW_VOUT_D_FREQ2 0x071e
|
||||
#define WCD934X_SIDO_RIPPLE_FREQ_EN_MASK BIT(0)
|
||||
#define WCD934X_SIDO_RIPPLE_FREQ_ENABLE BIT(0)
|
||||
#define WCD934X_MBHC_NEW_CTL_1 0x0720
|
||||
#define WCD934X_MBHC_CTL_RCO_EN_MASK BIT(7)
|
||||
#define WCD935X_MBHC_CTL_RCO_EN BIT(7)
|
||||
#define WCD934X_MBHC_NEW_CTL_2 0x0721
|
||||
#define WCD934X_M_RTH_CTL_MASK GENMASK(3, 2)
|
||||
#define WCD934X_MBHC_NEW_PLUG_DETECT_CTL 0x0722
|
||||
#define WCD934X_HSDET_PULLUP_C_MASK GENMASK(7, 6)
|
||||
#define WCD934X_MBHC_NEW_ZDET_ANA_CTL 0x0723
|
||||
#define WCD934X_ZDET_RANGE_CTL_MASK GENMASK(3, 0)
|
||||
#define WCD934X_ZDET_MAXV_CTL_MASK GENMASK(6, 4)
|
||||
#define WCD934X_MBHC_NEW_ZDET_RAMP_CTL 0x0724
|
||||
#define WCD934X_MBHC_NEW_FSM_STATUS 0x0725
|
||||
#define WCD934X_MBHC_NEW_ADC_RESULT 0x0726
|
||||
#define WCD934X_TX_NEW_AMIC_4_5_SEL 0x0727
|
||||
#define WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_L 0x0733
|
||||
#define WCD934X_HPH_NEW_INT_RDAC_OVERRIDE_CTL 0x0735
|
||||
|
@ -65,12 +65,22 @@ struct hdmi_codec_ops {
|
||||
|
||||
/*
|
||||
* Configures HDMI-encoder for audio stream.
|
||||
* Mandatory
|
||||
* Having either prepare or hw_params is mandatory.
|
||||
*/
|
||||
int (*hw_params)(struct device *dev, void *data,
|
||||
struct hdmi_codec_daifmt *fmt,
|
||||
struct hdmi_codec_params *hparms);
|
||||
|
||||
/*
|
||||
* Configures HDMI-encoder for audio stream. Can be called
|
||||
* multiple times for each setup.
|
||||
*
|
||||
* Having either prepare or hw_params is mandatory.
|
||||
*/
|
||||
int (*prepare)(struct device *dev, void *data,
|
||||
struct hdmi_codec_daifmt *fmt,
|
||||
struct hdmi_codec_params *hparms);
|
||||
|
||||
/*
|
||||
* Shuts down the audio stream.
|
||||
* Mandatory
|
||||
|
@ -4,6 +4,14 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
int snd_pcm_create_iec958_consumer_default(u8 *cs, size_t len);
|
||||
|
||||
int snd_pcm_fill_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
|
||||
size_t len);
|
||||
|
||||
int snd_pcm_fill_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
|
||||
u8 *cs, size_t len);
|
||||
|
||||
int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
|
||||
size_t len);
|
||||
|
||||
|
@ -36,6 +36,22 @@ struct snd_compr_stream;
|
||||
#define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J
|
||||
#define SND_SOC_DAIFMT_LSB SND_SOC_DAIFMT_RIGHT_J
|
||||
|
||||
/* Describes the possible PCM format */
|
||||
/*
|
||||
* use SND_SOC_DAI_FORMAT_xx as eash shift.
|
||||
* see
|
||||
* snd_soc_runtime_get_dai_fmt()
|
||||
*/
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_FORMAT_SHIFT 0
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_FORMAT_MASK (0xFFFF << SND_SOC_POSSIBLE_DAIFMT_FORMAT_SHIFT)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_I2S (1 << SND_SOC_DAI_FORMAT_I2S)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_RIGHT_J (1 << SND_SOC_DAI_FORMAT_RIGHT_J)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_LEFT_J (1 << SND_SOC_DAI_FORMAT_LEFT_J)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_DSP_A (1 << SND_SOC_DAI_FORMAT_DSP_A)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_DSP_B (1 << SND_SOC_DAI_FORMAT_DSP_B)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_AC97 (1 << SND_SOC_DAI_FORMAT_AC97)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_PDM (1 << SND_SOC_DAI_FORMAT_PDM)
|
||||
|
||||
/*
|
||||
* DAI Clock gating.
|
||||
*
|
||||
@ -45,6 +61,17 @@ struct snd_compr_stream;
|
||||
#define SND_SOC_DAIFMT_CONT (1 << 4) /* continuous clock */
|
||||
#define SND_SOC_DAIFMT_GATED (0 << 4) /* clock is gated */
|
||||
|
||||
/* Describes the possible PCM format */
|
||||
/*
|
||||
* define GATED -> CONT. GATED will be selected if both are selected.
|
||||
* see
|
||||
* snd_soc_runtime_get_dai_fmt()
|
||||
*/
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT 16
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_MASK (0xFFFF << SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_GATED (0x1ULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_CONT (0x2ULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_SHIFT)
|
||||
|
||||
/*
|
||||
* DAI hardware signal polarity.
|
||||
*
|
||||
@ -71,6 +98,14 @@ struct snd_compr_stream;
|
||||
#define SND_SOC_DAIFMT_IB_NF (3 << 8) /* invert BCLK + nor FRM */
|
||||
#define SND_SOC_DAIFMT_IB_IF (4 << 8) /* invert BCLK + FRM */
|
||||
|
||||
/* Describes the possible PCM format */
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_INV_SHIFT 32
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_INV_MASK (0xFFFFULL << SND_SOC_POSSIBLE_DAIFMT_INV_SHIFT)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_NB_NF (0x1ULL << SND_SOC_POSSIBLE_DAIFMT_INV_SHIFT)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_NB_IF (0x2ULL << SND_SOC_POSSIBLE_DAIFMT_INV_SHIFT)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_IB_NF (0x4ULL << SND_SOC_POSSIBLE_DAIFMT_INV_SHIFT)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_IB_IF (0x8ULL << SND_SOC_POSSIBLE_DAIFMT_INV_SHIFT)
|
||||
|
||||
/*
|
||||
* DAI hardware clock providers/consumers
|
||||
*
|
||||
@ -89,6 +124,14 @@ struct snd_compr_stream;
|
||||
#define SND_SOC_DAIFMT_CBM_CFS SND_SOC_DAIFMT_CBP_CFC
|
||||
#define SND_SOC_DAIFMT_CBS_CFS SND_SOC_DAIFMT_CBC_CFC
|
||||
|
||||
/* Describes the possible PCM format */
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT 48
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_MASK (0xFFFFULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_CBP_CFP (0x1ULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_CBC_CFP (0x2ULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_CBP_CFC (0x4ULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT)
|
||||
#define SND_SOC_POSSIBLE_DAIFMT_CBC_CFC (0x8ULL << SND_SOC_POSSIBLE_DAIFMT_CLOCK_PROVIDER_SHIFT)
|
||||
|
||||
#define SND_SOC_DAIFMT_FORMAT_MASK 0x000f
|
||||
#define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0
|
||||
#define SND_SOC_DAIFMT_INV_MASK 0x0f00
|
||||
@ -131,6 +174,8 @@ int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
|
||||
int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio);
|
||||
|
||||
/* Digital Audio interface formatting */
|
||||
int snd_soc_dai_get_fmt_max_priority(struct snd_soc_pcm_runtime *rtd);
|
||||
u64 snd_soc_dai_get_fmt(struct snd_soc_dai *dai, int priority);
|
||||
int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
|
||||
|
||||
int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
|
||||
@ -292,6 +337,16 @@ struct snd_soc_dai_ops {
|
||||
snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
|
||||
struct snd_soc_dai *);
|
||||
|
||||
/*
|
||||
* Format list for auto selection.
|
||||
* Format will be increased if priority format was
|
||||
* not selected.
|
||||
* see
|
||||
* snd_soc_dai_get_fmt()
|
||||
*/
|
||||
u64 *auto_selectable_formats;
|
||||
int num_auto_selectable_formats;
|
||||
|
||||
/* bit field */
|
||||
unsigned int no_capture_mute:1;
|
||||
};
|
||||
|
@ -54,7 +54,7 @@ struct snd_soc_dobj_control {
|
||||
|
||||
/* dynamic widget object */
|
||||
struct snd_soc_dobj_widget {
|
||||
unsigned int kcontrol_type; /* kcontrol type: mixer, enum, bytes */
|
||||
unsigned int *kcontrol_type; /* kcontrol type: mixer, enum, bytes */
|
||||
};
|
||||
|
||||
/* generic dynamic object - all dynamic objects belong to this struct */
|
||||
|
@ -1232,10 +1232,23 @@ void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
|
||||
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
|
||||
const char *propname);
|
||||
int snd_soc_of_parse_aux_devs(struct snd_soc_card *card, const char *propname);
|
||||
unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
|
||||
const char *prefix,
|
||||
struct device_node **bitclkmaster,
|
||||
struct device_node **framemaster);
|
||||
|
||||
unsigned int snd_soc_daifmt_clock_provider_fliped(unsigned int dai_fmt);
|
||||
unsigned int snd_soc_daifmt_clock_provider_from_bitmap(unsigned int bit_frame);
|
||||
|
||||
unsigned int snd_soc_daifmt_parse_format(struct device_node *np, const char *prefix);
|
||||
unsigned int snd_soc_daifmt_parse_clock_provider_raw(struct device_node *np,
|
||||
const char *prefix,
|
||||
struct device_node **bitclkmaster,
|
||||
struct device_node **framemaster);
|
||||
#define snd_soc_daifmt_parse_clock_provider_as_bitmap(np, prefix) \
|
||||
snd_soc_daifmt_parse_clock_provider_raw(np, prefix, NULL, NULL)
|
||||
#define snd_soc_daifmt_parse_clock_provider_as_phandle \
|
||||
snd_soc_daifmt_parse_clock_provider_raw
|
||||
#define snd_soc_daifmt_parse_clock_provider_as_flag(np, prefix) \
|
||||
snd_soc_daifmt_clock_provider_from_bitmap( \
|
||||
snd_soc_daifmt_parse_clock_provider_as_bitmap(np, prefix))
|
||||
|
||||
int snd_soc_get_dai_id(struct device_node *ep);
|
||||
int snd_soc_get_dai_name(const struct of_phandle_args *args,
|
||||
const char **dai_name);
|
||||
|
@ -9,41 +9,85 @@
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/pcm_iec958.h>
|
||||
|
||||
static int create_iec958_consumer(uint rate, uint sample_width,
|
||||
u8 *cs, size_t len)
|
||||
/**
|
||||
* snd_pcm_create_iec958_consumer_default - create default consumer format IEC958 channel status
|
||||
* @cs: channel status buffer, at least four bytes
|
||||
* @len: length of channel status buffer
|
||||
*
|
||||
* Create the consumer format channel status data in @cs of maximum size
|
||||
* @len. When relevant, the configuration-dependant bits will be set as
|
||||
* unspecified.
|
||||
*
|
||||
* Drivers should then call einter snd_pcm_fill_iec958_consumer() or
|
||||
* snd_pcm_fill_iec958_consumer_hw_params() to replace these unspecified
|
||||
* bits by their actual values.
|
||||
*
|
||||
* Drivers may wish to tweak the contents of the buffer after creation.
|
||||
*
|
||||
* Returns: length of buffer, or negative error code if something failed.
|
||||
*/
|
||||
int snd_pcm_create_iec958_consumer_default(u8 *cs, size_t len)
|
||||
{
|
||||
unsigned int fs, ws;
|
||||
|
||||
if (len < 4)
|
||||
return -EINVAL;
|
||||
|
||||
switch (rate) {
|
||||
case 32000:
|
||||
fs = IEC958_AES3_CON_FS_32000;
|
||||
break;
|
||||
case 44100:
|
||||
fs = IEC958_AES3_CON_FS_44100;
|
||||
break;
|
||||
case 48000:
|
||||
fs = IEC958_AES3_CON_FS_48000;
|
||||
break;
|
||||
case 88200:
|
||||
fs = IEC958_AES3_CON_FS_88200;
|
||||
break;
|
||||
case 96000:
|
||||
fs = IEC958_AES3_CON_FS_96000;
|
||||
break;
|
||||
case 176400:
|
||||
fs = IEC958_AES3_CON_FS_176400;
|
||||
break;
|
||||
case 192000:
|
||||
fs = IEC958_AES3_CON_FS_192000;
|
||||
break;
|
||||
default:
|
||||
memset(cs, 0, len);
|
||||
|
||||
cs[0] = IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE;
|
||||
cs[1] = IEC958_AES1_CON_GENERAL;
|
||||
cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC;
|
||||
cs[3] = IEC958_AES3_CON_CLOCK_1000PPM | IEC958_AES3_CON_FS_NOTID;
|
||||
|
||||
if (len > 4)
|
||||
cs[4] = IEC958_AES4_CON_WORDLEN_NOTID;
|
||||
|
||||
return len;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_create_iec958_consumer_default);
|
||||
|
||||
static int fill_iec958_consumer(uint rate, uint sample_width,
|
||||
u8 *cs, size_t len)
|
||||
{
|
||||
if (len < 4)
|
||||
return -EINVAL;
|
||||
|
||||
if ((cs[3] & IEC958_AES3_CON_FS) == IEC958_AES3_CON_FS_NOTID) {
|
||||
unsigned int fs;
|
||||
|
||||
switch (rate) {
|
||||
case 32000:
|
||||
fs = IEC958_AES3_CON_FS_32000;
|
||||
break;
|
||||
case 44100:
|
||||
fs = IEC958_AES3_CON_FS_44100;
|
||||
break;
|
||||
case 48000:
|
||||
fs = IEC958_AES3_CON_FS_48000;
|
||||
break;
|
||||
case 88200:
|
||||
fs = IEC958_AES3_CON_FS_88200;
|
||||
break;
|
||||
case 96000:
|
||||
fs = IEC958_AES3_CON_FS_96000;
|
||||
break;
|
||||
case 176400:
|
||||
fs = IEC958_AES3_CON_FS_176400;
|
||||
break;
|
||||
case 192000:
|
||||
fs = IEC958_AES3_CON_FS_192000;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cs[3] &= ~IEC958_AES3_CON_FS;
|
||||
cs[3] |= fs;
|
||||
}
|
||||
|
||||
if (len > 4) {
|
||||
if (len > 4 &&
|
||||
(cs[4] & IEC958_AES4_CON_WORDLEN) == IEC958_AES4_CON_WORDLEN_NOTID) {
|
||||
unsigned int ws;
|
||||
|
||||
switch (sample_width) {
|
||||
case 16:
|
||||
ws = IEC958_AES4_CON_WORDLEN_20_16;
|
||||
@ -64,21 +108,58 @@ static int create_iec958_consumer(uint rate, uint sample_width,
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cs[4] &= ~IEC958_AES4_CON_WORDLEN;
|
||||
cs[4] |= ws;
|
||||
}
|
||||
|
||||
memset(cs, 0, len);
|
||||
|
||||
cs[0] = IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE;
|
||||
cs[1] = IEC958_AES1_CON_GENERAL;
|
||||
cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC;
|
||||
cs[3] = IEC958_AES3_CON_CLOCK_1000PPM | fs;
|
||||
|
||||
if (len > 4)
|
||||
cs[4] = ws;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_pcm_fill_iec958_consumer - Fill consumer format IEC958 channel status
|
||||
* @runtime: pcm runtime structure with ->rate filled in
|
||||
* @cs: channel status buffer, at least four bytes
|
||||
* @len: length of channel status buffer
|
||||
*
|
||||
* Fill the unspecified bits in an IEC958 status bits array using the
|
||||
* parameters of the PCM runtime @runtime.
|
||||
*
|
||||
* Drivers may wish to tweak the contents of the buffer after its been
|
||||
* filled.
|
||||
*
|
||||
* Returns: length of buffer, or negative error code if something failed.
|
||||
*/
|
||||
int snd_pcm_fill_iec958_consumer(struct snd_pcm_runtime *runtime,
|
||||
u8 *cs, size_t len)
|
||||
{
|
||||
return fill_iec958_consumer(runtime->rate,
|
||||
snd_pcm_format_width(runtime->format),
|
||||
cs, len);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_fill_iec958_consumer);
|
||||
|
||||
/**
|
||||
* snd_pcm_fill_iec958_consumer_hw_params - Fill consumer format IEC958 channel status
|
||||
* @params: the hw_params instance for extracting rate and sample format
|
||||
* @cs: channel status buffer, at least four bytes
|
||||
* @len: length of channel status buffer
|
||||
*
|
||||
* Fill the unspecified bits in an IEC958 status bits array using the
|
||||
* parameters of the PCM hardware parameters @params.
|
||||
*
|
||||
* Drivers may wish to tweak the contents of the buffer after its been
|
||||
* filled..
|
||||
*
|
||||
* Returns: length of buffer, or negative error code if something failed.
|
||||
*/
|
||||
int snd_pcm_fill_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
|
||||
u8 *cs, size_t len)
|
||||
{
|
||||
return fill_iec958_consumer(params_rate(params), params_width(params), cs, len);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_fill_iec958_consumer_hw_params);
|
||||
|
||||
/**
|
||||
* snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status
|
||||
* @runtime: pcm runtime structure with ->rate filled in
|
||||
@ -95,9 +176,13 @@ static int create_iec958_consumer(uint rate, uint sample_width,
|
||||
int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
|
||||
size_t len)
|
||||
{
|
||||
return create_iec958_consumer(runtime->rate,
|
||||
snd_pcm_format_width(runtime->format),
|
||||
cs, len);
|
||||
int ret;
|
||||
|
||||
ret = snd_pcm_create_iec958_consumer_default(cs, len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return snd_pcm_fill_iec958_consumer(runtime, cs, len);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_create_iec958_consumer);
|
||||
|
||||
@ -117,7 +202,12 @@ EXPORT_SYMBOL(snd_pcm_create_iec958_consumer);
|
||||
int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params,
|
||||
u8 *cs, size_t len)
|
||||
{
|
||||
return create_iec958_consumer(params_rate(params), params_width(params),
|
||||
cs, len);
|
||||
int ret;
|
||||
|
||||
ret = snd_pcm_create_iec958_consumer_default(cs, len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return fill_iec958_consumer(params_rate(params), params_width(params), cs, len);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_create_iec958_consumer_hw_params);
|
||||
|
@ -198,8 +198,7 @@ static int axi_i2s_probe(struct platform_device *pdev)
|
||||
|
||||
axi_i2s_parse_of(i2s, pdev->dev.of_node);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
@ -189,8 +189,7 @@ static int axi_spdif_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, spdif);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
@ -77,7 +77,6 @@ static void enable_pdm_clock(void __iomem *acp_base)
|
||||
u32 pdm_clk_enable, pdm_ctrl;
|
||||
|
||||
pdm_clk_enable = ACP_PDM_CLK_FREQ_MASK;
|
||||
pdm_ctrl = 0x00;
|
||||
|
||||
rn_writel(pdm_clk_enable, acp_base + ACP_WOV_CLK_CTRL);
|
||||
pdm_ctrl = rn_readl(acp_base + ACP_WOV_MISC_CTRL);
|
||||
@ -144,9 +143,6 @@ static int stop_pdm_dma(void __iomem *acp_base)
|
||||
u32 pdm_enable, pdm_dma_enable;
|
||||
int timeout;
|
||||
|
||||
pdm_enable = 0x00;
|
||||
pdm_dma_enable = 0x00;
|
||||
|
||||
pdm_enable = rn_readl(acp_base + ACP_WOV_PDM_ENABLE);
|
||||
pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
|
||||
if (pdm_dma_enable & 0x01) {
|
||||
|
@ -558,8 +558,7 @@ static int atmel_classd_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
io_base = devm_ioremap_resource(dev, res);
|
||||
io_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(io_base))
|
||||
return PTR_ERR(io_base);
|
||||
|
||||
|
@ -629,8 +629,7 @@ static int atmel_i2s_probe(struct platform_device *pdev)
|
||||
dev->caps = match->data;
|
||||
|
||||
/* Map I/O registers. */
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(&pdev->dev, mem);
|
||||
base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
@ -620,8 +620,7 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
io_base = devm_ioremap_resource(dev, res);
|
||||
io_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(io_base))
|
||||
return PTR_ERR(io_base);
|
||||
|
||||
|
@ -1008,8 +1008,7 @@ static int mchp_i2s_mcc_probe(struct platform_device *pdev)
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(&pdev->dev, mem);
|
||||
base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
@ -120,19 +120,22 @@ static int snd_proto_probe(struct platform_device *pdev)
|
||||
dai->cpus->of_node = cpu_np;
|
||||
dai->platforms->of_node = cpu_np;
|
||||
|
||||
dai_fmt = snd_soc_of_parse_daifmt(np, NULL,
|
||||
&bitclkmaster, &framemaster);
|
||||
dai_fmt = snd_soc_daifmt_parse_format(np, NULL);
|
||||
snd_soc_daifmt_parse_clock_provider_as_phandle(np, NULL,
|
||||
&bitclkmaster, &framemaster);
|
||||
if (bitclkmaster != framemaster) {
|
||||
dev_err(&pdev->dev, "Must be the same bitclock and frame master\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (bitclkmaster) {
|
||||
dai_fmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
|
||||
if (codec_np == bitclkmaster)
|
||||
dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
|
||||
else
|
||||
dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
|
||||
} else {
|
||||
dai_fmt |= snd_soc_daifmt_parse_clock_provider_as_flag(np, NULL);
|
||||
}
|
||||
|
||||
of_node_put(bitclkmaster);
|
||||
of_node_put(framemaster);
|
||||
dai->dai_fmt = dai_fmt;
|
||||
|
@ -159,7 +159,7 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
|
||||
of_node_put(codec_np);
|
||||
of_node_put(cpu_np);
|
||||
|
||||
ret = snd_soc_register_card(card);
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Platform device allocation failed\n");
|
||||
goto out_put_audio;
|
||||
@ -180,7 +180,6 @@ static int sam9x5_wm8731_driver_remove(struct platform_device *pdev)
|
||||
struct snd_soc_card *card = platform_get_drvdata(pdev);
|
||||
struct sam9x5_drvdata *priv = card->drvdata;
|
||||
|
||||
snd_soc_unregister_card(card);
|
||||
atmel_ssc_put_audio(priv->ssc_id);
|
||||
|
||||
return 0;
|
||||
|
@ -1308,7 +1308,6 @@ static int cygnus_ssp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *child_node;
|
||||
struct resource *res;
|
||||
struct cygnus_audio *cygaud;
|
||||
int err;
|
||||
int node_count;
|
||||
@ -1320,13 +1319,11 @@ static int cygnus_ssp_probe(struct platform_device *pdev)
|
||||
|
||||
dev_set_drvdata(dev, cygaud);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aud");
|
||||
cygaud->audio = devm_ioremap_resource(dev, res);
|
||||
cygaud->audio = devm_platform_ioremap_resource_byname(pdev, "aud");
|
||||
if (IS_ERR(cygaud->audio))
|
||||
return PTR_ERR(cygaud->audio);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "i2s_in");
|
||||
cygaud->i2s_in = devm_ioremap_resource(dev, res);
|
||||
cygaud->i2s_in = devm_platform_ioremap_resource_byname(pdev, "i2s_in");
|
||||
if (IS_ERR(cygaud->i2s_in))
|
||||
return PTR_ERR(cygaud->i2s_in);
|
||||
|
||||
|
@ -155,6 +155,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_PCM512x_I2C
|
||||
imply SND_SOC_PCM512x_SPI
|
||||
imply SND_SOC_RK3328
|
||||
imply SND_SOC_RK817
|
||||
imply SND_SOC_RT274
|
||||
imply SND_SOC_RT286
|
||||
imply SND_SOC_RT298
|
||||
@ -211,6 +212,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_TAS6424
|
||||
imply SND_SOC_TDA7419
|
||||
imply SND_SOC_TFA9879
|
||||
imply SND_SOC_TFA989X
|
||||
imply SND_SOC_TLV320ADCX140
|
||||
imply SND_SOC_TLV320AIC23_I2C
|
||||
imply SND_SOC_TLV320AIC23_SPI
|
||||
@ -232,6 +234,8 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_UDA1380
|
||||
imply SND_SOC_WCD9335
|
||||
imply SND_SOC_WCD934X
|
||||
imply SND_SOC_WCD937X
|
||||
imply SND_SOC_WCD938X
|
||||
imply SND_SOC_LPASS_RX_MACRO
|
||||
imply SND_SOC_LPASS_TX_MACRO
|
||||
imply SND_SOC_WL1273
|
||||
@ -1063,6 +1067,11 @@ config SND_SOC_RK3328
|
||||
tristate "Rockchip RK3328 audio CODEC"
|
||||
select REGMAP_MMIO
|
||||
|
||||
config SND_SOC_RK817
|
||||
tristate "Rockchip RK817 audio CODEC"
|
||||
depends on MFD_RK808
|
||||
select REGMAP_I2C
|
||||
|
||||
config SND_SOC_RL6231
|
||||
tristate
|
||||
default y if SND_SOC_RT5514=y
|
||||
@ -1180,7 +1189,7 @@ config SND_SOC_RT5631
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_RT5640
|
||||
tristate
|
||||
tristate "Realtek RT5640/RT5639 Codec"
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_RT5645
|
||||
@ -1408,6 +1417,16 @@ config SND_SOC_TFA9879
|
||||
tristate "NXP Semiconductors TFA9879 amplifier"
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_TFA989X
|
||||
tristate "NXP/Goodix TFA989X (TFA1) amplifiers"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Enable support for NXP (now Goodix) TFA989X (TFA1 family) speaker
|
||||
amplifiers, e.g. TFA9895.
|
||||
Note that the driver currently bypasses the built-in "CoolFlux DSP"
|
||||
and does not support (hardware) volume control.
|
||||
|
||||
config SND_SOC_TLV320AIC23
|
||||
tristate
|
||||
|
||||
@ -1525,14 +1544,30 @@ config SND_SOC_WCD9335
|
||||
Qualcomm Technologies, Inc. (QTI) multimedia solutions,
|
||||
including the MSM8996, MSM8976, and MSM8956 chipsets.
|
||||
|
||||
config SND_SOC_WCD_MBHC
|
||||
tristate
|
||||
|
||||
config SND_SOC_WCD934X
|
||||
tristate "WCD9340/WCD9341 Codec"
|
||||
depends on COMMON_CLK
|
||||
select SND_SOC_WCD_MBHC
|
||||
depends on MFD_WCD934X
|
||||
help
|
||||
The WCD9340/9341 is a audio codec IC Integrated in
|
||||
Qualcomm SoCs like SDM845.
|
||||
|
||||
config SND_SOC_WCD938X
|
||||
tristate
|
||||
|
||||
config SND_SOC_WCD938X_SDW
|
||||
tristate "WCD9380/WCD9385 Codec - SDW"
|
||||
select SND_SOC_WCD938X
|
||||
depends on SOUNDWIRE
|
||||
select REGMAP_SOUNDWIRE
|
||||
help
|
||||
The WCD9380/9385 is a audio codec IC Integrated in
|
||||
Qualcomm SoCs like SM8250.
|
||||
|
||||
config SND_SOC_WL1273
|
||||
tristate
|
||||
|
||||
@ -1871,18 +1906,22 @@ config SND_SOC_TPA6130A2
|
||||
|
||||
config SND_SOC_LPASS_WSA_MACRO
|
||||
depends on COMMON_CLK
|
||||
select REGMAP_MMIO
|
||||
tristate "Qualcomm WSA Macro in LPASS(Low Power Audio SubSystem)"
|
||||
|
||||
config SND_SOC_LPASS_VA_MACRO
|
||||
depends on COMMON_CLK
|
||||
select REGMAP_MMIO
|
||||
tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)"
|
||||
|
||||
config SND_SOC_LPASS_RX_MACRO
|
||||
depends on COMMON_CLK
|
||||
select REGMAP_MMIO
|
||||
tristate "Qualcomm RX Macro in LPASS(Low Power Audio SubSystem)"
|
||||
|
||||
config SND_SOC_LPASS_TX_MACRO
|
||||
depends on COMMON_CLK
|
||||
select REGMAP_MMIO
|
||||
tristate "Qualcomm TX Macro in LPASS(Low Power Audio SubSystem)"
|
||||
|
||||
endmenu
|
||||
|
@ -166,6 +166,7 @@ snd-soc-pcm512x-objs := pcm512x.o
|
||||
snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
|
||||
snd-soc-pcm512x-spi-objs := pcm512x-spi.o
|
||||
snd-soc-rk3328-objs := rk3328_codec.o
|
||||
snd-soc-rk817-objs := rk817_codec.o
|
||||
snd-soc-rl6231-objs := rl6231.o
|
||||
snd-soc-rl6347a-objs := rl6347a.o
|
||||
snd-soc-rt1011-objs := rt1011.o
|
||||
@ -229,6 +230,7 @@ snd-soc-tas6424-objs := tas6424.o
|
||||
snd-soc-tda7419-objs := tda7419.o
|
||||
snd-soc-tas2770-objs := tas2770.o
|
||||
snd-soc-tfa9879-objs := tfa9879.o
|
||||
snd-soc-tfa989x-objs := tfa989x.o
|
||||
snd-soc-tlv320aic23-objs := tlv320aic23.o
|
||||
snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
|
||||
snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o
|
||||
@ -250,8 +252,11 @@ snd-soc-twl6040-objs := twl6040.o
|
||||
snd-soc-uda1334-objs := uda1334.o
|
||||
snd-soc-uda134x-objs := uda134x.o
|
||||
snd-soc-uda1380-objs := uda1380.o
|
||||
snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o
|
||||
snd-soc-wcd9335-objs := wcd-clsh-v2.o wcd9335.o
|
||||
snd-soc-wcd934x-objs := wcd-clsh-v2.o wcd934x.o
|
||||
snd-soc-wcd938x-objs := wcd938x.o wcd-clsh-v2.o
|
||||
snd-soc-wcd938x-sdw-objs := wcd938x-sdw.o
|
||||
snd-soc-wl1273-objs := wl1273.o
|
||||
snd-soc-wm-adsp-objs := wm_adsp.o
|
||||
snd-soc-wm0010-objs := wm0010.o
|
||||
@ -487,6 +492,7 @@ obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o
|
||||
obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
|
||||
obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o
|
||||
obj-$(CONFIG_SND_SOC_RK817) += snd-soc-rk817.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
|
||||
@ -551,6 +557,7 @@ obj-$(CONFIG_SND_SOC_TAS6424) += snd-soc-tas6424.o
|
||||
obj-$(CONFIG_SND_SOC_TDA7419) += snd-soc-tda7419.o
|
||||
obj-$(CONFIG_SND_SOC_TAS2770) += snd-soc-tas2770.o
|
||||
obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o
|
||||
obj-$(CONFIG_SND_SOC_TFA989X) += snd-soc-tfa989x.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o
|
||||
@ -572,8 +579,11 @@ obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
|
||||
obj-$(CONFIG_SND_SOC_UDA1334) += snd-soc-uda1334.o
|
||||
obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
|
||||
obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
|
||||
obj-$(CONFIG_SND_SOC_WCD_MBHC) += snd-soc-wcd-mbhc.o
|
||||
obj-$(CONFIG_SND_SOC_WCD9335) += snd-soc-wcd9335.o
|
||||
obj-$(CONFIG_SND_SOC_WCD934X) += snd-soc-wcd934x.o
|
||||
obj-$(CONFIG_SND_SOC_WCD938X) += snd-soc-wcd938x.o
|
||||
obj-$(CONFIG_SND_SOC_WCD938X_SDW) += snd-soc-wcd938x-sdw.o
|
||||
obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o
|
||||
obj-$(CONFIG_SND_SOC_WM0010) += snd-soc-wm0010.o
|
||||
obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
|
||||
|
@ -539,6 +539,15 @@ static int ak4613_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Select below from Sound Card, not Auto
|
||||
* SND_SOC_DAIFMT_CBC_CFC
|
||||
* SND_SOC_DAIFMT_CBP_CFP
|
||||
*/
|
||||
static u64 ak4613_dai_formats =
|
||||
SND_SOC_POSSIBLE_DAIFMT_I2S |
|
||||
SND_SOC_POSSIBLE_DAIFMT_LEFT_J;
|
||||
|
||||
static const struct snd_soc_dai_ops ak4613_dai_ops = {
|
||||
.startup = ak4613_dai_startup,
|
||||
.shutdown = ak4613_dai_shutdown,
|
||||
@ -546,6 +555,8 @@ static const struct snd_soc_dai_ops ak4613_dai_ops = {
|
||||
.set_fmt = ak4613_dai_set_fmt,
|
||||
.trigger = ak4613_dai_trigger,
|
||||
.hw_params = ak4613_dai_hw_params,
|
||||
.auto_selectable_formats = &ak4613_dai_formats,
|
||||
.num_auto_selectable_formats = 1,
|
||||
};
|
||||
|
||||
#define AK4613_PCM_RATE (SNDRV_PCM_RATE_32000 |\
|
||||
|
21
sound/soc/codecs/cirrus_legacy.h
Normal file
21
sound/soc/codecs/cirrus_legacy.h
Normal file
@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Some small helpers for older Cirrus Logic parts.
|
||||
*
|
||||
* Copyright (C) 2021 Cirrus Logic, Inc. and
|
||||
* Cirrus Logic International Semiconductor Ltd.
|
||||
*/
|
||||
|
||||
static inline int cirrus_read_device_id(struct regmap *regmap, unsigned int reg)
|
||||
{
|
||||
u8 devid[3];
|
||||
int ret;
|
||||
|
||||
ret = regmap_bulk_read(regmap, reg, devid, ARRAY_SIZE(devid));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ((devid[0] & 0xFF) << 12) |
|
||||
((devid[1] & 0xFF) << 4) |
|
||||
((devid[2] & 0xF0) >> 4);
|
||||
}
|
@ -30,6 +30,7 @@
|
||||
#include <dt-bindings/sound/cs35l32.h>
|
||||
|
||||
#include "cs35l32.h"
|
||||
#include "cirrus_legacy.h"
|
||||
|
||||
#define CS35L32_NUM_SUPPLIES 2
|
||||
static const char *const cs35l32_supply_names[CS35L32_NUM_SUPPLIES] = {
|
||||
@ -351,8 +352,7 @@ static int cs35l32_i2c_probe(struct i2c_client *i2c_client,
|
||||
struct cs35l32_private *cs35l32;
|
||||
struct cs35l32_platform_data *pdata =
|
||||
dev_get_platdata(&i2c_client->dev);
|
||||
int ret, i;
|
||||
unsigned int devid = 0;
|
||||
int ret, i, devid;
|
||||
unsigned int reg;
|
||||
|
||||
cs35l32 = devm_kzalloc(&i2c_client->dev, sizeof(*cs35l32), GFP_KERNEL);
|
||||
@ -407,40 +407,40 @@ static int cs35l32_i2c_probe(struct i2c_client *i2c_client,
|
||||
/* Reset the Device */
|
||||
cs35l32->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
|
||||
"reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(cs35l32->reset_gpio))
|
||||
return PTR_ERR(cs35l32->reset_gpio);
|
||||
if (IS_ERR(cs35l32->reset_gpio)) {
|
||||
ret = PTR_ERR(cs35l32->reset_gpio);
|
||||
goto err_supplies;
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(cs35l32->reset_gpio, 1);
|
||||
|
||||
/* initialize codec */
|
||||
ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_AB, ®);
|
||||
devid = (reg & 0xFF) << 12;
|
||||
|
||||
ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_CD, ®);
|
||||
devid |= (reg & 0xFF) << 4;
|
||||
|
||||
ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_E, ®);
|
||||
devid |= (reg & 0xF0) >> 4;
|
||||
devid = cirrus_read_device_id(cs35l32->regmap, CS35L32_DEVID_AB);
|
||||
if (devid < 0) {
|
||||
ret = devid;
|
||||
dev_err(&i2c_client->dev, "Failed to read device ID: %d\n", ret);
|
||||
goto err_disable;
|
||||
}
|
||||
|
||||
if (devid != CS35L32_CHIP_ID) {
|
||||
ret = -ENODEV;
|
||||
dev_err(&i2c_client->dev,
|
||||
"CS35L32 Device ID (%X). Expected %X\n",
|
||||
devid, CS35L32_CHIP_ID);
|
||||
return ret;
|
||||
goto err_disable;
|
||||
}
|
||||
|
||||
ret = regmap_read(cs35l32->regmap, CS35L32_REV_ID, ®);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "Get Revision ID failed\n");
|
||||
return ret;
|
||||
goto err_disable;
|
||||
}
|
||||
|
||||
ret = regmap_register_patch(cs35l32->regmap, cs35l32_monitor_patch,
|
||||
ARRAY_SIZE(cs35l32_monitor_patch));
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "Failed to apply errata patch\n");
|
||||
return ret;
|
||||
goto err_disable;
|
||||
}
|
||||
|
||||
dev_info(&i2c_client->dev,
|
||||
@ -481,7 +481,7 @@ static int cs35l32_i2c_probe(struct i2c_client *i2c_client,
|
||||
CS35L32_PDN_AMP);
|
||||
|
||||
/* Clear MCLK Error Bit since we don't have the clock yet */
|
||||
ret = regmap_read(cs35l32->regmap, CS35L32_INT_STATUS_1, ®);
|
||||
regmap_read(cs35l32->regmap, CS35L32_INT_STATUS_1, ®);
|
||||
|
||||
ret = devm_snd_soc_register_component(&i2c_client->dev,
|
||||
&soc_component_dev_cs35l32, cs35l32_dai,
|
||||
@ -492,6 +492,8 @@ static int cs35l32_i2c_probe(struct i2c_client *i2c_client,
|
||||
return 0;
|
||||
|
||||
err_disable:
|
||||
gpiod_set_value_cansleep(cs35l32->reset_gpio, 0);
|
||||
err_supplies:
|
||||
regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies),
|
||||
cs35l32->supplies);
|
||||
return ret;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#include "cs35l33.h"
|
||||
#include "cirrus_legacy.h"
|
||||
|
||||
#define CS35L33_BOOT_DELAY 50
|
||||
|
||||
@ -1190,12 +1191,12 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client,
|
||||
regcache_cache_only(cs35l33->regmap, false);
|
||||
|
||||
/* initialize codec */
|
||||
ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_AB, ®);
|
||||
devid = (reg & 0xFF) << 12;
|
||||
ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_CD, ®);
|
||||
devid |= (reg & 0xFF) << 4;
|
||||
ret = regmap_read(cs35l33->regmap, CS35L33_DEVID_E, ®);
|
||||
devid |= (reg & 0xF0) >> 4;
|
||||
devid = cirrus_read_device_id(cs35l33->regmap, CS35L33_DEVID_AB);
|
||||
if (devid < 0) {
|
||||
ret = devid;
|
||||
dev_err(&i2c_client->dev, "Failed to read device ID: %d\n", ret);
|
||||
goto err_enable;
|
||||
}
|
||||
|
||||
if (devid != CS35L33_CHIP_ID) {
|
||||
dev_err(&i2c_client->dev,
|
||||
@ -1243,6 +1244,8 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client,
|
||||
return 0;
|
||||
|
||||
err_enable:
|
||||
gpiod_set_value_cansleep(cs35l33->reset_gpio, 0);
|
||||
|
||||
regulator_bulk_disable(cs35l33->num_core_supplies,
|
||||
cs35l33->core_supplies);
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <sound/cs35l34.h>
|
||||
|
||||
#include "cs35l34.h"
|
||||
#include "cirrus_legacy.h"
|
||||
|
||||
#define PDN_DONE_ATTEMPTS 10
|
||||
#define CS35L34_START_DELAY 50
|
||||
@ -999,9 +1000,8 @@ static int cs35l34_i2c_probe(struct i2c_client *i2c_client,
|
||||
struct cs35l34_private *cs35l34;
|
||||
struct cs35l34_platform_data *pdata =
|
||||
dev_get_platdata(&i2c_client->dev);
|
||||
int i;
|
||||
int i, devid;
|
||||
int ret;
|
||||
unsigned int devid = 0;
|
||||
unsigned int reg;
|
||||
|
||||
cs35l34 = devm_kzalloc(&i2c_client->dev, sizeof(*cs35l34), GFP_KERNEL);
|
||||
@ -1042,13 +1042,15 @@ static int cs35l34_i2c_probe(struct i2c_client *i2c_client,
|
||||
} else {
|
||||
pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata),
|
||||
GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
if (!pdata) {
|
||||
ret = -ENOMEM;
|
||||
goto err_regulator;
|
||||
}
|
||||
|
||||
if (i2c_client->dev.of_node) {
|
||||
ret = cs35l34_handle_of_data(i2c_client, pdata);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
goto err_regulator;
|
||||
|
||||
}
|
||||
cs35l34->pdata = *pdata;
|
||||
@ -1062,33 +1064,34 @@ static int cs35l34_i2c_probe(struct i2c_client *i2c_client,
|
||||
|
||||
cs35l34->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
|
||||
"reset-gpios", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(cs35l34->reset_gpio))
|
||||
return PTR_ERR(cs35l34->reset_gpio);
|
||||
if (IS_ERR(cs35l34->reset_gpio)) {
|
||||
ret = PTR_ERR(cs35l34->reset_gpio);
|
||||
goto err_regulator;
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(cs35l34->reset_gpio, 1);
|
||||
|
||||
msleep(CS35L34_START_DELAY);
|
||||
|
||||
ret = regmap_read(cs35l34->regmap, CS35L34_DEVID_AB, ®);
|
||||
|
||||
devid = (reg & 0xFF) << 12;
|
||||
ret = regmap_read(cs35l34->regmap, CS35L34_DEVID_CD, ®);
|
||||
devid |= (reg & 0xFF) << 4;
|
||||
ret = regmap_read(cs35l34->regmap, CS35L34_DEVID_E, ®);
|
||||
devid |= (reg & 0xF0) >> 4;
|
||||
devid = cirrus_read_device_id(cs35l34->regmap, CS35L34_DEVID_AB);
|
||||
if (devid < 0) {
|
||||
ret = devid;
|
||||
dev_err(&i2c_client->dev, "Failed to read device ID: %d\n", ret);
|
||||
goto err_reset;
|
||||
}
|
||||
|
||||
if (devid != CS35L34_CHIP_ID) {
|
||||
dev_err(&i2c_client->dev,
|
||||
"CS35l34 Device ID (%X). Expected ID %X\n",
|
||||
devid, CS35L34_CHIP_ID);
|
||||
ret = -ENODEV;
|
||||
goto err_regulator;
|
||||
goto err_reset;
|
||||
}
|
||||
|
||||
ret = regmap_read(cs35l34->regmap, CS35L34_REV_ID, ®);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "Get Revision ID failed\n");
|
||||
goto err_regulator;
|
||||
goto err_reset;
|
||||
}
|
||||
|
||||
dev_info(&i2c_client->dev,
|
||||
@ -1113,11 +1116,13 @@ static int cs35l34_i2c_probe(struct i2c_client *i2c_client,
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev,
|
||||
"%s: Register component failed\n", __func__);
|
||||
goto err_regulator;
|
||||
goto err_reset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_reset:
|
||||
gpiod_set_value_cansleep(cs35l34->reset_gpio, 0);
|
||||
err_regulator:
|
||||
regulator_bulk_disable(cs35l34->num_core_supplies,
|
||||
cs35l34->core_supplies);
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <linux/completion.h>
|
||||
|
||||
#include "cs35l35.h"
|
||||
#include "cirrus_legacy.h"
|
||||
|
||||
/*
|
||||
* Some fields take zero as a valid value so use a high bit flag that won't
|
||||
@ -367,16 +368,16 @@ static int cs35l35_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
|
||||
struct snd_soc_component *component = codec_dai->component;
|
||||
struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBM_CFM:
|
||||
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBP_CFP:
|
||||
regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
|
||||
CS35L35_MS_MASK, 1 << CS35L35_MS_SHIFT);
|
||||
cs35l35->slave_mode = false;
|
||||
cs35l35->clock_consumer = false;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
case SND_SOC_DAIFMT_CBC_CFC:
|
||||
regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
|
||||
CS35L35_MS_MASK, 0 << CS35L35_MS_SHIFT);
|
||||
cs35l35->slave_mode = true;
|
||||
cs35l35->clock_consumer = true;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@ -495,10 +496,10 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
|
||||
* the Class H algorithm does not enable weak-drive operation for
|
||||
* nonzero values of CH_WKFET_DELAY if SP_RATE = 01 or 10
|
||||
*/
|
||||
errata_chk = clk_ctl & CS35L35_SP_RATE_MASK;
|
||||
errata_chk = (clk_ctl & CS35L35_SP_RATE_MASK) >> CS35L35_SP_RATE_SHIFT;
|
||||
|
||||
if (classh->classh_wk_fet_disable == 0x00 &&
|
||||
(errata_chk == 0x01 || errata_chk == 0x03)) {
|
||||
(errata_chk == 0x01 || errata_chk == 0x02)) {
|
||||
ret = regmap_update_bits(cs35l35->regmap,
|
||||
CS35L35_CLASS_H_FET_DRIVE_CTL,
|
||||
CS35L35_CH_WKFET_DEL_MASK,
|
||||
@ -555,8 +556,8 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
|
||||
}
|
||||
sp_sclks = ((cs35l35->sclk / srate) / 4) - 1;
|
||||
|
||||
/* Only certain ratios are supported in I2S Slave Mode */
|
||||
if (cs35l35->slave_mode) {
|
||||
/* Only certain ratios supported when device is a clock consumer */
|
||||
if (cs35l35->clock_consumer) {
|
||||
switch (sp_sclks) {
|
||||
case CS35L35_SP_SCLKS_32FS:
|
||||
case CS35L35_SP_SCLKS_48FS:
|
||||
@ -567,7 +568,7 @@ static int cs35l35_hw_params(struct snd_pcm_substream *substream,
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
/* Only certain ratios supported in I2S MASTER Mode */
|
||||
/* Only certain ratios supported when device is a clock provider */
|
||||
switch (sp_sclks) {
|
||||
case CS35L35_SP_SCLKS_32FS:
|
||||
case CS35L35_SP_SCLKS_64FS:
|
||||
@ -1471,9 +1472,8 @@ static int cs35l35_i2c_probe(struct i2c_client *i2c_client,
|
||||
struct cs35l35_private *cs35l35;
|
||||
struct device *dev = &i2c_client->dev;
|
||||
struct cs35l35_platform_data *pdata = dev_get_platdata(dev);
|
||||
int i;
|
||||
int i, devid;
|
||||
int ret;
|
||||
unsigned int devid = 0;
|
||||
unsigned int reg;
|
||||
|
||||
cs35l35 = devm_kzalloc(dev, sizeof(struct cs35l35_private), GFP_KERNEL);
|
||||
@ -1552,13 +1552,12 @@ static int cs35l35_i2c_probe(struct i2c_client *i2c_client,
|
||||
goto err;
|
||||
}
|
||||
/* initialize codec */
|
||||
ret = regmap_read(cs35l35->regmap, CS35L35_DEVID_AB, ®);
|
||||
|
||||
devid = (reg & 0xFF) << 12;
|
||||
ret = regmap_read(cs35l35->regmap, CS35L35_DEVID_CD, ®);
|
||||
devid |= (reg & 0xFF) << 4;
|
||||
ret = regmap_read(cs35l35->regmap, CS35L35_DEVID_E, ®);
|
||||
devid |= (reg & 0xF0) >> 4;
|
||||
devid = cirrus_read_device_id(cs35l35->regmap, CS35L35_DEVID_AB);
|
||||
if (devid < 0) {
|
||||
ret = devid;
|
||||
dev_err(dev, "Failed to read device ID: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (devid != CS35L35_CHIP_ID) {
|
||||
dev_err(dev, "CS35L35 Device ID (%X). Expected ID %X\n",
|
||||
|
@ -168,6 +168,7 @@
|
||||
#define CS35L35_SP_SCLKS_48FS 0x0B
|
||||
#define CS35L35_SP_SCLKS_64FS 0x0F
|
||||
#define CS35L35_SP_RATE_MASK 0xC0
|
||||
#define CS35L35_SP_RATE_SHIFT 6
|
||||
|
||||
#define CS35L35_PDN_BST_MASK 0x06
|
||||
#define CS35L35_PDN_BST_FETON_SHIFT 1
|
||||
@ -282,7 +283,7 @@ struct cs35l35_private {
|
||||
int sclk;
|
||||
bool pdm_mode;
|
||||
bool i2s_mode;
|
||||
bool slave_mode;
|
||||
bool clock_consumer;
|
||||
/* GPIO for /RST */
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct completion pdn_done;
|
||||
|
@ -756,14 +756,14 @@ static int cs35l36_set_dai_fmt(struct snd_soc_dai *component_dai,
|
||||
{
|
||||
struct cs35l36_private *cs35l36 =
|
||||
snd_soc_component_get_drvdata(component_dai->component);
|
||||
unsigned int asp_fmt, lrclk_fmt, sclk_fmt, slave_mode, clk_frc;
|
||||
unsigned int asp_fmt, lrclk_fmt, sclk_fmt, clock_provider, clk_frc;
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBM_CFM:
|
||||
slave_mode = 1;
|
||||
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBP_CFP:
|
||||
clock_provider = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
slave_mode = 0;
|
||||
case SND_SOC_DAIFMT_CBC_CFC:
|
||||
clock_provider = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@ -771,10 +771,10 @@ static int cs35l36_set_dai_fmt(struct snd_soc_dai *component_dai,
|
||||
|
||||
regmap_update_bits(cs35l36->regmap, CS35L36_ASP_TX_PIN_CTRL,
|
||||
CS35L36_SCLK_MSTR_MASK,
|
||||
slave_mode << CS35L36_SCLK_MSTR_SHIFT);
|
||||
clock_provider << CS35L36_SCLK_MSTR_SHIFT);
|
||||
regmap_update_bits(cs35l36->regmap, CS35L36_ASP_RATE_CTRL,
|
||||
CS35L36_LRCLK_MSTR_MASK,
|
||||
slave_mode << CS35L36_LRCLK_MSTR_SHIFT);
|
||||
clock_provider << CS35L36_LRCLK_MSTR_SHIFT);
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
|
||||
case SND_SOC_DAIFMT_CONT:
|
||||
@ -1156,7 +1156,7 @@ static int cs35l36_component_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct cs35l36_private *cs35l36 =
|
||||
snd_soc_component_get_drvdata(component);
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
if ((cs35l36->rev_id == CS35L36_REV_A0) && cs35l36->pdata.dcm_mode) {
|
||||
regmap_update_bits(cs35l36->regmap, CS35L36_BSTCVRT_DCM_CTRL,
|
||||
|
@ -573,7 +573,7 @@ static int cs4265_i2c_probe(struct i2c_client *i2c_client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct cs4265_private *cs4265;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
unsigned int devid = 0;
|
||||
unsigned int reg;
|
||||
|
||||
@ -602,6 +602,11 @@ static int cs4265_i2c_probe(struct i2c_client *i2c_client,
|
||||
i2c_set_clientdata(i2c_client, cs4265);
|
||||
|
||||
ret = regmap_read(cs4265->regmap, CS4265_CHIP_ID, ®);
|
||||
if (ret) {
|
||||
dev_err(&i2c_client->dev, "Failed to read chip ID: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
devid = reg & CS4265_CHIP_ID_MASK;
|
||||
if (devid != CS4265_CHIP_ID_VAL) {
|
||||
ret = -ENODEV;
|
||||
@ -616,10 +621,9 @@ static int cs4265_i2c_probe(struct i2c_client *i2c_client,
|
||||
|
||||
regmap_write(cs4265->regmap, CS4265_PWRCTL, 0x0F);
|
||||
|
||||
ret = devm_snd_soc_register_component(&i2c_client->dev,
|
||||
return devm_snd_soc_register_component(&i2c_client->dev,
|
||||
&soc_component_cs4265, cs4265_dai,
|
||||
ARRAY_SIZE(cs4265_dai));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id cs4265_of_match[] = {
|
||||
|
@ -19,11 +19,11 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <sound/core.h>
|
||||
@ -36,6 +36,7 @@
|
||||
#include <dt-bindings/sound/cs42l42.h>
|
||||
|
||||
#include "cs42l42.h"
|
||||
#include "cirrus_legacy.h"
|
||||
|
||||
static const struct reg_default cs42l42_reg_defaults[] = {
|
||||
{ CS42L42_FRZ_CTL, 0x00 },
|
||||
@ -521,26 +522,33 @@ static const struct snd_soc_dapm_route cs42l42_audio_map[] = {
|
||||
{ "SDOUT2", NULL, "ASP TX EN" },
|
||||
};
|
||||
|
||||
static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_jack *jk, void *d)
|
||||
{
|
||||
struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
cs42l42->jack = jk;
|
||||
|
||||
regmap_update_bits(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK,
|
||||
CS42L42_RS_PLUG_MASK | CS42L42_RS_UNPLUG_MASK |
|
||||
CS42L42_TS_PLUG_MASK | CS42L42_TS_UNPLUG_MASK,
|
||||
(1 << CS42L42_RS_PLUG_SHIFT) | (1 << CS42L42_RS_UNPLUG_SHIFT) |
|
||||
(0 << CS42L42_TS_PLUG_SHIFT) | (0 << CS42L42_TS_UNPLUG_SHIFT));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs42l42_component_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct cs42l42_private *cs42l42 =
|
||||
(struct cs42l42_private *)snd_soc_component_get_drvdata(component);
|
||||
struct snd_soc_card *crd = component->card;
|
||||
int ret = 0;
|
||||
struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
cs42l42->component = component;
|
||||
|
||||
ret = snd_soc_card_jack_new(crd, "CS42L42 Headset", SND_JACK_HEADSET | SND_JACK_BTN_0 |
|
||||
SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3,
|
||||
&cs42l42->jack, NULL, 0);
|
||||
if (ret < 0)
|
||||
dev_err(component->dev, "Cannot create CS42L42 Headset: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver soc_component_dev_cs42l42 = {
|
||||
.probe = cs42l42_component_probe,
|
||||
.set_jack = cs42l42_set_jack,
|
||||
.dapm_widgets = cs42l42_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets),
|
||||
.dapm_routes = cs42l42_audio_map,
|
||||
@ -581,6 +589,7 @@ struct cs42l42_pll_params {
|
||||
u8 pll_divout;
|
||||
u32 mclk_int;
|
||||
u8 pll_cal_ratio;
|
||||
u8 n;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -588,21 +597,23 @@ struct cs42l42_pll_params {
|
||||
* Table 4-5 from the Datasheet
|
||||
*/
|
||||
static const struct cs42l42_pll_params pll_ratio_table[] = {
|
||||
{ 1536000, 0, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125 },
|
||||
{ 2822400, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128 },
|
||||
{ 3000000, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128 },
|
||||
{ 3072000, 0, 1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125 },
|
||||
{ 4000000, 0, 1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000, 96 },
|
||||
{ 4096000, 0, 1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000, 94 },
|
||||
{ 5644800, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128 },
|
||||
{ 6000000, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128 },
|
||||
{ 6144000, 0, 1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125 },
|
||||
{ 11289600, 0, 0, 0, 0, 0, 0, 0, 11289600, 0 },
|
||||
{ 12000000, 0, 0, 0, 0, 0, 0, 0, 12000000, 0 },
|
||||
{ 12288000, 0, 0, 0, 0, 0, 0, 0, 12288000, 0 },
|
||||
{ 22579200, 1, 0, 0, 0, 0, 0, 0, 22579200, 0 },
|
||||
{ 24000000, 1, 0, 0, 0, 0, 0, 0, 24000000, 0 },
|
||||
{ 24576000, 1, 0, 0, 0, 0, 0, 0, 24576000, 0 }
|
||||
{ 1536000, 0, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125, 2},
|
||||
{ 2304000, 0, 1, 0x00, 0x55, 0xC00000, 0x02, 0x10, 12288000, 85, 2},
|
||||
{ 2400000, 0, 1, 0x00, 0x50, 0x000000, 0x03, 0x10, 12000000, 80, 2},
|
||||
{ 2822400, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
|
||||
{ 3000000, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
|
||||
{ 3072000, 0, 1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1},
|
||||
{ 4000000, 0, 1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000, 96, 1},
|
||||
{ 4096000, 0, 1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000, 94, 1},
|
||||
{ 5644800, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
|
||||
{ 6000000, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
|
||||
{ 6144000, 0, 1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1},
|
||||
{ 11289600, 0, 0, 0, 0, 0, 0, 0, 11289600, 0, 1},
|
||||
{ 12000000, 0, 0, 0, 0, 0, 0, 0, 12000000, 0, 1},
|
||||
{ 12288000, 0, 0, 0, 0, 0, 0, 0, 12288000, 0, 1},
|
||||
{ 22579200, 1, 0, 0, 0, 0, 0, 0, 22579200, 0, 1},
|
||||
{ 24000000, 1, 0, 0, 0, 0, 0, 0, 24000000, 0, 1},
|
||||
{ 24576000, 1, 0, 0, 0, 0, 0, 0, 24576000, 0, 1}
|
||||
};
|
||||
|
||||
static int cs42l42_pll_config(struct snd_soc_component *component)
|
||||
@ -738,8 +749,12 @@ static int cs42l42_pll_config(struct snd_soc_component *component)
|
||||
snd_soc_component_update_bits(component,
|
||||
CS42L42_PLL_CTL3,
|
||||
CS42L42_PLL_DIVOUT_MASK,
|
||||
pll_ratio_table[i].pll_divout
|
||||
(pll_ratio_table[i].pll_divout * pll_ratio_table[i].n)
|
||||
<< CS42L42_PLL_DIVOUT_SHIFT);
|
||||
if (pll_ratio_table[i].n != 1)
|
||||
cs42l42->pll_divout = pll_ratio_table[i].pll_divout;
|
||||
else
|
||||
cs42l42->pll_divout = 0;
|
||||
snd_soc_component_update_bits(component,
|
||||
CS42L42_PLL_CAL_RATIO,
|
||||
CS42L42_PLL_CAL_RATIO_MASK,
|
||||
@ -894,6 +909,16 @@ static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
|
||||
if ((cs42l42->bclk < 11289600) && (cs42l42->sclk < 11289600)) {
|
||||
snd_soc_component_update_bits(component, CS42L42_PLL_CTL1,
|
||||
CS42L42_PLL_START_MASK, 1);
|
||||
|
||||
if (cs42l42->pll_divout) {
|
||||
usleep_range(CS42L42_PLL_DIVOUT_TIME_US,
|
||||
CS42L42_PLL_DIVOUT_TIME_US * 2);
|
||||
snd_soc_component_update_bits(component, CS42L42_PLL_CTL3,
|
||||
CS42L42_PLL_DIVOUT_MASK,
|
||||
cs42l42->pll_divout <<
|
||||
CS42L42_PLL_DIVOUT_SHIFT);
|
||||
}
|
||||
|
||||
ret = regmap_read_poll_timeout(cs42l42->regmap,
|
||||
CS42L42_PLL_LOCK_STATUS,
|
||||
regval,
|
||||
@ -1028,7 +1053,7 @@ static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42)
|
||||
CS42L42_AUTO_HSBIAS_HIZ_MASK |
|
||||
CS42L42_TIP_SENSE_EN_MASK |
|
||||
CS42L42_HSBIAS_SENSE_TRIP_MASK,
|
||||
(1 << CS42L42_HSBIAS_SENSE_EN_SHIFT) |
|
||||
(cs42l42->hs_bias_sense_en << CS42L42_HSBIAS_SENSE_EN_SHIFT) |
|
||||
(1 << CS42L42_AUTO_HSBIAS_HIZ_SHIFT) |
|
||||
(0 << CS42L42_TIP_SENSE_EN_SHIFT) |
|
||||
(3 << CS42L42_HSBIAS_SENSE_TRIP_SHIFT));
|
||||
@ -1413,11 +1438,11 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
|
||||
switch(cs42l42->hs_type){
|
||||
case CS42L42_PLUG_CTIA:
|
||||
case CS42L42_PLUG_OMTP:
|
||||
snd_soc_jack_report(&cs42l42->jack, SND_JACK_HEADSET,
|
||||
snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADSET,
|
||||
SND_JACK_HEADSET);
|
||||
break;
|
||||
case CS42L42_PLUG_HEADPHONE:
|
||||
snd_soc_jack_report(&cs42l42->jack, SND_JACK_HEADPHONE,
|
||||
snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADPHONE,
|
||||
SND_JACK_HEADPHONE);
|
||||
break;
|
||||
default:
|
||||
@ -1445,14 +1470,18 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
|
||||
switch(cs42l42->hs_type){
|
||||
case CS42L42_PLUG_CTIA:
|
||||
case CS42L42_PLUG_OMTP:
|
||||
snd_soc_jack_report(&cs42l42->jack, 0, SND_JACK_HEADSET);
|
||||
snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADSET);
|
||||
break;
|
||||
case CS42L42_PLUG_HEADPHONE:
|
||||
snd_soc_jack_report(&cs42l42->jack, 0, SND_JACK_HEADPHONE);
|
||||
snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADPHONE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
snd_soc_jack_report(cs42l42->jack, 0,
|
||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
SND_JACK_BTN_2 | SND_JACK_BTN_3);
|
||||
|
||||
dev_dbg(component->dev, "Unplug event\n");
|
||||
}
|
||||
break;
|
||||
@ -1464,7 +1493,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
|
||||
}
|
||||
|
||||
/* Check button detect status */
|
||||
if ((~masks[7]) & irq_params_table[7].mask) {
|
||||
if (cs42l42->plug_state == CS42L42_TS_PLUG && ((~masks[7]) & irq_params_table[7].mask)) {
|
||||
if (!(current_button_status &
|
||||
CS42L42_M_HSBIAS_HIZ_MASK)) {
|
||||
|
||||
@ -1475,7 +1504,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data)
|
||||
report = cs42l42_handle_button_press(cs42l42);
|
||||
|
||||
}
|
||||
snd_soc_jack_report(&cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
snd_soc_jack_report(cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
SND_JACK_BTN_2 | SND_JACK_BTN_3);
|
||||
}
|
||||
}
|
||||
@ -1582,8 +1611,8 @@ static void cs42l42_set_interrupt_masks(struct cs42l42_private *cs42l42)
|
||||
CS42L42_TS_UNPLUG_MASK,
|
||||
(1 << CS42L42_RS_PLUG_SHIFT) |
|
||||
(1 << CS42L42_RS_UNPLUG_SHIFT) |
|
||||
(0 << CS42L42_TS_PLUG_SHIFT) |
|
||||
(0 << CS42L42_TS_UNPLUG_SHIFT));
|
||||
(1 << CS42L42_TS_PLUG_SHIFT) |
|
||||
(1 << CS42L42_TS_UNPLUG_SHIFT));
|
||||
}
|
||||
|
||||
static void cs42l42_setup_hs_type_detect(struct cs42l42_private *cs42l42)
|
||||
@ -1633,17 +1662,15 @@ static const unsigned int threshold_defaults[] = {
|
||||
CS42L42_HS_DET_LEVEL_1
|
||||
};
|
||||
|
||||
static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
|
||||
static int cs42l42_handle_device_data(struct device *dev,
|
||||
struct cs42l42_private *cs42l42)
|
||||
{
|
||||
struct device_node *np = i2c_client->dev.of_node;
|
||||
unsigned int val;
|
||||
unsigned int thresholds[CS42L42_NUM_BIASES];
|
||||
u32 thresholds[CS42L42_NUM_BIASES];
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = of_property_read_u32(np, "cirrus,ts-inv", &val);
|
||||
|
||||
ret = device_property_read_u32(dev, "cirrus,ts-inv", &val);
|
||||
if (!ret) {
|
||||
switch (val) {
|
||||
case CS42L42_TS_INV_EN:
|
||||
@ -1651,7 +1678,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
|
||||
cs42l42->ts_inv = val;
|
||||
break;
|
||||
default:
|
||||
dev_err(&i2c_client->dev,
|
||||
dev_err(dev,
|
||||
"Wrong cirrus,ts-inv DT value %d\n",
|
||||
val);
|
||||
cs42l42->ts_inv = CS42L42_TS_INV_DIS;
|
||||
@ -1664,8 +1691,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
|
||||
CS42L42_TS_INV_MASK,
|
||||
(cs42l42->ts_inv << CS42L42_TS_INV_SHIFT));
|
||||
|
||||
ret = of_property_read_u32(np, "cirrus,ts-dbnc-rise", &val);
|
||||
|
||||
ret = device_property_read_u32(dev, "cirrus,ts-dbnc-rise", &val);
|
||||
if (!ret) {
|
||||
switch (val) {
|
||||
case CS42L42_TS_DBNCE_0:
|
||||
@ -1679,7 +1705,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
|
||||
cs42l42->ts_dbnc_rise = val;
|
||||
break;
|
||||
default:
|
||||
dev_err(&i2c_client->dev,
|
||||
dev_err(dev,
|
||||
"Wrong cirrus,ts-dbnc-rise DT value %d\n",
|
||||
val);
|
||||
cs42l42->ts_dbnc_rise = CS42L42_TS_DBNCE_1000;
|
||||
@ -1693,8 +1719,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
|
||||
(cs42l42->ts_dbnc_rise <<
|
||||
CS42L42_TS_RISE_DBNCE_TIME_SHIFT));
|
||||
|
||||
ret = of_property_read_u32(np, "cirrus,ts-dbnc-fall", &val);
|
||||
|
||||
ret = device_property_read_u32(dev, "cirrus,ts-dbnc-fall", &val);
|
||||
if (!ret) {
|
||||
switch (val) {
|
||||
case CS42L42_TS_DBNCE_0:
|
||||
@ -1708,7 +1733,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
|
||||
cs42l42->ts_dbnc_fall = val;
|
||||
break;
|
||||
default:
|
||||
dev_err(&i2c_client->dev,
|
||||
dev_err(dev,
|
||||
"Wrong cirrus,ts-dbnc-fall DT value %d\n",
|
||||
val);
|
||||
cs42l42->ts_dbnc_fall = CS42L42_TS_DBNCE_0;
|
||||
@ -1722,13 +1747,12 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
|
||||
(cs42l42->ts_dbnc_fall <<
|
||||
CS42L42_TS_FALL_DBNCE_TIME_SHIFT));
|
||||
|
||||
ret = of_property_read_u32(np, "cirrus,btn-det-init-dbnce", &val);
|
||||
|
||||
ret = device_property_read_u32(dev, "cirrus,btn-det-init-dbnce", &val);
|
||||
if (!ret) {
|
||||
if (val <= CS42L42_BTN_DET_INIT_DBNCE_MAX)
|
||||
cs42l42->btn_det_init_dbnce = val;
|
||||
else {
|
||||
dev_err(&i2c_client->dev,
|
||||
dev_err(dev,
|
||||
"Wrong cirrus,btn-det-init-dbnce DT value %d\n",
|
||||
val);
|
||||
cs42l42->btn_det_init_dbnce =
|
||||
@ -1739,14 +1763,13 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
|
||||
CS42L42_BTN_DET_INIT_DBNCE_DEFAULT;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np, "cirrus,btn-det-event-dbnce", &val);
|
||||
|
||||
ret = device_property_read_u32(dev, "cirrus,btn-det-event-dbnce", &val);
|
||||
if (!ret) {
|
||||
if (val <= CS42L42_BTN_DET_EVENT_DBNCE_MAX)
|
||||
cs42l42->btn_det_event_dbnce = val;
|
||||
else {
|
||||
dev_err(&i2c_client->dev,
|
||||
"Wrong cirrus,btn-det-event-dbnce DT value %d\n", val);
|
||||
dev_err(dev,
|
||||
"Wrong cirrus,btn-det-event-dbnce DT value %d\n", val);
|
||||
cs42l42->btn_det_event_dbnce =
|
||||
CS42L42_BTN_DET_EVENT_DBNCE_DEFAULT;
|
||||
}
|
||||
@ -1755,19 +1778,17 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
|
||||
CS42L42_BTN_DET_EVENT_DBNCE_DEFAULT;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32_array(np, "cirrus,bias-lvls",
|
||||
(u32 *)thresholds, CS42L42_NUM_BIASES);
|
||||
|
||||
ret = device_property_read_u32_array(dev, "cirrus,bias-lvls",
|
||||
thresholds, ARRAY_SIZE(thresholds));
|
||||
if (!ret) {
|
||||
for (i = 0; i < CS42L42_NUM_BIASES; i++) {
|
||||
if (thresholds[i] <= CS42L42_HS_DET_LEVEL_MAX)
|
||||
cs42l42->bias_thresholds[i] = thresholds[i];
|
||||
else {
|
||||
dev_err(&i2c_client->dev,
|
||||
"Wrong cirrus,bias-lvls[%d] DT value %d\n", i,
|
||||
dev_err(dev,
|
||||
"Wrong cirrus,bias-lvls[%d] DT value %d\n", i,
|
||||
thresholds[i]);
|
||||
cs42l42->bias_thresholds[i] =
|
||||
threshold_defaults[i];
|
||||
cs42l42->bias_thresholds[i] = threshold_defaults[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1775,8 +1796,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
|
||||
cs42l42->bias_thresholds[i] = threshold_defaults[i];
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np, "cirrus,hs-bias-ramp-rate", &val);
|
||||
|
||||
ret = device_property_read_u32(dev, "cirrus,hs-bias-ramp-rate", &val);
|
||||
if (!ret) {
|
||||
switch (val) {
|
||||
case CS42L42_HSBIAS_RAMP_FAST_RISE_SLOW_FALL:
|
||||
@ -1796,7 +1816,7 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
|
||||
cs42l42->hs_bias_ramp_time = CS42L42_HSBIAS_RAMP_TIME3;
|
||||
break;
|
||||
default:
|
||||
dev_err(&i2c_client->dev,
|
||||
dev_err(dev,
|
||||
"Wrong cirrus,hs-bias-ramp-rate DT value %d\n",
|
||||
val);
|
||||
cs42l42->hs_bias_ramp_rate = CS42L42_HSBIAS_RAMP_SLOW;
|
||||
@ -1812,6 +1832,11 @@ static int cs42l42_handle_device_data(struct i2c_client *i2c_client,
|
||||
(cs42l42->hs_bias_ramp_rate <<
|
||||
CS42L42_HSBIAS_RAMP_SHIFT));
|
||||
|
||||
if (device_property_read_bool(dev, "cirrus,hs-bias-sense-disable"))
|
||||
cs42l42->hs_bias_sense_en = 0;
|
||||
else
|
||||
cs42l42->hs_bias_sense_en = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1819,8 +1844,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct cs42l42_private *cs42l42;
|
||||
int ret, i;
|
||||
unsigned int devid = 0;
|
||||
int ret, i, devid;
|
||||
unsigned int reg;
|
||||
|
||||
cs42l42 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l42_private),
|
||||
@ -1883,14 +1907,12 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client,
|
||||
"Failed to request IRQ: %d\n", ret);
|
||||
|
||||
/* initialize codec */
|
||||
ret = regmap_read(cs42l42->regmap, CS42L42_DEVID_AB, ®);
|
||||
devid = (reg & 0xFF) << 12;
|
||||
|
||||
ret = regmap_read(cs42l42->regmap, CS42L42_DEVID_CD, ®);
|
||||
devid |= (reg & 0xFF) << 4;
|
||||
|
||||
ret = regmap_read(cs42l42->regmap, CS42L42_DEVID_E, ®);
|
||||
devid |= (reg & 0xF0) >> 4;
|
||||
devid = cirrus_read_device_id(cs42l42->regmap, CS42L42_DEVID_AB);
|
||||
if (devid < 0) {
|
||||
ret = devid;
|
||||
dev_err(&i2c_client->dev, "Failed to read device ID: %d\n", ret);
|
||||
goto err_disable;
|
||||
}
|
||||
|
||||
if (devid != CS42L42_CHIP_ID) {
|
||||
ret = -ENODEV;
|
||||
@ -1926,11 +1948,9 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client,
|
||||
(1 << CS42L42_ADC_PDN_SHIFT) |
|
||||
(0 << CS42L42_PDN_ALL_SHIFT));
|
||||
|
||||
if (i2c_client->dev.of_node) {
|
||||
ret = cs42l42_handle_device_data(i2c_client, cs42l42);
|
||||
if (ret != 0)
|
||||
goto err_disable;
|
||||
}
|
||||
ret = cs42l42_handle_device_data(&i2c_client->dev, cs42l42);
|
||||
if (ret != 0)
|
||||
goto err_disable;
|
||||
|
||||
/* Setup headset detection */
|
||||
cs42l42_setup_hs_type_detect(cs42l42);
|
||||
@ -2009,12 +2029,21 @@ static const struct dev_pm_ops cs42l42_runtime_pm = {
|
||||
NULL)
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id cs42l42_of_match[] = {
|
||||
{ .compatible = "cirrus,cs42l42", },
|
||||
{},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cs42l42_of_match);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static const struct acpi_device_id cs42l42_acpi_match[] = {
|
||||
{"10134242", 0,},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, cs42l42_acpi_match);
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id cs42l42_id[] = {
|
||||
{"cs42l42", 0},
|
||||
@ -2027,7 +2056,8 @@ static struct i2c_driver cs42l42_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "cs42l42",
|
||||
.pm = &cs42l42_runtime_pm,
|
||||
.of_match_table = cs42l42_of_match,
|
||||
.of_match_table = of_match_ptr(cs42l42_of_match),
|
||||
.acpi_match_table = ACPI_PTR(cs42l42_acpi_match),
|
||||
},
|
||||
.id_table = cs42l42_id,
|
||||
.probe = cs42l42_i2c_probe,
|
||||
|
@ -755,6 +755,7 @@
|
||||
|
||||
#define CS42L42_NUM_SUPPLIES 5
|
||||
#define CS42L42_BOOT_TIME_US 3000
|
||||
#define CS42L42_PLL_DIVOUT_TIME_US 800
|
||||
#define CS42L42_CLOCK_SWITCH_DELAY_US 150
|
||||
#define CS42L42_PLL_LOCK_POLL_US 250
|
||||
#define CS42L42_PLL_LOCK_TIMEOUT_US 1250
|
||||
@ -773,10 +774,11 @@ struct cs42l42_private {
|
||||
struct regulator_bulk_data supplies[CS42L42_NUM_SUPPLIES];
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct completion pdn_done;
|
||||
struct snd_soc_jack jack;
|
||||
struct snd_soc_jack *jack;
|
||||
int bclk;
|
||||
u32 sclk;
|
||||
u32 srate;
|
||||
u8 pll_divout;
|
||||
u8 plug_state;
|
||||
u8 hs_type;
|
||||
u8 ts_inv;
|
||||
@ -787,6 +789,7 @@ struct cs42l42_private {
|
||||
u8 bias_thresholds[CS42L42_NUM_BIASES];
|
||||
u8 hs_bias_ramp_rate;
|
||||
u8 hs_bias_ramp_time;
|
||||
u8 hs_bias_sense_en;
|
||||
u8 stream_use;
|
||||
};
|
||||
|
||||
|
@ -957,9 +957,8 @@ static int cs42l52_beep_event(struct input_dev *dev, unsigned int type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t cs42l52_beep_set(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
static ssize_t beep_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct cs42l52_private *cs42l52 = dev_get_drvdata(dev);
|
||||
long int time;
|
||||
@ -974,7 +973,7 @@ static ssize_t cs42l52_beep_set(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(beep, 0200, NULL, cs42l52_beep_set);
|
||||
static DEVICE_ATTR_WO(beep);
|
||||
|
||||
static void cs42l52_init_beep(struct snd_soc_component *component)
|
||||
{
|
||||
@ -1093,7 +1092,7 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
|
||||
struct cs42l52_private *cs42l52;
|
||||
struct cs42l52_platform_data *pdata = dev_get_platdata(&i2c_client->dev);
|
||||
int ret;
|
||||
unsigned int devid = 0;
|
||||
unsigned int devid;
|
||||
unsigned int reg;
|
||||
u32 val32;
|
||||
|
||||
@ -1163,6 +1162,11 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
|
||||
ret);
|
||||
|
||||
ret = regmap_read(cs42l52->regmap, CS42L52_CHIP, ®);
|
||||
if (ret) {
|
||||
dev_err(&i2c_client->dev, "Failed to read chip ID: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
devid = reg & CS42L52_CHIP_ID_MASK;
|
||||
if (devid != CS42L52_CHIP_ID) {
|
||||
ret = -ENODEV;
|
||||
@ -1199,11 +1203,8 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
|
||||
CS42L52_IFACE_CTL2_BIAS_LVL,
|
||||
cs42l52->pdata.micbias_lvl);
|
||||
|
||||
ret = devm_snd_soc_register_component(&i2c_client->dev,
|
||||
return devm_snd_soc_register_component(&i2c_client->dev,
|
||||
&soc_component_dev_cs42l52, &cs42l52_dai, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id cs42l52_of_match[] = {
|
||||
|
@ -1021,9 +1021,8 @@ static int cs42l56_beep_event(struct input_dev *dev, unsigned int type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t cs42l56_beep_set(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
static ssize_t beep_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct cs42l56_private *cs42l56 = dev_get_drvdata(dev);
|
||||
long int time;
|
||||
@ -1038,7 +1037,7 @@ static ssize_t cs42l56_beep_set(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(beep, 0200, NULL, cs42l56_beep_set);
|
||||
static DEVICE_ATTR_WO(beep);
|
||||
|
||||
static void cs42l56_init_beep(struct snd_soc_component *component)
|
||||
{
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <sound/tlv.h>
|
||||
#include <sound/cs42l73.h>
|
||||
#include "cs42l73.h"
|
||||
#include "cirrus_legacy.h"
|
||||
|
||||
struct sp_config {
|
||||
u8 spc, mmcc, spfs;
|
||||
@ -1278,8 +1279,7 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client,
|
||||
{
|
||||
struct cs42l73_private *cs42l73;
|
||||
struct cs42l73_platform_data *pdata = dev_get_platdata(&i2c_client->dev);
|
||||
int ret;
|
||||
unsigned int devid = 0;
|
||||
int ret, devid;
|
||||
unsigned int reg;
|
||||
u32 val32;
|
||||
|
||||
@ -1329,27 +1329,25 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client,
|
||||
}
|
||||
|
||||
/* initialize codec */
|
||||
ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, ®);
|
||||
devid = (reg & 0xFF) << 12;
|
||||
|
||||
ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_CD, ®);
|
||||
devid |= (reg & 0xFF) << 4;
|
||||
|
||||
ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_E, ®);
|
||||
devid |= (reg & 0xF0) >> 4;
|
||||
devid = cirrus_read_device_id(cs42l73->regmap, CS42L73_DEVID_AB);
|
||||
if (devid < 0) {
|
||||
ret = devid;
|
||||
dev_err(&i2c_client->dev, "Failed to read device ID: %d\n", ret);
|
||||
goto err_reset;
|
||||
}
|
||||
|
||||
if (devid != CS42L73_DEVID) {
|
||||
ret = -ENODEV;
|
||||
dev_err(&i2c_client->dev,
|
||||
"CS42L73 Device ID (%X). Expected %X\n",
|
||||
devid, CS42L73_DEVID);
|
||||
return ret;
|
||||
goto err_reset;
|
||||
}
|
||||
|
||||
ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_client->dev, "Get Revision ID failed\n");
|
||||
return ret;
|
||||
goto err_reset;
|
||||
}
|
||||
|
||||
dev_info(&i2c_client->dev,
|
||||
@ -1359,8 +1357,14 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client,
|
||||
&soc_component_dev_cs42l73, cs42l73_dai,
|
||||
ARRAY_SIZE(cs42l73_dai));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err_reset;
|
||||
|
||||
return 0;
|
||||
|
||||
err_reset:
|
||||
gpio_set_value_cansleep(cs42l73->pdata.reset_gpio, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id cs42l73_of_match[] = {
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <sound/jack.h>
|
||||
|
||||
#include "cs43130.h"
|
||||
#include "cirrus_legacy.h"
|
||||
|
||||
static const struct reg_default cs43130_reg_defaults[] = {
|
||||
{CS43130_SYS_CLK_CTL_1, 0x06},
|
||||
@ -1671,14 +1672,14 @@ static int cs43130_show_dc(struct device *dev, char *buf, u8 ch)
|
||||
cs43130->hpload_dc[ch]);
|
||||
}
|
||||
|
||||
static ssize_t cs43130_show_dc_l(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static ssize_t hpload_dc_l_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return cs43130_show_dc(dev, buf, HP_LEFT);
|
||||
}
|
||||
|
||||
static ssize_t cs43130_show_dc_r(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static ssize_t hpload_dc_r_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return cs43130_show_dc(dev, buf, HP_RIGHT);
|
||||
}
|
||||
@ -1718,22 +1719,22 @@ static int cs43130_show_ac(struct device *dev, char *buf, u8 ch)
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t cs43130_show_ac_l(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static ssize_t hpload_ac_l_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return cs43130_show_ac(dev, buf, HP_LEFT);
|
||||
}
|
||||
|
||||
static ssize_t cs43130_show_ac_r(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static ssize_t hpload_ac_r_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return cs43130_show_ac(dev, buf, HP_RIGHT);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(hpload_dc_l, 0444, cs43130_show_dc_l, NULL);
|
||||
static DEVICE_ATTR(hpload_dc_r, 0444, cs43130_show_dc_r, NULL);
|
||||
static DEVICE_ATTR(hpload_ac_l, 0444, cs43130_show_ac_l, NULL);
|
||||
static DEVICE_ATTR(hpload_ac_r, 0444, cs43130_show_ac_r, NULL);
|
||||
static DEVICE_ATTR_RO(hpload_dc_l);
|
||||
static DEVICE_ATTR_RO(hpload_dc_r);
|
||||
static DEVICE_ATTR_RO(hpload_ac_l);
|
||||
static DEVICE_ATTR_RO(hpload_ac_r);
|
||||
|
||||
static struct attribute *hpload_attrs[] = {
|
||||
&dev_attr_hpload_dc_l.attr,
|
||||
@ -2422,9 +2423,8 @@ static int cs43130_i2c_probe(struct i2c_client *client,
|
||||
{
|
||||
struct cs43130_private *cs43130;
|
||||
int ret;
|
||||
unsigned int devid = 0;
|
||||
unsigned int reg;
|
||||
int i;
|
||||
int i, devid;
|
||||
|
||||
cs43130 = devm_kzalloc(&client->dev, sizeof(*cs43130), GFP_KERNEL);
|
||||
if (!cs43130)
|
||||
@ -2462,20 +2462,21 @@ static int cs43130_i2c_probe(struct i2c_client *client,
|
||||
|
||||
cs43130->reset_gpio = devm_gpiod_get_optional(&client->dev,
|
||||
"reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(cs43130->reset_gpio))
|
||||
return PTR_ERR(cs43130->reset_gpio);
|
||||
if (IS_ERR(cs43130->reset_gpio)) {
|
||||
ret = PTR_ERR(cs43130->reset_gpio);
|
||||
goto err_supplies;
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(cs43130->reset_gpio, 1);
|
||||
|
||||
usleep_range(2000, 2050);
|
||||
|
||||
ret = regmap_read(cs43130->regmap, CS43130_DEVID_AB, ®);
|
||||
|
||||
devid = (reg & 0xFF) << 12;
|
||||
ret = regmap_read(cs43130->regmap, CS43130_DEVID_CD, ®);
|
||||
devid |= (reg & 0xFF) << 4;
|
||||
ret = regmap_read(cs43130->regmap, CS43130_DEVID_E, ®);
|
||||
devid |= (reg & 0xF0) >> 4;
|
||||
devid = cirrus_read_device_id(cs43130->regmap, CS43130_DEVID_AB);
|
||||
if (devid < 0) {
|
||||
ret = devid;
|
||||
dev_err(&client->dev, "Failed to read device ID: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch (devid) {
|
||||
case CS43130_CHIP_ID:
|
||||
@ -2515,7 +2516,7 @@ static int cs43130_i2c_probe(struct i2c_client *client,
|
||||
"cs43130", cs43130);
|
||||
if (ret != 0) {
|
||||
dev_err(&client->dev, "Failed to request IRQ: %d\n", ret);
|
||||
return ret;
|
||||
goto err;
|
||||
}
|
||||
|
||||
cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO;
|
||||
@ -2574,7 +2575,13 @@ static int cs43130_i2c_probe(struct i2c_client *client,
|
||||
CS43130_XSP_3ST_MASK, 0);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
gpiod_set_value_cansleep(cs43130->reset_gpio, 0);
|
||||
err_supplies:
|
||||
regulator_bulk_disable(ARRAY_SIZE(cs43130->supplies),
|
||||
cs43130->supplies);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1178,7 +1178,7 @@ static unsigned int cs47l24_digital_vu[] = {
|
||||
ARIZONA_DAC_DIGITAL_VOLUME_4L,
|
||||
};
|
||||
|
||||
static struct snd_compress_ops cs47l24_compress_ops = {
|
||||
static const struct snd_compress_ops cs47l24_compress_ops = {
|
||||
.open = cs47l24_open,
|
||||
.free = wm_adsp_compr_free,
|
||||
.set_params = wm_adsp_compr_set_params,
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <sound/tlv.h>
|
||||
|
||||
#include "cs53l30.h"
|
||||
#include "cirrus_legacy.h"
|
||||
|
||||
#define CS53L30_NUM_SUPPLIES 2
|
||||
static const char *const cs53l30_supply_names[CS53L30_NUM_SUPPLIES] = {
|
||||
@ -923,9 +924,8 @@ static int cs53l30_i2c_probe(struct i2c_client *client,
|
||||
const struct device_node *np = client->dev.of_node;
|
||||
struct device *dev = &client->dev;
|
||||
struct cs53l30_private *cs53l30;
|
||||
unsigned int devid = 0;
|
||||
unsigned int reg;
|
||||
int ret = 0, i;
|
||||
int ret = 0, i, devid;
|
||||
u8 val;
|
||||
|
||||
cs53l30 = devm_kzalloc(dev, sizeof(*cs53l30), GFP_KERNEL);
|
||||
@ -954,7 +954,7 @@ static int cs53l30_i2c_probe(struct i2c_client *client,
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(cs53l30->reset_gpio)) {
|
||||
ret = PTR_ERR(cs53l30->reset_gpio);
|
||||
goto error;
|
||||
goto error_supplies;
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(cs53l30->reset_gpio, 1);
|
||||
@ -971,14 +971,12 @@ static int cs53l30_i2c_probe(struct i2c_client *client,
|
||||
}
|
||||
|
||||
/* Initialize codec */
|
||||
ret = regmap_read(cs53l30->regmap, CS53L30_DEVID_AB, ®);
|
||||
devid = reg << 12;
|
||||
|
||||
ret = regmap_read(cs53l30->regmap, CS53L30_DEVID_CD, ®);
|
||||
devid |= reg << 4;
|
||||
|
||||
ret = regmap_read(cs53l30->regmap, CS53L30_DEVID_E, ®);
|
||||
devid |= (reg & 0xF0) >> 4;
|
||||
devid = cirrus_read_device_id(cs53l30->regmap, CS53L30_DEVID_AB);
|
||||
if (devid < 0) {
|
||||
ret = devid;
|
||||
dev_err(dev, "Failed to read device ID: %d\n", ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (devid != CS53L30_DEVID) {
|
||||
ret = -ENODEV;
|
||||
@ -1040,6 +1038,8 @@ static int cs53l30_i2c_probe(struct i2c_client *client,
|
||||
return 0;
|
||||
|
||||
error:
|
||||
gpiod_set_value_cansleep(cs53l30->reset_gpio, 0);
|
||||
error_supplies:
|
||||
regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies),
|
||||
cs53l30->supplies);
|
||||
return ret;
|
||||
|
@ -277,6 +277,7 @@ struct hdmi_codec_priv {
|
||||
bool busy;
|
||||
struct snd_soc_jack *jack;
|
||||
unsigned int jack_status;
|
||||
u8 iec_status[5];
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget hdmi_widgets[] = {
|
||||
@ -385,6 +386,47 @@ static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_codec_iec958_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
|
||||
uinfo->count = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_codec_iec958_default_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
|
||||
|
||||
memcpy(ucontrol->value.iec958.status, hcp->iec_status,
|
||||
sizeof(hcp->iec_status));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_codec_iec958_default_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
|
||||
|
||||
memcpy(hcp->iec_status, ucontrol->value.iec958.status,
|
||||
sizeof(hcp->iec_status));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_codec_iec958_mask_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
memset(ucontrol->value.iec958.status, 0xff,
|
||||
sizeof_field(struct hdmi_codec_priv, iec_status));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_codec_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
@ -439,6 +481,42 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
|
||||
mutex_unlock(&hcp->lock);
|
||||
}
|
||||
|
||||
static int hdmi_codec_fill_codec_params(struct snd_soc_dai *dai,
|
||||
unsigned int sample_width,
|
||||
unsigned int sample_rate,
|
||||
unsigned int channels,
|
||||
struct hdmi_codec_params *hp)
|
||||
{
|
||||
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
|
||||
int idx;
|
||||
|
||||
/* Select a channel allocation that matches with ELD and pcm channels */
|
||||
idx = hdmi_codec_get_ch_alloc_table_idx(hcp, channels);
|
||||
if (idx < 0) {
|
||||
dev_err(dai->dev, "Not able to map channels to speakers (%d)\n",
|
||||
idx);
|
||||
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
|
||||
return idx;
|
||||
}
|
||||
|
||||
memset(hp, 0, sizeof(*hp));
|
||||
|
||||
hdmi_audio_infoframe_init(&hp->cea);
|
||||
hp->cea.channels = channels;
|
||||
hp->cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
|
||||
hp->cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
|
||||
hp->cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
|
||||
hp->cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
|
||||
|
||||
hp->sample_width = sample_width;
|
||||
hp->sample_rate = sample_rate;
|
||||
hp->channels = channels;
|
||||
|
||||
hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
@ -453,46 +531,73 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
|
||||
.dig_subframe = { 0 },
|
||||
}
|
||||
};
|
||||
int ret, idx;
|
||||
int ret;
|
||||
|
||||
if (!hcp->hcd.ops->hw_params)
|
||||
return 0;
|
||||
|
||||
dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
|
||||
params_width(params), params_rate(params),
|
||||
params_channels(params));
|
||||
|
||||
ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status,
|
||||
sizeof(hp.iec.status));
|
||||
ret = hdmi_codec_fill_codec_params(dai,
|
||||
params_width(params),
|
||||
params_rate(params),
|
||||
params_channels(params),
|
||||
&hp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status));
|
||||
ret = snd_pcm_fill_iec958_consumer_hw_params(params, hp.iec.status,
|
||||
sizeof(hp.iec.status));
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
hdmi_audio_infoframe_init(&hp.cea);
|
||||
hp.cea.channels = params_channels(params);
|
||||
hp.cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
|
||||
hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
|
||||
hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
|
||||
|
||||
/* Select a channel allocation that matches with ELD and pcm channels */
|
||||
idx = hdmi_codec_get_ch_alloc_table_idx(hcp, hp.cea.channels);
|
||||
if (idx < 0) {
|
||||
dev_err(dai->dev, "Not able to map channels to speakers (%d)\n",
|
||||
idx);
|
||||
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
|
||||
return idx;
|
||||
}
|
||||
hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
|
||||
hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
|
||||
|
||||
hp.sample_width = params_width(params);
|
||||
hp.sample_rate = params_rate(params);
|
||||
hp.channels = params_channels(params);
|
||||
|
||||
cf->bit_fmt = params_format(params);
|
||||
return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data,
|
||||
cf, &hp);
|
||||
}
|
||||
|
||||
static int hdmi_codec_prepare(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 snd_pcm_runtime *runtime = substream->runtime;
|
||||
unsigned int channels = runtime->channels;
|
||||
unsigned int width = snd_pcm_format_width(runtime->format);
|
||||
unsigned int rate = runtime->rate;
|
||||
struct hdmi_codec_params hp;
|
||||
int ret;
|
||||
|
||||
if (!hcp->hcd.ops->prepare)
|
||||
return 0;
|
||||
|
||||
dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
|
||||
width, rate, channels);
|
||||
|
||||
ret = hdmi_codec_fill_codec_params(dai, width, rate, channels, &hp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status));
|
||||
ret = snd_pcm_fill_iec958_consumer(runtime, hp.iec.status,
|
||||
sizeof(hp.iec.status));
|
||||
if (ret < 0) {
|
||||
dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cf->bit_fmt = runtime->format;
|
||||
return hcp->hcd.ops->prepare(dai->dev->parent, hcp->hcd.data,
|
||||
cf, &hp);
|
||||
}
|
||||
|
||||
static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai,
|
||||
unsigned int fmt)
|
||||
{
|
||||
@ -580,12 +685,34 @@ static int hdmi_codec_mute(struct snd_soc_dai *dai, int mute, int direction)
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
/*
|
||||
* This driver can select all SND_SOC_DAIFMT_CBx_CFx,
|
||||
* but need to be selected from Sound Card, not be auto selected.
|
||||
* Because it might be used from other driver.
|
||||
* For example,
|
||||
* ${LINUX}/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
|
||||
*/
|
||||
static u64 hdmi_codec_formats =
|
||||
SND_SOC_POSSIBLE_DAIFMT_NB_NF |
|
||||
SND_SOC_POSSIBLE_DAIFMT_NB_IF |
|
||||
SND_SOC_POSSIBLE_DAIFMT_IB_NF |
|
||||
SND_SOC_POSSIBLE_DAIFMT_IB_IF |
|
||||
SND_SOC_POSSIBLE_DAIFMT_I2S |
|
||||
SND_SOC_POSSIBLE_DAIFMT_DSP_A |
|
||||
SND_SOC_POSSIBLE_DAIFMT_DSP_B |
|
||||
SND_SOC_POSSIBLE_DAIFMT_RIGHT_J |
|
||||
SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
|
||||
SND_SOC_POSSIBLE_DAIFMT_AC97;
|
||||
|
||||
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,
|
||||
.prepare = hdmi_codec_prepare,
|
||||
.set_fmt = hdmi_codec_i2s_set_fmt,
|
||||
.mute_stream = hdmi_codec_mute,
|
||||
.auto_selectable_formats = &hdmi_codec_formats,
|
||||
.num_auto_selectable_formats = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = {
|
||||
@ -620,21 +747,37 @@ static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = {
|
||||
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\
|
||||
SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
|
||||
|
||||
static struct snd_kcontrol_new hdmi_codec_controls[] = {
|
||||
{
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ,
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
|
||||
.info = hdmi_codec_iec958_info,
|
||||
.get = hdmi_codec_iec958_mask_get,
|
||||
},
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
|
||||
.info = hdmi_codec_iec958_info,
|
||||
.get = hdmi_codec_iec958_default_get,
|
||||
.put = hdmi_codec_iec958_default_put,
|
||||
},
|
||||
{
|
||||
.access = (SNDRV_CTL_ELEM_ACCESS_READ |
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE),
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = "ELD",
|
||||
.info = hdmi_eld_ctl_info,
|
||||
.get = hdmi_eld_ctl_get,
|
||||
},
|
||||
};
|
||||
|
||||
static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_dai_driver *drv = dai->driver;
|
||||
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
|
||||
struct snd_kcontrol *kctl;
|
||||
struct snd_kcontrol_new hdmi_eld_ctl = {
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ |
|
||||
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = "ELD",
|
||||
.info = hdmi_eld_ctl_info,
|
||||
.get = hdmi_eld_ctl_get,
|
||||
.device = rtd->pcm->device,
|
||||
};
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK,
|
||||
@ -651,12 +794,21 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
|
||||
hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
|
||||
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
|
||||
|
||||
/* add ELD ctl with the device number corresponding to the PCM stream */
|
||||
kctl = snd_ctl_new1(&hdmi_eld_ctl, dai->component);
|
||||
if (!kctl)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < ARRAY_SIZE(hdmi_codec_controls); i++) {
|
||||
struct snd_kcontrol *kctl;
|
||||
|
||||
return snd_ctl_add(rtd->card->snd_card, kctl);
|
||||
/* add ELD ctl with the device number corresponding to the PCM stream */
|
||||
kctl = snd_ctl_new1(&hdmi_codec_controls[i], dai->component);
|
||||
if (!kctl)
|
||||
return -ENOMEM;
|
||||
|
||||
kctl->id.device = rtd->pcm->device;
|
||||
ret = snd_ctl_add(rtd->card->snd_card, kctl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_dai_probe(struct snd_soc_dai *dai)
|
||||
@ -849,7 +1001,8 @@ static int hdmi_codec_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
dai_count = hcd->i2s + hcd->spdif;
|
||||
if (dai_count < 1 || !hcd->ops || !hcd->ops->hw_params ||
|
||||
if (dai_count < 1 || !hcd->ops ||
|
||||
(!hcd->ops->hw_params && !hcd->ops->prepare) ||
|
||||
!hcd->ops->audio_shutdown) {
|
||||
dev_err(dev, "%s: Invalid parameters\n", __func__);
|
||||
return -EINVAL;
|
||||
@ -862,6 +1015,11 @@ static int hdmi_codec_probe(struct platform_device *pdev)
|
||||
hcp->hcd = *hcd;
|
||||
mutex_init(&hcp->lock);
|
||||
|
||||
ret = snd_pcm_create_iec958_consumer_default(hcp->iec_status,
|
||||
sizeof(hcp->iec_status));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
daidrv = devm_kcalloc(dev, dai_count, sizeof(*daidrv), GFP_KERNEL);
|
||||
if (!daidrv)
|
||||
return -ENOMEM;
|
||||
|
@ -2628,7 +2628,7 @@ static int rx_macro_enable_rx_path_clk(struct snd_soc_dapm_widget *w,
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1727,6 +1727,10 @@ static int wsa_macro_enable_echo(struct snd_soc_dapm_widget *w,
|
||||
val = val & CDC_WSA_RX_MIX_TX1_SEL_MASK;
|
||||
ec_tx = (val >> CDC_WSA_RX_MIX_TX1_SEL_SHFT) - 1;
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "%s: Invalid shift %u\n",
|
||||
__func__, w->shift);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (wsa->ec_hq[ec_tx]) {
|
||||
|
@ -414,7 +414,7 @@ static void mt6359_accdet_work(struct work_struct *work)
|
||||
|
||||
static void mt6359_accdet_jd_work(struct work_struct *work)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret;
|
||||
unsigned int value = 0;
|
||||
|
||||
struct mt6359_accdet *priv =
|
||||
|
@ -271,7 +271,7 @@ static void hp_aux_feedback_loop_gain_ramp(struct mt6359_priv *priv, bool up)
|
||||
|
||||
static void hp_in_pair_current(struct mt6359_priv *priv, bool increase)
|
||||
{
|
||||
int i = 0, stage = 0;
|
||||
int i, stage;
|
||||
int target = 0x3;
|
||||
|
||||
/* Set input diff pair bias select (Hi-Fi mode) */
|
||||
|
@ -573,6 +573,30 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 pcm3168a_dai_formats[] = {
|
||||
/*
|
||||
* Select below from Sound Card, not here
|
||||
* SND_SOC_DAIFMT_CBC_CFC
|
||||
* SND_SOC_DAIFMT_CBP_CFP
|
||||
*/
|
||||
|
||||
/*
|
||||
* First Priority
|
||||
*/
|
||||
SND_SOC_POSSIBLE_DAIFMT_I2S |
|
||||
SND_SOC_POSSIBLE_DAIFMT_LEFT_J,
|
||||
/*
|
||||
* Second Priority
|
||||
*
|
||||
* These have picky limitation.
|
||||
* see
|
||||
* pcm3168a_hw_params()
|
||||
*/
|
||||
SND_SOC_POSSIBLE_DAIFMT_RIGHT_J |
|
||||
SND_SOC_POSSIBLE_DAIFMT_DSP_A |
|
||||
SND_SOC_POSSIBLE_DAIFMT_DSP_B,
|
||||
};
|
||||
|
||||
static const struct snd_soc_dai_ops pcm3168a_dai_ops = {
|
||||
.set_fmt = pcm3168a_set_dai_fmt,
|
||||
.set_sysclk = pcm3168a_set_dai_sysclk,
|
||||
@ -580,6 +604,8 @@ static const struct snd_soc_dai_ops pcm3168a_dai_ops = {
|
||||
.mute_stream = pcm3168a_mute,
|
||||
.set_tdm_slot = pcm3168a_set_tdm_slot,
|
||||
.no_capture_mute = 1,
|
||||
.auto_selectable_formats = pcm3168a_dai_formats,
|
||||
.num_auto_selectable_formats = ARRAY_SIZE(pcm3168a_dai_formats),
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver pcm3168a_dais[] = {
|
||||
|
@ -474,7 +474,8 @@ static int rk3328_platform_probe(struct platform_device *pdev)
|
||||
rk3328->pclk = devm_clk_get(&pdev->dev, "pclk");
|
||||
if (IS_ERR(rk3328->pclk)) {
|
||||
dev_err(&pdev->dev, "can't get acodec pclk\n");
|
||||
return PTR_ERR(rk3328->pclk);
|
||||
ret = PTR_ERR(rk3328->pclk);
|
||||
goto err_unprepare_mclk;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(rk3328->pclk);
|
||||
@ -484,19 +485,34 @@ static int rk3328_platform_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
if (IS_ERR(base)) {
|
||||
ret = PTR_ERR(base);
|
||||
goto err_unprepare_pclk;
|
||||
}
|
||||
|
||||
rk3328->regmap = devm_regmap_init_mmio(&pdev->dev, base,
|
||||
&rk3328_codec_regmap_config);
|
||||
if (IS_ERR(rk3328->regmap))
|
||||
return PTR_ERR(rk3328->regmap);
|
||||
if (IS_ERR(rk3328->regmap)) {
|
||||
ret = PTR_ERR(rk3328->regmap);
|
||||
goto err_unprepare_pclk;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, rk3328);
|
||||
|
||||
return devm_snd_soc_register_component(&pdev->dev, &soc_codec_rk3328,
|
||||
ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_rk3328,
|
||||
rk3328_dai,
|
||||
ARRAY_SIZE(rk3328_dai));
|
||||
if (ret)
|
||||
goto err_unprepare_pclk;
|
||||
|
||||
return 0;
|
||||
|
||||
err_unprepare_pclk:
|
||||
clk_disable_unprepare(rk3328->pclk);
|
||||
|
||||
err_unprepare_mclk:
|
||||
clk_disable_unprepare(rk3328->mclk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id rk3328_codec_of_match[] __maybe_unused = {
|
||||
|
541
sound/soc/codecs/rk817_codec.c
Normal file
541
sound/soc/codecs/rk817_codec.c
Normal file
@ -0,0 +1,541 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// rk817 ALSA SoC Audio driver
|
||||
//
|
||||
// Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd All rights reserved.
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mfd/rk808.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/tlv.h>
|
||||
|
||||
struct rk817_codec_priv {
|
||||
struct snd_soc_component *component;
|
||||
struct rk808 *rk808;
|
||||
struct clk *mclk;
|
||||
unsigned int stereo_sysclk;
|
||||
bool mic_in_differential;
|
||||
};
|
||||
|
||||
/*
|
||||
* This sets the codec up with the values defined in the default implementation including the APLL
|
||||
* from the Rockchip vendor kernel. I do not know if these values are universal despite differing
|
||||
* from the default values defined above and taken from the datasheet, or implementation specific.
|
||||
* I don't have another implementation to compare from the Rockchip sources. Hard-coding for now.
|
||||
* Additionally, I do not know according to the documentation the units accepted for the clock
|
||||
* values, so for the moment those are left unvalidated.
|
||||
*/
|
||||
|
||||
static int rk817_init(struct snd_soc_component *component)
|
||||
{
|
||||
struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
snd_soc_component_write(component, RK817_CODEC_DDAC_POPD_DACST, 0x02);
|
||||
snd_soc_component_write(component, RK817_CODEC_DDAC_SR_LMT0, 0x02);
|
||||
snd_soc_component_write(component, RK817_CODEC_DADC_SR_ACL0, 0x02);
|
||||
snd_soc_component_write(component, RK817_CODEC_DTOP_VUCTIME, 0xf4);
|
||||
if (rk817->mic_in_differential) {
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_AMIC_CFG0, MIC_DIFF_MASK,
|
||||
MIC_DIFF_EN);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk817_set_component_pll(struct snd_soc_component *component,
|
||||
int pll_id, int source, unsigned int freq_in,
|
||||
unsigned int freq_out)
|
||||
{
|
||||
/* Set resistor value and charge pump current for PLL. */
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG1, 0x58);
|
||||
/* Set the PLL feedback clock divide value (values not documented). */
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG2, 0x2d);
|
||||
/* Set the PLL pre-divide value (values not documented). */
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG3, 0x0c);
|
||||
/* Set the PLL VCO output clock divide and PLL divided ratio of PLL High Clk (values not
|
||||
* documented).
|
||||
*/
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* DDAC/DADC L/R volume setting
|
||||
* 0db~-95db, 0.375db/step, for example:
|
||||
* 0x00: 0dB
|
||||
* 0xff: -95dB
|
||||
*/
|
||||
|
||||
static const DECLARE_TLV_DB_MINMAX(rk817_vol_tlv, -9500, 0);
|
||||
|
||||
/*
|
||||
* PGA GAIN L/R volume setting
|
||||
* 27db~-18db, 3db/step, for example:
|
||||
* 0x0: -18dB
|
||||
* 0xf: 27dB
|
||||
*/
|
||||
|
||||
static const DECLARE_TLV_DB_MINMAX(rk817_gain_tlv, -1800, 2700);
|
||||
|
||||
static const struct snd_kcontrol_new rk817_volume_controls[] = {
|
||||
SOC_DOUBLE_R_RANGE_TLV("Master Playback Volume", RK817_CODEC_DDAC_VOLL,
|
||||
RK817_CODEC_DDAC_VOLR, 0, 0x00, 0xff, 1, rk817_vol_tlv),
|
||||
SOC_DOUBLE_R_RANGE_TLV("Master Capture Volume", RK817_CODEC_DADC_VOLL,
|
||||
RK817_CODEC_DADC_VOLR, 0, 0x00, 0xff, 1, rk817_vol_tlv),
|
||||
SOC_DOUBLE_TLV("Mic Capture Gain", RK817_CODEC_DMIC_PGA_GAIN, 4, 0, 0xf, 0,
|
||||
rk817_gain_tlv),
|
||||
};
|
||||
|
||||
/* Since the speaker output and L headphone pin are internally the same, make audio path mutually
|
||||
* exclusive with a mux.
|
||||
*/
|
||||
|
||||
static const char *dac_mux_text[] = {
|
||||
"HP",
|
||||
"SPK",
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_VIRT_DECL(dac_enum, dac_mux_text);
|
||||
|
||||
static const struct snd_kcontrol_new dac_mux =
|
||||
SOC_DAPM_ENUM("Playback Mux", dac_enum);
|
||||
|
||||
static const struct snd_soc_dapm_widget rk817_dapm_widgets[] = {
|
||||
|
||||
/* capture/playback common */
|
||||
SND_SOC_DAPM_SUPPLY("LDO Regulator", RK817_CODEC_AREF_RTCFG1, 6, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("IBIAS Block", RK817_CODEC_AREF_RTCFG1, 2, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("VAvg Buffer", RK817_CODEC_AREF_RTCFG1, 1, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("PLL Power", RK817_CODEC_APLL_CFG5, 0, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("I2S TX1 Transfer Start", RK817_CODEC_DI2S_RXCMD_TSD, 5, 0, NULL, 0),
|
||||
|
||||
/* capture path common */
|
||||
SND_SOC_DAPM_SUPPLY("ADC Clock", RK817_CODEC_DTOP_DIGEN_CLKE, 7, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("I2S TX Clock", RK817_CODEC_DTOP_DIGEN_CLKE, 6, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("ADC Channel Enable", RK817_CODEC_DTOP_DIGEN_CLKE, 5, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("I2S TX Channel Enable", RK817_CODEC_DTOP_DIGEN_CLKE, 4, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("MIC Power On", RK817_CODEC_AMIC_CFG0, 6, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("I2S TX3 Transfer Start", RK817_CODEC_DI2S_TXCR3_TXCMD, 7, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("I2S TX3 Right Justified", RK817_CODEC_DI2S_TXCR3_TXCMD, 3, 0, NULL, 0),
|
||||
|
||||
/* capture path L */
|
||||
SND_SOC_DAPM_ADC("ADC L", "Capture", RK817_CODEC_AADC_CFG0, 7, 1),
|
||||
SND_SOC_DAPM_SUPPLY("PGA L Power On", RK817_CODEC_AMIC_CFG0, 5, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Mic Boost L1", RK817_CODEC_AMIC_CFG0, 3, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Mic Boost L2", RK817_CODEC_AMIC_CFG0, 2, 0, NULL, 0),
|
||||
|
||||
/* capture path R */
|
||||
SND_SOC_DAPM_ADC("ADC R", "Capture", RK817_CODEC_AADC_CFG0, 6, 1),
|
||||
SND_SOC_DAPM_SUPPLY("PGA R Power On", RK817_CODEC_AMIC_CFG0, 4, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Mic Boost R1", RK817_CODEC_AMIC_CFG0, 3, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Mic Boost R2", RK817_CODEC_AMIC_CFG0, 3, 0, NULL, 0),
|
||||
|
||||
/* playback path common */
|
||||
SND_SOC_DAPM_SUPPLY("DAC Clock", RK817_CODEC_DTOP_DIGEN_CLKE, 3, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("I2S RX Clock", RK817_CODEC_DTOP_DIGEN_CLKE, 2, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("DAC Channel Enable", RK817_CODEC_DTOP_DIGEN_CLKE, 1, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("I2S RX Channel Enable", RK817_CODEC_DTOP_DIGEN_CLKE, 0, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("DAC Bias", RK817_CODEC_ADAC_CFG1, 3, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("DAC Mute Off", RK817_CODEC_DDAC_MUTE_MIXCTL, 0, 1, NULL, 0),
|
||||
|
||||
/* playback path speaker */
|
||||
SND_SOC_DAPM_SUPPLY("Class D Mode", RK817_CODEC_DDAC_MUTE_MIXCTL, 4, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("High Pass Filter", RK817_CODEC_DDAC_MUTE_MIXCTL, 7, 0, NULL, 0),
|
||||
SND_SOC_DAPM_DAC("SPK DAC", "Playback", RK817_CODEC_ADAC_CFG1, 2, 1),
|
||||
SND_SOC_DAPM_SUPPLY("Enable Class D", RK817_CODEC_ACLASSD_CFG1, 7, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Disable Class D Mute Ramp", RK817_CODEC_ACLASSD_CFG1, 6, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Class D Mute Rate 1", RK817_CODEC_ACLASSD_CFG1, 3, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Class D Mute Rate 2", RK817_CODEC_ACLASSD_CFG1, 2, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Class D OCPP 2", RK817_CODEC_ACLASSD_CFG2, 5, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Class D OCPP 3", RK817_CODEC_ACLASSD_CFG2, 4, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Class D OCPN 2", RK817_CODEC_ACLASSD_CFG2, 1, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Class D OCPN 3", RK817_CODEC_ACLASSD_CFG2, 0, 0, NULL, 0),
|
||||
|
||||
/* playback path headphones */
|
||||
SND_SOC_DAPM_SUPPLY("Headphone Charge Pump", RK817_CODEC_AHP_CP, 4, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Headphone CP Discharge LDO", RK817_CODEC_AHP_CP, 3, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Headphone OStage", RK817_CODEC_AHP_CFG0, 6, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Headphone Pre Amp", RK817_CODEC_AHP_CFG0, 5, 1, NULL, 0),
|
||||
SND_SOC_DAPM_DAC("DAC L", "Playback", RK817_CODEC_ADAC_CFG1, 1, 1),
|
||||
SND_SOC_DAPM_DAC("DAC R", "Playback", RK817_CODEC_ADAC_CFG1, 0, 1),
|
||||
|
||||
/* Mux for input/output path selection */
|
||||
SND_SOC_DAPM_MUX("Playback Mux", SND_SOC_NOPM, 1, 0, &dac_mux),
|
||||
|
||||
/* Pins for Simple Card Bindings */
|
||||
SND_SOC_DAPM_INPUT("MICL"),
|
||||
SND_SOC_DAPM_INPUT("MICR"),
|
||||
SND_SOC_DAPM_OUTPUT("HPOL"),
|
||||
SND_SOC_DAPM_OUTPUT("HPOR"),
|
||||
SND_SOC_DAPM_OUTPUT("SPKO"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route rk817_dapm_routes[] = {
|
||||
|
||||
/* capture path */
|
||||
/* left mic */
|
||||
{"ADC L", NULL, "LDO Regulator"},
|
||||
{"ADC L", NULL, "IBIAS Block"},
|
||||
{"ADC L", NULL, "VAvg Buffer"},
|
||||
{"ADC L", NULL, "PLL Power"},
|
||||
{"ADC L", NULL, "ADC Clock"},
|
||||
{"ADC L", NULL, "I2S TX Clock"},
|
||||
{"ADC L", NULL, "ADC Channel Enable"},
|
||||
{"ADC L", NULL, "I2S TX Channel Enable"},
|
||||
{"ADC L", NULL, "I2S TX1 Transfer Start"},
|
||||
{"MICL", NULL, "MIC Power On"},
|
||||
{"MICL", NULL, "PGA L Power On"},
|
||||
{"MICL", NULL, "Mic Boost L1"},
|
||||
{"MICL", NULL, "Mic Boost L2"},
|
||||
{"MICL", NULL, "I2S TX3 Transfer Start"},
|
||||
{"MICL", NULL, "I2S TX3 Right Justified"},
|
||||
{"ADC L", NULL, "MICL"},
|
||||
|
||||
/* right mic */
|
||||
{"ADC R", NULL, "LDO Regulator"},
|
||||
{"ADC R", NULL, "IBIAS Block"},
|
||||
{"ADC R", NULL, "VAvg Buffer"},
|
||||
{"ADC R", NULL, "PLL Power"},
|
||||
{"ADC R", NULL, "ADC Clock"},
|
||||
{"ADC R", NULL, "I2S TX Clock"},
|
||||
{"ADC R", NULL, "ADC Channel Enable"},
|
||||
{"ADC R", NULL, "I2S TX Channel Enable"},
|
||||
{"ADC R", NULL, "I2S TX1 Transfer Start"},
|
||||
{"MICR", NULL, "MIC Power On"},
|
||||
{"MICR", NULL, "PGA R Power On"},
|
||||
{"MICR", NULL, "Mic Boost R1"},
|
||||
{"MICR", NULL, "Mic Boost R2"},
|
||||
{"MICR", NULL, "I2S TX3 Transfer Start"},
|
||||
{"MICR", NULL, "I2S TX3 Right Justified"},
|
||||
{"ADC R", NULL, "MICR"},
|
||||
|
||||
/* playback path */
|
||||
/* speaker path */
|
||||
{"SPK DAC", NULL, "LDO Regulator"},
|
||||
{"SPK DAC", NULL, "IBIAS Block"},
|
||||
{"SPK DAC", NULL, "VAvg Buffer"},
|
||||
{"SPK DAC", NULL, "PLL Power"},
|
||||
{"SPK DAC", NULL, "I2S TX1 Transfer Start"},
|
||||
{"SPK DAC", NULL, "DAC Clock"},
|
||||
{"SPK DAC", NULL, "I2S RX Clock"},
|
||||
{"SPK DAC", NULL, "DAC Channel Enable"},
|
||||
{"SPK DAC", NULL, "I2S RX Channel Enable"},
|
||||
{"SPK DAC", NULL, "Class D Mode"},
|
||||
{"SPK DAC", NULL, "DAC Bias"},
|
||||
{"SPK DAC", NULL, "DAC Mute Off"},
|
||||
{"SPK DAC", NULL, "Enable Class D"},
|
||||
{"SPK DAC", NULL, "Disable Class D Mute Ramp"},
|
||||
{"SPK DAC", NULL, "Class D Mute Rate 1"},
|
||||
{"SPK DAC", NULL, "Class D Mute Rate 2"},
|
||||
{"SPK DAC", NULL, "Class D OCPP 2"},
|
||||
{"SPK DAC", NULL, "Class D OCPP 3"},
|
||||
{"SPK DAC", NULL, "Class D OCPN 2"},
|
||||
{"SPK DAC", NULL, "Class D OCPN 3"},
|
||||
{"SPK DAC", NULL, "High Pass Filter"},
|
||||
|
||||
/* headphone path L */
|
||||
{"DAC L", NULL, "LDO Regulator"},
|
||||
{"DAC L", NULL, "IBIAS Block"},
|
||||
{"DAC L", NULL, "VAvg Buffer"},
|
||||
{"DAC L", NULL, "PLL Power"},
|
||||
{"DAC L", NULL, "I2S TX1 Transfer Start"},
|
||||
{"DAC L", NULL, "DAC Clock"},
|
||||
{"DAC L", NULL, "I2S RX Clock"},
|
||||
{"DAC L", NULL, "DAC Channel Enable"},
|
||||
{"DAC L", NULL, "I2S RX Channel Enable"},
|
||||
{"DAC L", NULL, "DAC Bias"},
|
||||
{"DAC L", NULL, "DAC Mute Off"},
|
||||
{"DAC L", NULL, "Headphone Charge Pump"},
|
||||
{"DAC L", NULL, "Headphone CP Discharge LDO"},
|
||||
{"DAC L", NULL, "Headphone OStage"},
|
||||
{"DAC L", NULL, "Headphone Pre Amp"},
|
||||
|
||||
/* headphone path R */
|
||||
{"DAC R", NULL, "LDO Regulator"},
|
||||
{"DAC R", NULL, "IBIAS Block"},
|
||||
{"DAC R", NULL, "VAvg Buffer"},
|
||||
{"DAC R", NULL, "PLL Power"},
|
||||
{"DAC R", NULL, "I2S TX1 Transfer Start"},
|
||||
{"DAC R", NULL, "DAC Clock"},
|
||||
{"DAC R", NULL, "I2S RX Clock"},
|
||||
{"DAC R", NULL, "DAC Channel Enable"},
|
||||
{"DAC R", NULL, "I2S RX Channel Enable"},
|
||||
{"DAC R", NULL, "DAC Bias"},
|
||||
{"DAC R", NULL, "DAC Mute Off"},
|
||||
{"DAC R", NULL, "Headphone Charge Pump"},
|
||||
{"DAC R", NULL, "Headphone CP Discharge LDO"},
|
||||
{"DAC R", NULL, "Headphone OStage"},
|
||||
{"DAC R", NULL, "Headphone Pre Amp"},
|
||||
|
||||
/* mux path for output selection */
|
||||
{"Playback Mux", "HP", "DAC L"},
|
||||
{"Playback Mux", "HP", "DAC R"},
|
||||
{"Playback Mux", "SPK", "SPK DAC"},
|
||||
{"SPKO", NULL, "Playback Mux"},
|
||||
{"HPOL", NULL, "Playback Mux"},
|
||||
{"HPOR", NULL, "Playback Mux"},
|
||||
};
|
||||
|
||||
static int rk817_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
||||
int clk_id, unsigned int freq, int dir)
|
||||
{
|
||||
struct snd_soc_component *component = codec_dai->component;
|
||||
struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
rk817->stereo_sysclk = freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk817_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
unsigned int fmt)
|
||||
{
|
||||
struct snd_soc_component *component = codec_dai->component;
|
||||
unsigned int i2s_mst = 0;
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
i2s_mst |= RK817_I2S_MODE_SLV;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBM_CFM:
|
||||
i2s_mst |= RK817_I2S_MODE_MST;
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "%s : set master mask failed!\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DI2S_CKM,
|
||||
RK817_I2S_MODE_MASK, i2s_mst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk817_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;
|
||||
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
snd_soc_component_write(component, RK817_CODEC_DI2S_RXCR2,
|
||||
VDW_RX_16BITS);
|
||||
snd_soc_component_write(component, RK817_CODEC_DI2S_TXCR2,
|
||||
VDW_TX_16BITS);
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
case SNDRV_PCM_FORMAT_S32_LE:
|
||||
snd_soc_component_write(component, RK817_CODEC_DI2S_RXCR2,
|
||||
VDW_RX_24BITS);
|
||||
snd_soc_component_write(component, RK817_CODEC_DI2S_TXCR2,
|
||||
VDW_TX_24BITS);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk817_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
|
||||
if (mute)
|
||||
snd_soc_component_update_bits(component,
|
||||
RK817_CODEC_DDAC_MUTE_MIXCTL,
|
||||
DACMT_MASK, DACMT_ENABLE);
|
||||
else
|
||||
snd_soc_component_update_bits(component,
|
||||
RK817_CODEC_DDAC_MUTE_MIXCTL,
|
||||
DACMT_MASK, DACMT_DISABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define RK817_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\
|
||||
SNDRV_PCM_RATE_16000 | \
|
||||
SNDRV_PCM_RATE_32000 | \
|
||||
SNDRV_PCM_RATE_44100 | \
|
||||
SNDRV_PCM_RATE_48000 | \
|
||||
SNDRV_PCM_RATE_96000)
|
||||
|
||||
#define RK817_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
|
||||
SNDRV_PCM_RATE_16000 | \
|
||||
SNDRV_PCM_RATE_32000 | \
|
||||
SNDRV_PCM_RATE_44100 | \
|
||||
SNDRV_PCM_RATE_48000 | \
|
||||
SNDRV_PCM_RATE_96000)
|
||||
|
||||
#define RK817_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
|
||||
SNDRV_PCM_FMTBIT_S20_3LE |\
|
||||
SNDRV_PCM_FMTBIT_S24_LE |\
|
||||
SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
||||
static const struct snd_soc_dai_ops rk817_dai_ops = {
|
||||
.hw_params = rk817_hw_params,
|
||||
.set_fmt = rk817_set_dai_fmt,
|
||||
.set_sysclk = rk817_set_dai_sysclk,
|
||||
.mute_stream = rk817_digital_mute,
|
||||
.no_capture_mute = 1,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver rk817_dai[] = {
|
||||
{
|
||||
.name = "rk817-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 2,
|
||||
.channels_max = 8,
|
||||
.rates = RK817_PLAYBACK_RATES,
|
||||
.formats = RK817_FORMATS,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = RK817_CAPTURE_RATES,
|
||||
.formats = RK817_FORMATS,
|
||||
},
|
||||
.ops = &rk817_dai_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static int rk817_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component);
|
||||
struct rk808 *rk808 = dev_get_drvdata(component->dev->parent);
|
||||
|
||||
snd_soc_component_init_regmap(component, rk808->regmap);
|
||||
rk817->component = component;
|
||||
|
||||
snd_soc_component_write(component, RK817_CODEC_DTOP_LPT_SRST, 0x40);
|
||||
|
||||
rk817_init(component);
|
||||
|
||||
/* setting initial pll values so that we can continue to leverage simple-audio-card.
|
||||
* The values aren't important since no parameters are used.
|
||||
*/
|
||||
|
||||
snd_soc_component_set_pll(component, 0, 0, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk817_remove(struct snd_soc_component *component)
|
||||
{
|
||||
snd_soc_component_exit_regmap(component);
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver soc_codec_dev_rk817 = {
|
||||
.probe = rk817_probe,
|
||||
.remove = rk817_remove,
|
||||
.idle_bias_on = 1,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
.controls = rk817_volume_controls,
|
||||
.num_controls = ARRAY_SIZE(rk817_volume_controls),
|
||||
.dapm_routes = rk817_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(rk817_dapm_routes),
|
||||
.dapm_widgets = rk817_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(rk817_dapm_widgets),
|
||||
.set_pll = rk817_set_component_pll,
|
||||
};
|
||||
|
||||
static void rk817_codec_parse_dt_property(struct device *dev,
|
||||
struct rk817_codec_priv *rk817)
|
||||
{
|
||||
struct device_node *node;
|
||||
|
||||
node = of_get_child_by_name(dev->parent->of_node, "codec");
|
||||
if (!node) {
|
||||
dev_dbg(dev, "%s() Can not get child: codec\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
rk817->mic_in_differential =
|
||||
of_property_read_bool(node, "rockchip,mic-in-differential");
|
||||
|
||||
of_node_put(node);
|
||||
}
|
||||
|
||||
static int rk817_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
|
||||
struct rk817_codec_priv *rk817_codec_data;
|
||||
int ret;
|
||||
|
||||
rk817_codec_data = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct rk817_codec_priv),
|
||||
GFP_KERNEL);
|
||||
if (!rk817_codec_data)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, rk817_codec_data);
|
||||
|
||||
rk817_codec_data->rk808 = rk808;
|
||||
|
||||
rk817_codec_parse_dt_property(&pdev->dev, rk817_codec_data);
|
||||
|
||||
rk817_codec_data->mclk = clk_get(pdev->dev.parent, "mclk");
|
||||
if (IS_ERR(rk817_codec_data->mclk)) {
|
||||
dev_dbg(&pdev->dev, "Unable to get mclk\n");
|
||||
ret = -ENXIO;
|
||||
goto err_;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(rk817_codec_data->mclk);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "%s() clock prepare error %d\n",
|
||||
__func__, ret);
|
||||
goto err_;
|
||||
}
|
||||
|
||||
ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_rk817,
|
||||
rk817_dai, ARRAY_SIZE(rk817_dai));
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "%s() register codec error %d\n",
|
||||
__func__, ret);
|
||||
goto err_;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk817_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rk817_codec_priv *rk817 = platform_get_drvdata(pdev);
|
||||
|
||||
clk_disable_unprepare(rk817->mclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rk817_codec_driver = {
|
||||
.driver = {
|
||||
.name = "rk817-codec",
|
||||
},
|
||||
.probe = rk817_platform_probe,
|
||||
.remove = rk817_platform_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(rk817_codec_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC RK817 codec driver");
|
||||
MODULE_AUTHOR("binyuan <kevan.lan@rock-chips.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -372,8 +372,8 @@ static int rt1019_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
|
||||
RT1019_AUTO_BITS_SEL_MANU | RT1019_AUTO_CLK_SEL_MANU);
|
||||
snd_soc_component_update_bits(component, RT1019_PLL_1,
|
||||
RT1019_PLL_M_MASK | RT1019_PLL_M_BP_MASK | RT1019_PLL_Q_8_8_MASK,
|
||||
(pll_code.m_bp ? 0 : pll_code.m_code) << RT1019_PLL_M_SFT |
|
||||
pll_code.m_bp << RT1019_PLL_M_BP_SFT |
|
||||
((pll_code.m_bp ? 0 : pll_code.m_code) << RT1019_PLL_M_SFT) |
|
||||
(pll_code.m_bp << RT1019_PLL_M_BP_SFT) |
|
||||
((pll_code.n_code >> 8) & RT1019_PLL_Q_8_8_MASK));
|
||||
snd_soc_component_update_bits(component, RT1019_PLL_2,
|
||||
RT1019_PLL_Q_7_0_MASK, pll_code.n_code & RT1019_PLL_Q_7_0_MASK);
|
||||
@ -522,6 +522,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt1019 = {
|
||||
.num_dapm_widgets = ARRAY_SIZE(rt1019_dapm_widgets),
|
||||
.dapm_routes = rt1019_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(rt1019_dapm_routes),
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static const struct regmap_config rt1019_regmap = {
|
||||
|
@ -725,7 +725,6 @@ static int rt286_hw_params(struct snd_pcm_substream *substream,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
d_len_code = 0;
|
||||
switch (params_width(params)) {
|
||||
/* bit 6:4 Bits per Sample */
|
||||
case 16:
|
||||
|
@ -273,12 +273,23 @@ static void rt5682_i2c_shutdown(struct i2c_client *client)
|
||||
{
|
||||
struct rt5682_priv *rt5682 = i2c_get_clientdata(client);
|
||||
|
||||
disable_irq(client->irq);
|
||||
cancel_delayed_work_sync(&rt5682->jack_detect_work);
|
||||
cancel_delayed_work_sync(&rt5682->jd_check_work);
|
||||
|
||||
rt5682_reset(rt5682);
|
||||
}
|
||||
|
||||
static int rt5682_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct rt5682_priv *rt5682 = i2c_get_clientdata(client);
|
||||
|
||||
rt5682_i2c_shutdown(client);
|
||||
regulator_bulk_disable(ARRAY_SIZE(rt5682->supplies), rt5682->supplies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id rt5682_of_match[] = {
|
||||
{.compatible = "realtek,rt5682i"},
|
||||
{},
|
||||
@ -305,6 +316,7 @@ static struct i2c_driver rt5682_i2c_driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
},
|
||||
.probe = rt5682_i2c_probe,
|
||||
.remove = rt5682_i2c_remove,
|
||||
.shutdown = rt5682_i2c_shutdown,
|
||||
.id_table = rt5682_i2c_id,
|
||||
};
|
||||
|
@ -267,7 +267,9 @@ static const struct reg_default rt711_reg_defaults[] = {
|
||||
{ 0x8393, 0x00 },
|
||||
{ 0x7319, 0x00 },
|
||||
{ 0x8399, 0x00 },
|
||||
{ 0x752008, 0xa807 },
|
||||
{ 0x752009, 0x1029 },
|
||||
{ 0x75200b, 0x7770 },
|
||||
{ 0x752011, 0x007a },
|
||||
{ 0x75201a, 0x8003 },
|
||||
{ 0x752045, 0x5289 },
|
||||
|
@ -389,6 +389,36 @@ static void rt711_jack_init(struct rt711_priv *rt711)
|
||||
RT711_HP_JD_FINAL_RESULT_CTL_JD12,
|
||||
RT711_HP_JD_FINAL_RESULT_CTL_JD12);
|
||||
break;
|
||||
case RT711_JD2_100K:
|
||||
rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
|
||||
RT711_JD_CTL2, RT711_JD2_2PORT_100K_DECODE | RT711_JD2_1PORT_TYPE_DECODE |
|
||||
RT711_HP_JD_SEL_JD2 | RT711_JD1_2PORT_TYPE_100K_DECODE,
|
||||
RT711_JD2_2PORT_100K_DECODE_HP | RT711_JD2_1PORT_JD_HP |
|
||||
RT711_HP_JD_SEL_JD2 | RT711_JD1_2PORT_JD_RESERVED);
|
||||
rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
|
||||
RT711_CC_DET1,
|
||||
RT711_HP_JD_FINAL_RESULT_CTL_JD12,
|
||||
RT711_HP_JD_FINAL_RESULT_CTL_JD12);
|
||||
break;
|
||||
case RT711_JD2_1P8V_1PORT:
|
||||
rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
|
||||
RT711_JD_CTL1, RT711_JD2_DIGITAL_JD_MODE_SEL,
|
||||
RT711_JD2_1_JD_MODE);
|
||||
rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
|
||||
RT711_JD_CTL2, RT711_JD2_1PORT_TYPE_DECODE |
|
||||
RT711_HP_JD_SEL_JD2,
|
||||
RT711_JD2_1PORT_JD_HP |
|
||||
RT711_HP_JD_SEL_JD2);
|
||||
rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
|
||||
RT711_JD_CTL4, RT711_JD2_PAD_PULL_UP_MASK |
|
||||
RT711_JD2_MODE_SEL_MASK,
|
||||
RT711_JD2_PAD_PULL_UP |
|
||||
RT711_JD2_MODE2_1P8V_1PORT);
|
||||
rt711_index_update_bits(rt711->regmap, RT711_VENDOR_REG,
|
||||
RT711_CC_DET1,
|
||||
RT711_HP_JD_FINAL_RESULT_CTL_JD12,
|
||||
RT711_HP_JD_FINAL_RESULT_CTL_JD12);
|
||||
break;
|
||||
default:
|
||||
dev_warn(rt711->component->dev, "Wrong JD source\n");
|
||||
break;
|
||||
|
@ -54,7 +54,9 @@ struct sdw_stream_data {
|
||||
|
||||
/* Index (NID:20h) */
|
||||
#define RT711_DAC_DC_CALI_CTL1 0x00
|
||||
#define RT711_JD_CTL1 0x08
|
||||
#define RT711_JD_CTL2 0x09
|
||||
#define RT711_JD_CTL4 0x0b
|
||||
#define RT711_CC_DET1 0x11
|
||||
#define RT711_PARA_VERB_CTL 0x1a
|
||||
#define RT711_COMBO_JACK_AUTO_CTL1 0x45
|
||||
@ -173,10 +175,33 @@ struct sdw_stream_data {
|
||||
/* DAC DC offset calibration control-1 (0x00)(NID:20h) */
|
||||
#define RT711_DAC_DC_CALI_TRIGGER (0x1 << 15)
|
||||
|
||||
/* jack detect control 1 (0x08)(NID:20h) */
|
||||
#define RT711_JD2_DIGITAL_JD_MODE_SEL (0x1 << 1)
|
||||
#define RT711_JD2_1_JD_MODE (0x0 << 1)
|
||||
#define RT711_JD2_2_JD_MODE (0x1 << 1)
|
||||
|
||||
/* jack detect control 2 (0x09)(NID:20h) */
|
||||
#define RT711_JD2_2PORT_200K_DECODE_HP (0x1 << 13)
|
||||
#define RT711_JD2_2PORT_100K_DECODE (0x1 << 12)
|
||||
#define RT711_JD2_2PORT_100K_DECODE_HP (0x0 << 12)
|
||||
#define RT711_HP_JD_SEL_JD1 (0x0 << 1)
|
||||
#define RT711_HP_JD_SEL_JD2 (0x1 << 1)
|
||||
#define RT711_JD2_1PORT_TYPE_DECODE (0x3 << 10)
|
||||
#define RT711_JD2_1PORT_JD_LINE2 (0x0 << 10)
|
||||
#define RT711_JD2_1PORT_JD_HP (0x1 << 10)
|
||||
#define RT711_JD2_1PORT_JD_LINE1 (0x2 << 10)
|
||||
#define RT711_JD1_2PORT_TYPE_100K_DECODE (0x1 << 0)
|
||||
#define RT711_JD1_2PORT_JD_RESERVED (0x0 << 0)
|
||||
#define RT711_JD1_2PORT_JD_LINE1 (0x1 << 0)
|
||||
|
||||
/* jack detect control 4 (0x0b)(NID:20h) */
|
||||
#define RT711_JD2_PAD_PULL_UP_MASK (0x1 << 3)
|
||||
#define RT711_JD2_PAD_NOT_PULL_UP (0x0 << 3)
|
||||
#define RT711_JD2_PAD_PULL_UP (0x1 << 3)
|
||||
#define RT711_JD2_MODE_SEL_MASK (0x3 << 0)
|
||||
#define RT711_JD2_MODE0_2PORT (0x0 << 0)
|
||||
#define RT711_JD2_MODE1_3P3V_1PORT (0x1 << 0)
|
||||
#define RT711_JD2_MODE2_1P8V_1PORT (0x2 << 0)
|
||||
|
||||
/* CC DET1 (0x11)(NID:20h) */
|
||||
#define RT711_HP_JD_FINAL_RESULT_CTL_JD12 (0x1 << 10)
|
||||
@ -217,7 +242,9 @@ enum {
|
||||
enum rt711_jd_src {
|
||||
RT711_JD_NULL,
|
||||
RT711_JD1,
|
||||
RT711_JD2
|
||||
RT711_JD2,
|
||||
RT711_JD2_100K,
|
||||
RT711_JD2_1P8V_1PORT
|
||||
};
|
||||
|
||||
int rt711_io_init(struct device *dev, struct sdw_slave *slave);
|
||||
|
@ -44,7 +44,6 @@ struct sigmadsp {
|
||||
|
||||
struct sigmadsp *devm_sigmadsp_init(struct device *dev,
|
||||
const struct sigmadsp_ops *ops, const char *firmware_name);
|
||||
void sigmadsp_reset(struct sigmadsp *sigmadsp);
|
||||
|
||||
int sigmadsp_restrict_params(struct sigmadsp *sigmadsp,
|
||||
struct snd_pcm_substream *substream);
|
||||
|
357
sound/soc/codecs/tfa989x.c
Normal file
357
sound/soc/codecs/tfa989x.c
Normal file
@ -0,0 +1,357 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021 Stephan Gerhold
|
||||
*
|
||||
* Register definitions/sequences taken from various tfa98xx kernel drivers:
|
||||
* Copyright (C) 2014-2020 NXP Semiconductors, All Rights Reserved.
|
||||
* Copyright (C) 2013 Sony Mobile Communications Inc.
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#define TFA989X_STATUSREG 0x00
|
||||
#define TFA989X_BATTERYVOLTAGE 0x01
|
||||
#define TFA989X_TEMPERATURE 0x02
|
||||
#define TFA989X_REVISIONNUMBER 0x03
|
||||
#define TFA989X_REVISIONNUMBER_REV_MSK GENMASK(7, 0) /* device revision */
|
||||
#define TFA989X_I2SREG 0x04
|
||||
#define TFA989X_I2SREG_CHSA 6 /* amplifier input select */
|
||||
#define TFA989X_I2SREG_CHSA_MSK GENMASK(7, 6)
|
||||
#define TFA989X_I2SREG_I2SSR 12 /* sample rate */
|
||||
#define TFA989X_I2SREG_I2SSR_MSK GENMASK(15, 12)
|
||||
#define TFA989X_BAT_PROT 0x05
|
||||
#define TFA989X_AUDIO_CTR 0x06
|
||||
#define TFA989X_DCDCBOOST 0x07
|
||||
#define TFA989X_SPKR_CALIBRATION 0x08
|
||||
#define TFA989X_SYS_CTRL 0x09
|
||||
#define TFA989X_SYS_CTRL_PWDN 0 /* power down */
|
||||
#define TFA989X_SYS_CTRL_I2CR 1 /* I2C reset */
|
||||
#define TFA989X_SYS_CTRL_CFE 2 /* enable CoolFlux DSP */
|
||||
#define TFA989X_SYS_CTRL_AMPE 3 /* enable amplifier */
|
||||
#define TFA989X_SYS_CTRL_DCA 4 /* enable boost */
|
||||
#define TFA989X_SYS_CTRL_SBSL 5 /* DSP configured */
|
||||
#define TFA989X_SYS_CTRL_AMPC 6 /* amplifier enabled by DSP */
|
||||
#define TFA989X_I2S_SEL_REG 0x0a
|
||||
#define TFA989X_I2S_SEL_REG_SPKR_MSK GENMASK(10, 9) /* speaker impedance */
|
||||
#define TFA989X_I2S_SEL_REG_DCFG_MSK GENMASK(14, 11) /* DCDC compensation */
|
||||
#define TFA989X_PWM_CONTROL 0x41
|
||||
#define TFA989X_CURRENTSENSE1 0x46
|
||||
#define TFA989X_CURRENTSENSE2 0x47
|
||||
#define TFA989X_CURRENTSENSE3 0x48
|
||||
#define TFA989X_CURRENTSENSE4 0x49
|
||||
|
||||
#define TFA9895_REVISION 0x12
|
||||
#define TFA9897_REVISION 0x97
|
||||
|
||||
struct tfa989x_rev {
|
||||
unsigned int rev;
|
||||
int (*init)(struct regmap *regmap);
|
||||
};
|
||||
|
||||
struct tfa989x {
|
||||
struct regulator *vddd_supply;
|
||||
};
|
||||
|
||||
static bool tfa989x_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
return reg > TFA989X_REVISIONNUMBER;
|
||||
}
|
||||
|
||||
static bool tfa989x_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
return reg < TFA989X_REVISIONNUMBER;
|
||||
}
|
||||
|
||||
static const struct regmap_config tfa989x_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 16,
|
||||
|
||||
.writeable_reg = tfa989x_writeable_reg,
|
||||
.volatile_reg = tfa989x_volatile_reg,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static const char * const chsa_text[] = { "Left", "Right", /* "DSP" */ };
|
||||
static SOC_ENUM_SINGLE_DECL(chsa_enum, TFA989X_I2SREG, TFA989X_I2SREG_CHSA, chsa_text);
|
||||
static const struct snd_kcontrol_new chsa_mux = SOC_DAPM_ENUM("Amp Input", chsa_enum);
|
||||
|
||||
static const struct snd_soc_dapm_widget tfa989x_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_OUTPUT("OUT"),
|
||||
SND_SOC_DAPM_SUPPLY("POWER", TFA989X_SYS_CTRL, TFA989X_SYS_CTRL_PWDN, 1, NULL, 0),
|
||||
SND_SOC_DAPM_OUT_DRV("AMPE", TFA989X_SYS_CTRL, TFA989X_SYS_CTRL_AMPE, 0, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_MUX("Amp Input", SND_SOC_NOPM, 0, 0, &chsa_mux),
|
||||
SND_SOC_DAPM_AIF_IN("AIFINL", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("AIFINR", "HiFi Playback", 1, SND_SOC_NOPM, 0, 0),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route tfa989x_dapm_routes[] = {
|
||||
{"OUT", NULL, "AMPE"},
|
||||
{"AMPE", NULL, "POWER"},
|
||||
{"AMPE", NULL, "Amp Input"},
|
||||
{"Amp Input", "Left", "AIFINL"},
|
||||
{"Amp Input", "Right", "AIFINR"},
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver tfa989x_component = {
|
||||
.dapm_widgets = tfa989x_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(tfa989x_dapm_widgets),
|
||||
.dapm_routes = tfa989x_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(tfa989x_dapm_routes),
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static const unsigned int tfa989x_rates[] = {
|
||||
8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
|
||||
};
|
||||
|
||||
static int tfa989x_find_sample_rate(unsigned int rate)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tfa989x_rates); ++i)
|
||||
if (tfa989x_rates[i] == rate)
|
||||
return i;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int tfa989x_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;
|
||||
int sr;
|
||||
|
||||
sr = tfa989x_find_sample_rate(params_rate(params));
|
||||
if (sr < 0)
|
||||
return sr;
|
||||
|
||||
return snd_soc_component_update_bits(component, TFA989X_I2SREG,
|
||||
TFA989X_I2SREG_I2SSR_MSK,
|
||||
sr << TFA989X_I2SREG_I2SSR);
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops tfa989x_dai_ops = {
|
||||
.hw_params = tfa989x_hw_params,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver tfa989x_dai = {
|
||||
.name = "tfa989x-hifi",
|
||||
.playback = {
|
||||
.stream_name = "HiFi Playback",
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
.rates = SNDRV_PCM_RATE_8000_48000,
|
||||
.rate_min = 8000,
|
||||
.rate_max = 48000,
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
},
|
||||
.ops = &tfa989x_dai_ops,
|
||||
};
|
||||
|
||||
static const struct reg_sequence tfa9895_reg_init[] = {
|
||||
/* some other registers must be set for optimal amplifier behaviour */
|
||||
{ TFA989X_BAT_PROT, 0x13ab },
|
||||
{ TFA989X_AUDIO_CTR, 0x001f },
|
||||
|
||||
/* peak voltage protection is always on, but may be written */
|
||||
{ TFA989X_SPKR_CALIBRATION, 0x3c4e },
|
||||
|
||||
/* TFA989X_SYSCTRL_DCA = 0 */
|
||||
{ TFA989X_SYS_CTRL, 0x024d },
|
||||
{ TFA989X_PWM_CONTROL, 0x0308 },
|
||||
{ TFA989X_CURRENTSENSE4, 0x0e82 },
|
||||
};
|
||||
|
||||
static int tfa9895_init(struct regmap *regmap)
|
||||
{
|
||||
return regmap_multi_reg_write(regmap, tfa9895_reg_init,
|
||||
ARRAY_SIZE(tfa9895_reg_init));
|
||||
}
|
||||
|
||||
static const struct tfa989x_rev tfa9895_rev = {
|
||||
.rev = TFA9895_REVISION,
|
||||
.init = tfa9895_init,
|
||||
};
|
||||
|
||||
static int tfa9897_init(struct regmap *regmap)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Reduce slewrate by clearing iddqtestbst to avoid booster damage */
|
||||
ret = regmap_write(regmap, TFA989X_CURRENTSENSE3, 0x0300);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable clipping */
|
||||
ret = regmap_clear_bits(regmap, TFA989X_CURRENTSENSE4, 0x1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set required TDM configuration */
|
||||
return regmap_write(regmap, 0x14, 0x0);
|
||||
}
|
||||
|
||||
static const struct tfa989x_rev tfa9897_rev = {
|
||||
.rev = TFA9897_REVISION,
|
||||
.init = tfa9897_init,
|
||||
};
|
||||
|
||||
/*
|
||||
* Note: At the moment this driver bypasses the "CoolFlux DSP" built into the
|
||||
* TFA989X amplifiers. Unfortunately, there seems to be absolutely
|
||||
* no documentation for it - the public "short datasheets" do not provide
|
||||
* any information about the DSP or available registers.
|
||||
*
|
||||
* Usually the TFA989X amplifiers are configured through proprietary userspace
|
||||
* libraries. There are also some (rather complex) kernel drivers but even those
|
||||
* rely on obscure firmware blobs for configuration (so-called "containers").
|
||||
* They seem to contain different "profiles" with tuned speaker settings, sample
|
||||
* rates and volume steps (which would be better exposed as separate ALSA mixers).
|
||||
*
|
||||
* Bypassing the DSP disables volume control (and perhaps some speaker
|
||||
* optimization?), but at least allows using the speaker without obscure
|
||||
* kernel drivers and firmware.
|
||||
*
|
||||
* Ideally NXP (or now Goodix) should release proper documentation for these
|
||||
* amplifiers so that support for the "CoolFlux DSP" can be implemented properly.
|
||||
*/
|
||||
static int tfa989x_dsp_bypass(struct regmap *regmap)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Clear CHSA to bypass DSP and take input from I2S 1 left channel */
|
||||
ret = regmap_clear_bits(regmap, TFA989X_I2SREG, TFA989X_I2SREG_CHSA_MSK);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set DCDC compensation to off and speaker impedance to 8 ohm */
|
||||
ret = regmap_update_bits(regmap, TFA989X_I2S_SEL_REG,
|
||||
TFA989X_I2S_SEL_REG_DCFG_MSK |
|
||||
TFA989X_I2S_SEL_REG_SPKR_MSK,
|
||||
TFA989X_I2S_SEL_REG_SPKR_MSK);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set DCDC to follower mode and disable CoolFlux DSP */
|
||||
return regmap_clear_bits(regmap, TFA989X_SYS_CTRL,
|
||||
BIT(TFA989X_SYS_CTRL_DCA) |
|
||||
BIT(TFA989X_SYS_CTRL_CFE) |
|
||||
BIT(TFA989X_SYS_CTRL_AMPC));
|
||||
}
|
||||
|
||||
static void tfa989x_regulator_disable(void *data)
|
||||
{
|
||||
struct tfa989x *tfa989x = data;
|
||||
|
||||
regulator_disable(tfa989x->vddd_supply);
|
||||
}
|
||||
|
||||
static int tfa989x_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct device *dev = &i2c->dev;
|
||||
const struct tfa989x_rev *rev;
|
||||
struct tfa989x *tfa989x;
|
||||
struct regmap *regmap;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
rev = device_get_match_data(dev);
|
||||
if (!rev) {
|
||||
dev_err(dev, "unknown device revision\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
tfa989x = devm_kzalloc(dev, sizeof(*tfa989x), GFP_KERNEL);
|
||||
if (!tfa989x)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(i2c, tfa989x);
|
||||
|
||||
tfa989x->vddd_supply = devm_regulator_get(dev, "vddd");
|
||||
if (IS_ERR(tfa989x->vddd_supply))
|
||||
return dev_err_probe(dev, PTR_ERR(tfa989x->vddd_supply),
|
||||
"Failed to get vddd regulator\n");
|
||||
|
||||
regmap = devm_regmap_init_i2c(i2c, &tfa989x_regmap);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
ret = regulator_enable(tfa989x->vddd_supply);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to enable vddd regulator: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(dev, tfa989x_regulator_disable, tfa989x);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Bypass regcache for reset and init sequence */
|
||||
regcache_cache_bypass(regmap, true);
|
||||
|
||||
/* Dummy read to generate i2c clocks, required on some devices */
|
||||
regmap_read(regmap, TFA989X_REVISIONNUMBER, &val);
|
||||
|
||||
ret = regmap_read(regmap, TFA989X_REVISIONNUMBER, &val);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to read revision number: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
val &= TFA989X_REVISIONNUMBER_REV_MSK;
|
||||
if (val != rev->rev) {
|
||||
dev_err(dev, "invalid revision number, expected %#x, got %#x\n",
|
||||
rev->rev, val);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = regmap_write(regmap, TFA989X_SYS_CTRL, BIT(TFA989X_SYS_CTRL_I2CR));
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to reset I2C registers: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rev->init(regmap);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to initialize registers: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = tfa989x_dsp_bypass(regmap);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable DSP bypass: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
regcache_cache_bypass(regmap, false);
|
||||
|
||||
return devm_snd_soc_register_component(dev, &tfa989x_component,
|
||||
&tfa989x_dai, 1);
|
||||
}
|
||||
|
||||
static const struct of_device_id tfa989x_of_match[] = {
|
||||
{ .compatible = "nxp,tfa9895", .data = &tfa9895_rev },
|
||||
{ .compatible = "nxp,tfa9897", .data = &tfa9897_rev },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tfa989x_of_match);
|
||||
|
||||
static struct i2c_driver tfa989x_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "tfa989x",
|
||||
.of_match_table = tfa989x_of_match,
|
||||
},
|
||||
.probe_new = tfa989x_i2c_probe,
|
||||
};
|
||||
module_i2c_driver(tfa989x_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC NXP/Goodix TFA989X (TFA1) driver");
|
||||
MODULE_AUTHOR("Stephan Gerhold <stephan@gerhold.net>");
|
||||
MODULE_LICENSE("GPL");
|
@ -261,8 +261,8 @@ static const struct snd_kcontrol_new aic26_snd_controls[] = {
|
||||
* SPI device portion of driver: sysfs files for debugging
|
||||
*/
|
||||
|
||||
static ssize_t aic26_keyclick_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static ssize_t keyclick_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct aic26 *aic26 = dev_get_drvdata(dev);
|
||||
int val, amp, freq, len;
|
||||
@ -276,9 +276,9 @@ static ssize_t aic26_keyclick_show(struct device *dev,
|
||||
}
|
||||
|
||||
/* Any write to the keyclick attribute will trigger the keyclick event */
|
||||
static ssize_t aic26_keyclick_set(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
static ssize_t keyclick_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct aic26 *aic26 = dev_get_drvdata(dev);
|
||||
|
||||
@ -288,7 +288,7 @@ static ssize_t aic26_keyclick_set(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
|
||||
static DEVICE_ATTR_RW(keyclick);
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* SoC CODEC portion of driver: probe and release routines
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
#include "tlv320aic32x4.h"
|
||||
|
||||
static const struct of_device_id aic32x4_of_id[];
|
||||
|
||||
static int aic32x4_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
@ -27,6 +29,16 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c,
|
||||
config.val_bits = 8;
|
||||
|
||||
regmap = devm_regmap_init_i2c(i2c, &config);
|
||||
|
||||
if (i2c->dev.of_node) {
|
||||
const struct of_device_id *oid;
|
||||
|
||||
oid = of_match_node(aic32x4_of_id, i2c->dev.of_node);
|
||||
dev_set_drvdata(&i2c->dev, (void *)oid->data);
|
||||
} else if (id) {
|
||||
dev_set_drvdata(&i2c->dev, (void *)id->driver_data);
|
||||
}
|
||||
|
||||
return aic32x4_probe(&i2c->dev, regmap);
|
||||
}
|
||||
|
||||
@ -36,15 +48,17 @@ static int aic32x4_i2c_remove(struct i2c_client *i2c)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id aic32x4_i2c_id[] = {
|
||||
{ "tlv320aic32x4", 0 },
|
||||
{ "tlv320aic32x6", 1 },
|
||||
{ "tlv320aic32x4", (kernel_ulong_t)AIC32X4_TYPE_AIC32X4 },
|
||||
{ "tlv320aic32x6", (kernel_ulong_t)AIC32X4_TYPE_AIC32X6 },
|
||||
{ "tas2505", (kernel_ulong_t)AIC32X4_TYPE_TAS2505 },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id);
|
||||
|
||||
static const struct of_device_id aic32x4_of_id[] = {
|
||||
{ .compatible = "ti,tlv320aic32x4", },
|
||||
{ .compatible = "ti,tlv320aic32x6", },
|
||||
{ .compatible = "ti,tlv320aic32x4", .data = (void *)AIC32X4_TYPE_AIC32X4 },
|
||||
{ .compatible = "ti,tlv320aic32x6", .data = (void *)AIC32X4_TYPE_AIC32X6 },
|
||||
{ .compatible = "ti,tas2505", .data = (void *)AIC32X4_TYPE_TAS2505 },
|
||||
{ /* senitel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, aic32x4_of_id);
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
#include "tlv320aic32x4.h"
|
||||
|
||||
static const struct of_device_id aic32x4_of_id[];
|
||||
|
||||
static int aic32x4_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
@ -28,6 +30,19 @@ static int aic32x4_spi_probe(struct spi_device *spi)
|
||||
config.read_flag_mask = 0x01;
|
||||
|
||||
regmap = devm_regmap_init_spi(spi, &config);
|
||||
|
||||
if (spi->dev.of_node) {
|
||||
const struct of_device_id *oid;
|
||||
|
||||
oid = of_match_node(aic32x4_of_id, spi->dev.of_node);
|
||||
dev_set_drvdata(&spi->dev, (void *)oid->data);
|
||||
} else {
|
||||
const struct spi_device_id *id_entry;
|
||||
|
||||
id_entry = spi_get_device_id(spi);
|
||||
dev_set_drvdata(&spi->dev, (void *)id_entry->driver_data);
|
||||
}
|
||||
|
||||
return aic32x4_probe(&spi->dev, regmap);
|
||||
}
|
||||
|
||||
@ -37,15 +52,15 @@ static int aic32x4_spi_remove(struct spi_device *spi)
|
||||
}
|
||||
|
||||
static const struct spi_device_id aic32x4_spi_id[] = {
|
||||
{ "tlv320aic32x4", 0 },
|
||||
{ "tlv320aic32x6", 1 },
|
||||
{ "tlv320aic32x4", (kernel_ulong_t)AIC32X4_TYPE_AIC32X4 },
|
||||
{ "tlv320aic32x6", (kernel_ulong_t)AIC32X4_TYPE_AIC32X6 },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, aic32x4_spi_id);
|
||||
|
||||
static const struct of_device_id aic32x4_of_id[] = {
|
||||
{ .compatible = "ti,tlv320aic32x4", },
|
||||
{ .compatible = "ti,tlv320aic32x6", },
|
||||
{ .compatible = "ti,tlv320aic32x4", .data = (void *)AIC32X4_TYPE_AIC32X4 },
|
||||
{ .compatible = "ti,tlv320aic32x6", .data = (void *)AIC32X4_TYPE_AIC32X6 },
|
||||
{ /* senitel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, aic32x4_of_id);
|
||||
|
@ -48,6 +48,7 @@ struct aic32x4_priv {
|
||||
|
||||
struct aic32x4_setup_data *setup;
|
||||
struct device *dev;
|
||||
enum aic32x4_type type;
|
||||
};
|
||||
|
||||
static int aic32x4_reset_adc(struct snd_soc_dapm_widget *w,
|
||||
@ -250,6 +251,9 @@ static DECLARE_TLV_DB_SCALE(tlv_driver_gain, -600, 100, 0);
|
||||
/* -12dB min, 0.5dB steps */
|
||||
static DECLARE_TLV_DB_SCALE(tlv_adc_vol, -1200, 50, 0);
|
||||
|
||||
static DECLARE_TLV_DB_LINEAR(tlv_spk_vol, TLV_DB_GAIN_MUTE, 0);
|
||||
static DECLARE_TLV_DB_SCALE(tlv_amp_vol, 0, 600, 1);
|
||||
|
||||
static const char * const lo_cm_text[] = {
|
||||
"Full Chip", "1.65V",
|
||||
};
|
||||
@ -1058,6 +1062,129 @@ static const struct snd_soc_component_driver soc_component_dev_aic32x4 = {
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new aic32x4_tas2505_snd_controls[] = {
|
||||
SOC_DOUBLE_R_S_TLV("PCM Playback Volume", AIC32X4_LDACVOL,
|
||||
AIC32X4_LDACVOL, 0, -0x7f, 0x30, 7, 0, tlv_pcm),
|
||||
SOC_ENUM("DAC Playback PowerTune Switch", l_ptm_enum),
|
||||
SOC_DOUBLE_R_S_TLV("HP Driver Playback Volume", AIC32X4_HPLGAIN,
|
||||
AIC32X4_HPLGAIN, 0, -0x6, 0x1d, 5, 0,
|
||||
tlv_driver_gain),
|
||||
SOC_DOUBLE_R("HP DAC Playback Switch", AIC32X4_HPLGAIN,
|
||||
AIC32X4_HPLGAIN, 6, 0x01, 1),
|
||||
|
||||
SOC_SINGLE("Auto-mute Switch", AIC32X4_DACMUTE, 4, 7, 0),
|
||||
|
||||
SOC_SINGLE_RANGE_TLV("Speaker Driver Playback Volume", TAS2505_SPKVOL1,
|
||||
0, 0, 117, 1, tlv_spk_vol),
|
||||
SOC_SINGLE_TLV("Speaker Amplifier Playback Volume", TAS2505_SPKVOL2,
|
||||
4, 5, 0, tlv_amp_vol),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new hp_output_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("DAC Switch", AIC32X4_HPLROUTE, 3, 1, 0),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget aic32x4_tas2505_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_DAC("DAC", "Playback", AIC32X4_DACSETUP, 7, 0),
|
||||
SND_SOC_DAPM_MIXER("HP Output Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&hp_output_mixer_controls[0],
|
||||
ARRAY_SIZE(hp_output_mixer_controls)),
|
||||
SND_SOC_DAPM_PGA("HP Power", AIC32X4_OUTPWRCTL, 5, 0, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_PGA("Speaker Driver", TAS2505_SPK, 1, 0, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("HP"),
|
||||
SND_SOC_DAPM_OUTPUT("Speaker"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route aic32x4_tas2505_dapm_routes[] = {
|
||||
/* Left Output */
|
||||
{"HP Output Mixer", "DAC Switch", "DAC"},
|
||||
|
||||
{"HP Power", NULL, "HP Output Mixer"},
|
||||
{"HP", NULL, "HP Power"},
|
||||
|
||||
{"Speaker Driver", NULL, "DAC"},
|
||||
{"Speaker", NULL, "Speaker Driver"},
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver aic32x4_tas2505_dai = {
|
||||
.name = "tas2505-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 1,
|
||||
.rates = SNDRV_PCM_RATE_8000_96000,
|
||||
.formats = AIC32X4_FORMATS,},
|
||||
.ops = &aic32x4_ops,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int aic32x4_tas2505_component_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct aic32x4_priv *aic32x4 = snd_soc_component_get_drvdata(component);
|
||||
u32 tmp_reg;
|
||||
int ret;
|
||||
|
||||
struct clk_bulk_data clocks[] = {
|
||||
{ .id = "codec_clkin" },
|
||||
{ .id = "pll" },
|
||||
{ .id = "bdiv" },
|
||||
{ .id = "mdac" },
|
||||
};
|
||||
|
||||
ret = devm_clk_bulk_get(component->dev, ARRAY_SIZE(clocks), clocks);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (aic32x4->setup)
|
||||
aic32x4_setup_gpios(component);
|
||||
|
||||
clk_set_parent(clocks[0].clk, clocks[1].clk);
|
||||
clk_set_parent(clocks[2].clk, clocks[3].clk);
|
||||
|
||||
/* Power platform configuration */
|
||||
if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE)
|
||||
snd_soc_component_write(component, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);
|
||||
|
||||
tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ?
|
||||
AIC32X4_LDOCTLEN : 0;
|
||||
snd_soc_component_write(component, AIC32X4_LDOCTL, tmp_reg);
|
||||
|
||||
tmp_reg = snd_soc_component_read(component, AIC32X4_CMMODE);
|
||||
if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36)
|
||||
tmp_reg |= AIC32X4_LDOIN_18_36;
|
||||
if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED)
|
||||
tmp_reg |= AIC32X4_LDOIN2HP;
|
||||
snd_soc_component_write(component, AIC32X4_CMMODE, tmp_reg);
|
||||
|
||||
/*
|
||||
* Enable the fast charging feature and ensure the needed 40ms ellapsed
|
||||
* before using the analog circuits.
|
||||
*/
|
||||
snd_soc_component_write(component, TAS2505_REFPOWERUP,
|
||||
AIC32X4_REFPOWERUP_40MS);
|
||||
msleep(40);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver soc_component_dev_aic32x4_tas2505 = {
|
||||
.probe = aic32x4_tas2505_component_probe,
|
||||
.set_bias_level = aic32x4_set_bias_level,
|
||||
.controls = aic32x4_tas2505_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(aic32x4_tas2505_snd_controls),
|
||||
.dapm_widgets = aic32x4_tas2505_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(aic32x4_tas2505_dapm_widgets),
|
||||
.dapm_routes = aic32x4_tas2505_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(aic32x4_tas2505_dapm_routes),
|
||||
.suspend_bias_off = 1,
|
||||
.idle_bias_on = 1,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4,
|
||||
struct device_node *np)
|
||||
{
|
||||
@ -1198,6 +1325,8 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap)
|
||||
return -ENOMEM;
|
||||
|
||||
aic32x4->dev = dev;
|
||||
aic32x4->type = (enum aic32x4_type)dev_get_drvdata(dev);
|
||||
|
||||
dev_set_drvdata(dev, aic32x4);
|
||||
|
||||
if (pdata) {
|
||||
@ -1247,8 +1376,16 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap)
|
||||
if (ret)
|
||||
goto err_disable_regulators;
|
||||
|
||||
ret = devm_snd_soc_register_component(dev,
|
||||
switch (aic32x4->type) {
|
||||
case AIC32X4_TYPE_TAS2505:
|
||||
ret = devm_snd_soc_register_component(dev,
|
||||
&soc_component_dev_aic32x4_tas2505, &aic32x4_tas2505_dai, 1);
|
||||
break;
|
||||
default:
|
||||
ret = devm_snd_soc_register_component(dev,
|
||||
&soc_component_dev_aic32x4, &aic32x4_dai, 1);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to register component\n");
|
||||
goto err_disable_regulators;
|
||||
|
@ -10,6 +10,12 @@
|
||||
struct device;
|
||||
struct regmap_config;
|
||||
|
||||
enum aic32x4_type {
|
||||
AIC32X4_TYPE_AIC32X4 = 0,
|
||||
AIC32X4_TYPE_AIC32X6,
|
||||
AIC32X4_TYPE_TAS2505,
|
||||
};
|
||||
|
||||
extern const struct regmap_config aic32x4_regmap_config;
|
||||
int aic32x4_probe(struct device *dev, struct regmap *regmap);
|
||||
int aic32x4_remove(struct device *dev);
|
||||
@ -88,6 +94,9 @@ int aic32x4_register_clocks(struct device *dev, const char *mclk_name);
|
||||
#define AIC32X4_LOLGAIN AIC32X4_REG(1, 18)
|
||||
#define AIC32X4_LORGAIN AIC32X4_REG(1, 19)
|
||||
#define AIC32X4_HEADSTART AIC32X4_REG(1, 20)
|
||||
#define TAS2505_SPK AIC32X4_REG(1, 45)
|
||||
#define TAS2505_SPKVOL1 AIC32X4_REG(1, 46)
|
||||
#define TAS2505_SPKVOL2 AIC32X4_REG(1, 48)
|
||||
#define AIC32X4_MICBIAS AIC32X4_REG(1, 51)
|
||||
#define AIC32X4_LMICPGAPIN AIC32X4_REG(1, 52)
|
||||
#define AIC32X4_LMICPGANIN AIC32X4_REG(1, 54)
|
||||
@ -96,6 +105,7 @@ int aic32x4_register_clocks(struct device *dev, const char *mclk_name);
|
||||
#define AIC32X4_FLOATINGINPUT AIC32X4_REG(1, 58)
|
||||
#define AIC32X4_LMICPGAVOL AIC32X4_REG(1, 59)
|
||||
#define AIC32X4_RMICPGAVOL AIC32X4_REG(1, 60)
|
||||
#define TAS2505_REFPOWERUP AIC32X4_REG(1, 122)
|
||||
#define AIC32X4_REFPOWERUP AIC32X4_REG(1, 123)
|
||||
|
||||
/* Bits, masks, and shifts */
|
||||
|
@ -88,6 +88,19 @@ struct wcd_clsh_ctrl {
|
||||
#define WCD9XXX_CLASSH_CTRL_CCL_1_DELTA_IPEAK_50MA 0x50
|
||||
#define WCD9XXX_CLASSH_CTRL_CCL_1_DELTA_IPEAK_30MA 0x30
|
||||
|
||||
#define WCD9XXX_BASE_ADDRESS 0x3000
|
||||
#define WCD9XXX_ANA_RX_SUPPLIES (WCD9XXX_BASE_ADDRESS+0x008)
|
||||
#define WCD9XXX_ANA_HPH (WCD9XXX_BASE_ADDRESS+0x009)
|
||||
#define WCD9XXX_CLASSH_MODE_2 (WCD9XXX_BASE_ADDRESS+0x098)
|
||||
#define WCD9XXX_CLASSH_MODE_3 (WCD9XXX_BASE_ADDRESS+0x099)
|
||||
#define WCD9XXX_FLYBACK_VNEG_CTRL_1 (WCD9XXX_BASE_ADDRESS+0x0A5)
|
||||
#define WCD9XXX_FLYBACK_VNEG_CTRL_4 (WCD9XXX_BASE_ADDRESS+0x0A8)
|
||||
#define WCD9XXX_FLYBACK_VNEGDAC_CTRL_2 (WCD9XXX_BASE_ADDRESS+0x0AF)
|
||||
#define WCD9XXX_RX_BIAS_HPH_LOWPOWER (WCD9XXX_BASE_ADDRESS+0x0BF)
|
||||
#define WCD9XXX_V3_RX_BIAS_FLYB_BUFF (WCD9XXX_BASE_ADDRESS+0x0C7)
|
||||
#define WCD9XXX_HPH_PA_CTL1 (WCD9XXX_BASE_ADDRESS+0x0D1)
|
||||
#define WCD9XXX_HPH_NEW_INT_PA_MISC2 (WCD9XXX_BASE_ADDRESS+0x138)
|
||||
|
||||
#define CLSH_REQ_ENABLE true
|
||||
#define CLSH_REQ_DISABLE false
|
||||
#define WCD_USLEEP_RANGE 50
|
||||
@ -137,6 +150,20 @@ static inline void wcd_clsh_set_buck_mode(struct snd_soc_component *comp,
|
||||
WCD9XXX_A_ANA_RX_VPOS_PWR_LVL_DEFAULT);
|
||||
}
|
||||
|
||||
static void wcd_clsh_v3_set_buck_mode(struct snd_soc_component *component,
|
||||
int mode)
|
||||
{
|
||||
if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI ||
|
||||
mode == CLS_AB_HIFI || mode == CLS_AB_LOHIFI)
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_ANA_RX_SUPPLIES,
|
||||
0x08, 0x08); /* set to HIFI */
|
||||
else
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_ANA_RX_SUPPLIES,
|
||||
0x08, 0x00); /* set to default */
|
||||
}
|
||||
|
||||
static inline void wcd_clsh_set_flyback_mode(struct snd_soc_component *comp,
|
||||
int mode)
|
||||
{
|
||||
@ -170,6 +197,36 @@ static void wcd_clsh_buck_ctrl(struct wcd_clsh_ctrl *ctrl,
|
||||
usleep_range(500, 500 + WCD_USLEEP_RANGE);
|
||||
}
|
||||
|
||||
static void wcd_clsh_v3_buck_ctrl(struct snd_soc_component *component,
|
||||
struct wcd_clsh_ctrl *ctrl,
|
||||
int mode,
|
||||
bool enable)
|
||||
{
|
||||
/* enable/disable buck */
|
||||
if ((enable && (++ctrl->buck_users == 1)) ||
|
||||
(!enable && (--ctrl->buck_users == 0))) {
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_ANA_RX_SUPPLIES,
|
||||
(1 << 7), (enable << 7));
|
||||
/*
|
||||
* 500us sleep is required after buck enable/disable
|
||||
* as per HW requirement
|
||||
*/
|
||||
usleep_range(500, 510);
|
||||
if (mode == CLS_H_LOHIFI || mode == CLS_H_ULP ||
|
||||
mode == CLS_H_HIFI || mode == CLS_H_LP)
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_CLASSH_MODE_3,
|
||||
0x02, 0x00);
|
||||
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_CLASSH_MODE_2,
|
||||
0xFF, 0x3A);
|
||||
/* 500usec delay is needed as per HW requirement */
|
||||
usleep_range(500, 500 + WCD_USLEEP_RANGE);
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd_clsh_flyback_ctrl(struct wcd_clsh_ctrl *ctrl,
|
||||
int mode,
|
||||
bool enable)
|
||||
@ -219,8 +276,7 @@ static void wcd_clsh_set_gain_path(struct wcd_clsh_ctrl *ctrl, int mode)
|
||||
val);
|
||||
}
|
||||
|
||||
static void wcd_clsh_set_hph_mode(struct snd_soc_component *comp,
|
||||
int mode)
|
||||
static void wcd_clsh_v2_set_hph_mode(struct snd_soc_component *comp, int mode)
|
||||
{
|
||||
int val = 0, gain = 0, res_val;
|
||||
int ipeak = WCD9XXX_CLASSH_CTRL_CCL_1_DELTA_IPEAK_50MA;
|
||||
@ -264,6 +320,48 @@ static void wcd_clsh_set_hph_mode(struct snd_soc_component *comp,
|
||||
ipeak);
|
||||
}
|
||||
|
||||
static void wcd_clsh_v3_set_hph_mode(struct snd_soc_component *component,
|
||||
int mode)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
switch (mode) {
|
||||
case CLS_H_NORMAL:
|
||||
val = 0x00;
|
||||
break;
|
||||
case CLS_AB:
|
||||
case CLS_H_ULP:
|
||||
val = 0x0C;
|
||||
break;
|
||||
case CLS_AB_HIFI:
|
||||
case CLS_H_HIFI:
|
||||
val = 0x08;
|
||||
break;
|
||||
case CLS_H_LP:
|
||||
case CLS_H_LOHIFI:
|
||||
case CLS_AB_LP:
|
||||
case CLS_AB_LOHIFI:
|
||||
val = 0x04;
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "%s:Invalid mode %d\n", __func__, mode);
|
||||
return;
|
||||
}
|
||||
|
||||
snd_soc_component_update_bits(component, WCD9XXX_ANA_HPH, 0x0C, val);
|
||||
}
|
||||
|
||||
void wcd_clsh_set_hph_mode(struct wcd_clsh_ctrl *ctrl, int mode)
|
||||
{
|
||||
struct snd_soc_component *comp = ctrl->comp;
|
||||
|
||||
if (ctrl->codec_version >= WCD937X)
|
||||
wcd_clsh_v3_set_hph_mode(comp, mode);
|
||||
else
|
||||
wcd_clsh_v2_set_hph_mode(comp, mode);
|
||||
|
||||
}
|
||||
|
||||
static void wcd_clsh_set_flyback_current(struct snd_soc_component *comp,
|
||||
int mode)
|
||||
{
|
||||
@ -289,6 +387,130 @@ static void wcd_clsh_set_buck_regulator_mode(struct snd_soc_component *comp,
|
||||
WCD9XXX_A_ANA_RX_REGULATOR_MODE_CLS_H);
|
||||
}
|
||||
|
||||
static void wcd_clsh_v3_set_buck_regulator_mode(struct snd_soc_component *component,
|
||||
int mode)
|
||||
{
|
||||
snd_soc_component_update_bits(component, WCD9XXX_ANA_RX_SUPPLIES,
|
||||
0x02, 0x00);
|
||||
}
|
||||
|
||||
static void wcd_clsh_v3_set_flyback_mode(struct snd_soc_component *component,
|
||||
int mode)
|
||||
{
|
||||
if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI ||
|
||||
mode == CLS_AB_HIFI || mode == CLS_AB_LOHIFI) {
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_ANA_RX_SUPPLIES,
|
||||
0x04, 0x04);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_FLYBACK_VNEG_CTRL_4,
|
||||
0xF0, 0x80);
|
||||
} else {
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_ANA_RX_SUPPLIES,
|
||||
0x04, 0x00); /* set to Default */
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_FLYBACK_VNEG_CTRL_4,
|
||||
0xF0, 0x70);
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd_clsh_v3_force_iq_ctl(struct snd_soc_component *component,
|
||||
int mode, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_FLYBACK_VNEGDAC_CTRL_2,
|
||||
0xE0, 0xA0);
|
||||
/* 100usec delay is needed as per HW requirement */
|
||||
usleep_range(100, 110);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_CLASSH_MODE_3,
|
||||
0x02, 0x02);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_CLASSH_MODE_2,
|
||||
0xFF, 0x1C);
|
||||
if (mode == CLS_H_LOHIFI || mode == CLS_AB_LOHIFI) {
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_HPH_NEW_INT_PA_MISC2,
|
||||
0x20, 0x20);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_RX_BIAS_HPH_LOWPOWER,
|
||||
0xF0, 0xC0);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_HPH_PA_CTL1,
|
||||
0x0E, 0x02);
|
||||
}
|
||||
} else {
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_HPH_NEW_INT_PA_MISC2,
|
||||
0x20, 0x00);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_RX_BIAS_HPH_LOWPOWER,
|
||||
0xF0, 0x80);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_HPH_PA_CTL1,
|
||||
0x0E, 0x06);
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd_clsh_v3_flyback_ctrl(struct snd_soc_component *component,
|
||||
struct wcd_clsh_ctrl *ctrl,
|
||||
int mode,
|
||||
bool enable)
|
||||
{
|
||||
/* enable/disable flyback */
|
||||
if ((enable && (++ctrl->flyback_users == 1)) ||
|
||||
(!enable && (--ctrl->flyback_users == 0))) {
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_FLYBACK_VNEG_CTRL_1,
|
||||
0xE0, 0xE0);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_ANA_RX_SUPPLIES,
|
||||
(1 << 6), (enable << 6));
|
||||
/*
|
||||
* 100us sleep is required after flyback enable/disable
|
||||
* as per HW requirement
|
||||
*/
|
||||
usleep_range(100, 110);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD9XXX_FLYBACK_VNEGDAC_CTRL_2,
|
||||
0xE0, 0xE0);
|
||||
/* 500usec delay is needed as per HW requirement */
|
||||
usleep_range(500, 500 + WCD_USLEEP_RANGE);
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd_clsh_v3_set_flyback_current(struct snd_soc_component *component,
|
||||
int mode)
|
||||
{
|
||||
snd_soc_component_update_bits(component, WCD9XXX_V3_RX_BIAS_FLYB_BUFF,
|
||||
0x0F, 0x0A);
|
||||
snd_soc_component_update_bits(component, WCD9XXX_V3_RX_BIAS_FLYB_BUFF,
|
||||
0xF0, 0xA0);
|
||||
/* Sleep needed to avoid click and pop as per HW requirement */
|
||||
usleep_range(100, 110);
|
||||
}
|
||||
|
||||
static void wcd_clsh_v3_state_aux(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
bool is_enable, int mode)
|
||||
{
|
||||
struct snd_soc_component *component = ctrl->comp;
|
||||
|
||||
if (is_enable) {
|
||||
wcd_clsh_v3_set_buck_mode(component, mode);
|
||||
wcd_clsh_v3_set_flyback_mode(component, mode);
|
||||
wcd_clsh_v3_flyback_ctrl(component, ctrl, mode, true);
|
||||
wcd_clsh_v3_set_flyback_current(component, mode);
|
||||
wcd_clsh_v3_buck_ctrl(component, ctrl, mode, true);
|
||||
} else {
|
||||
wcd_clsh_v3_buck_ctrl(component, ctrl, mode, false);
|
||||
wcd_clsh_v3_flyback_ctrl(component, ctrl, mode, false);
|
||||
wcd_clsh_v3_set_flyback_mode(component, CLS_H_NORMAL);
|
||||
wcd_clsh_v3_set_buck_mode(component, CLS_H_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd_clsh_state_lo(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
bool is_enable, int mode)
|
||||
{
|
||||
@ -316,6 +538,38 @@ static void wcd_clsh_state_lo(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd_clsh_v3_state_hph_r(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
bool is_enable, int mode)
|
||||
{
|
||||
struct snd_soc_component *component = ctrl->comp;
|
||||
|
||||
if (mode == CLS_H_NORMAL) {
|
||||
dev_dbg(component->dev, "%s: Normal mode not applicable for hph_r\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_enable) {
|
||||
wcd_clsh_v3_set_buck_regulator_mode(component, mode);
|
||||
wcd_clsh_v3_set_flyback_mode(component, mode);
|
||||
wcd_clsh_v3_force_iq_ctl(component, mode, true);
|
||||
wcd_clsh_v3_flyback_ctrl(component, ctrl, mode, true);
|
||||
wcd_clsh_v3_set_flyback_current(component, mode);
|
||||
wcd_clsh_v3_set_buck_mode(component, mode);
|
||||
wcd_clsh_v3_buck_ctrl(component, ctrl, mode, true);
|
||||
wcd_clsh_v3_set_hph_mode(component, mode);
|
||||
} else {
|
||||
wcd_clsh_v3_set_hph_mode(component, CLS_H_NORMAL);
|
||||
|
||||
/* buck and flyback set to default mode and disable */
|
||||
wcd_clsh_v3_flyback_ctrl(component, ctrl, CLS_H_NORMAL, false);
|
||||
wcd_clsh_v3_buck_ctrl(component, ctrl, CLS_H_NORMAL, false);
|
||||
wcd_clsh_v3_force_iq_ctl(component, CLS_H_NORMAL, false);
|
||||
wcd_clsh_v3_set_flyback_mode(component, CLS_H_NORMAL);
|
||||
wcd_clsh_v3_set_buck_mode(component, CLS_H_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd_clsh_state_hph_r(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
bool is_enable, int mode)
|
||||
{
|
||||
@ -353,10 +607,10 @@ static void wcd_clsh_state_hph_r(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
wcd_clsh_set_flyback_current(comp, mode);
|
||||
wcd_clsh_set_buck_mode(comp, mode);
|
||||
wcd_clsh_buck_ctrl(ctrl, mode, true);
|
||||
wcd_clsh_set_hph_mode(comp, mode);
|
||||
wcd_clsh_v2_set_hph_mode(comp, mode);
|
||||
wcd_clsh_set_gain_path(ctrl, mode);
|
||||
} else {
|
||||
wcd_clsh_set_hph_mode(comp, CLS_H_NORMAL);
|
||||
wcd_clsh_v2_set_hph_mode(comp, CLS_H_NORMAL);
|
||||
|
||||
if (mode != CLS_AB) {
|
||||
snd_soc_component_update_bits(comp,
|
||||
@ -374,6 +628,38 @@ static void wcd_clsh_state_hph_r(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd_clsh_v3_state_hph_l(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
bool is_enable, int mode)
|
||||
{
|
||||
struct snd_soc_component *component = ctrl->comp;
|
||||
|
||||
if (mode == CLS_H_NORMAL) {
|
||||
dev_dbg(component->dev, "%s: Normal mode not applicable for hph_l\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_enable) {
|
||||
wcd_clsh_v3_set_buck_regulator_mode(component, mode);
|
||||
wcd_clsh_v3_set_flyback_mode(component, mode);
|
||||
wcd_clsh_v3_force_iq_ctl(component, mode, true);
|
||||
wcd_clsh_v3_flyback_ctrl(component, ctrl, mode, true);
|
||||
wcd_clsh_v3_set_flyback_current(component, mode);
|
||||
wcd_clsh_v3_set_buck_mode(component, mode);
|
||||
wcd_clsh_v3_buck_ctrl(component, ctrl, mode, true);
|
||||
wcd_clsh_v3_set_hph_mode(component, mode);
|
||||
} else {
|
||||
wcd_clsh_v3_set_hph_mode(component, CLS_H_NORMAL);
|
||||
|
||||
/* set buck and flyback to Default Mode */
|
||||
wcd_clsh_v3_flyback_ctrl(component, ctrl, CLS_H_NORMAL, false);
|
||||
wcd_clsh_v3_buck_ctrl(component, ctrl, CLS_H_NORMAL, false);
|
||||
wcd_clsh_v3_force_iq_ctl(component, CLS_H_NORMAL, false);
|
||||
wcd_clsh_v3_set_flyback_mode(component, CLS_H_NORMAL);
|
||||
wcd_clsh_v3_set_buck_mode(component, CLS_H_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd_clsh_state_hph_l(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
bool is_enable, int mode)
|
||||
{
|
||||
@ -411,10 +697,10 @@ static void wcd_clsh_state_hph_l(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
wcd_clsh_set_flyback_current(comp, mode);
|
||||
wcd_clsh_set_buck_mode(comp, mode);
|
||||
wcd_clsh_buck_ctrl(ctrl, mode, true);
|
||||
wcd_clsh_set_hph_mode(comp, mode);
|
||||
wcd_clsh_v2_set_hph_mode(comp, mode);
|
||||
wcd_clsh_set_gain_path(ctrl, mode);
|
||||
} else {
|
||||
wcd_clsh_set_hph_mode(comp, CLS_H_NORMAL);
|
||||
wcd_clsh_v2_set_hph_mode(comp, CLS_H_NORMAL);
|
||||
|
||||
if (mode != CLS_AB) {
|
||||
snd_soc_component_update_bits(comp,
|
||||
@ -432,6 +718,32 @@ static void wcd_clsh_state_hph_l(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd_clsh_v3_state_ear(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
bool is_enable, int mode)
|
||||
{
|
||||
struct snd_soc_component *component = ctrl->comp;
|
||||
|
||||
if (is_enable) {
|
||||
wcd_clsh_v3_set_buck_regulator_mode(component, mode);
|
||||
wcd_clsh_v3_set_flyback_mode(component, mode);
|
||||
wcd_clsh_v3_force_iq_ctl(component, mode, true);
|
||||
wcd_clsh_v3_flyback_ctrl(component, ctrl, mode, true);
|
||||
wcd_clsh_v3_set_flyback_current(component, mode);
|
||||
wcd_clsh_v3_set_buck_mode(component, mode);
|
||||
wcd_clsh_v3_buck_ctrl(component, ctrl, mode, true);
|
||||
wcd_clsh_v3_set_hph_mode(component, mode);
|
||||
} else {
|
||||
wcd_clsh_v3_set_hph_mode(component, CLS_H_NORMAL);
|
||||
|
||||
/* set buck and flyback to Default Mode */
|
||||
wcd_clsh_v3_flyback_ctrl(component, ctrl, CLS_H_NORMAL, false);
|
||||
wcd_clsh_v3_buck_ctrl(component, ctrl, CLS_H_NORMAL, false);
|
||||
wcd_clsh_v3_force_iq_ctl(component, CLS_H_NORMAL, false);
|
||||
wcd_clsh_v3_set_flyback_mode(component, CLS_H_NORMAL);
|
||||
wcd_clsh_v3_set_buck_mode(component, CLS_H_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
static void wcd_clsh_state_ear(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
bool is_enable, int mode)
|
||||
{
|
||||
@ -472,16 +784,30 @@ static int _wcd_clsh_ctrl_set_state(struct wcd_clsh_ctrl *ctrl, int req_state,
|
||||
{
|
||||
switch (req_state) {
|
||||
case WCD_CLSH_STATE_EAR:
|
||||
wcd_clsh_state_ear(ctrl, req_state, is_enable, mode);
|
||||
if (ctrl->codec_version >= WCD937X)
|
||||
wcd_clsh_v3_state_ear(ctrl, req_state, is_enable, mode);
|
||||
else
|
||||
wcd_clsh_state_ear(ctrl, req_state, is_enable, mode);
|
||||
break;
|
||||
case WCD_CLSH_STATE_HPHL:
|
||||
wcd_clsh_state_hph_l(ctrl, req_state, is_enable, mode);
|
||||
if (ctrl->codec_version >= WCD937X)
|
||||
wcd_clsh_v3_state_hph_l(ctrl, req_state, is_enable, mode);
|
||||
else
|
||||
wcd_clsh_state_hph_l(ctrl, req_state, is_enable, mode);
|
||||
break;
|
||||
case WCD_CLSH_STATE_HPHR:
|
||||
wcd_clsh_state_hph_r(ctrl, req_state, is_enable, mode);
|
||||
if (ctrl->codec_version >= WCD937X)
|
||||
wcd_clsh_v3_state_hph_r(ctrl, req_state, is_enable, mode);
|
||||
else
|
||||
wcd_clsh_state_hph_r(ctrl, req_state, is_enable, mode);
|
||||
break;
|
||||
case WCD_CLSH_STATE_LO:
|
||||
wcd_clsh_state_lo(ctrl, req_state, is_enable, mode);
|
||||
if (ctrl->codec_version < WCD937X)
|
||||
wcd_clsh_state_lo(ctrl, req_state, is_enable, mode);
|
||||
break;
|
||||
case WCD_CLSH_STATE_AUX:
|
||||
if (ctrl->codec_version >= WCD937X)
|
||||
wcd_clsh_v3_state_aux(ctrl, req_state, is_enable, mode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -504,6 +830,7 @@ static bool wcd_clsh_is_state_valid(int state)
|
||||
case WCD_CLSH_STATE_HPHL:
|
||||
case WCD_CLSH_STATE_HPHR:
|
||||
case WCD_CLSH_STATE_LO:
|
||||
case WCD_CLSH_STATE_AUX:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -565,6 +892,7 @@ struct wcd_clsh_ctrl *wcd_clsh_ctrl_alloc(struct snd_soc_component *comp,
|
||||
|
||||
ctrl->state = WCD_CLSH_STATE_IDLE;
|
||||
ctrl->comp = comp;
|
||||
ctrl->codec_version = version;
|
||||
|
||||
return ctrl;
|
||||
}
|
||||
|
@ -22,8 +22,11 @@ enum wcd_clsh_event {
|
||||
#define WCD_CLSH_STATE_HPHL BIT(1)
|
||||
#define WCD_CLSH_STATE_HPHR BIT(2)
|
||||
#define WCD_CLSH_STATE_LO BIT(3)
|
||||
#define WCD_CLSH_STATE_AUX BIT(4)
|
||||
#define WCD_CLSH_STATE_MAX 4
|
||||
#define WCD_CLSH_V3_STATE_MAX 5
|
||||
#define NUM_CLSH_STATES_V2 BIT(WCD_CLSH_STATE_MAX)
|
||||
#define NUM_CLSH_STATES_V3 BIT(WCD_CLSH_V3_STATE_MAX)
|
||||
|
||||
enum wcd_clsh_mode {
|
||||
CLS_H_NORMAL = 0, /* Class-H Default */
|
||||
@ -31,9 +34,20 @@ enum wcd_clsh_mode {
|
||||
CLS_H_LP, /* Class-H Low Power */
|
||||
CLS_AB, /* Class-AB */
|
||||
CLS_H_LOHIFI, /* LoHIFI */
|
||||
CLS_H_ULP, /* Ultra Low power */
|
||||
CLS_AB_HIFI, /* Class-AB */
|
||||
CLS_AB_LP, /* Class-AB Low Power */
|
||||
CLS_AB_LOHIFI, /* Class-AB Low HIFI */
|
||||
CLS_NONE, /* None of the above modes */
|
||||
};
|
||||
|
||||
enum wcd_codec_version {
|
||||
WCD9335 = 0,
|
||||
WCD934X = 1,
|
||||
/* New CLSH after this */
|
||||
WCD937X = 2,
|
||||
WCD938X = 3,
|
||||
};
|
||||
struct wcd_clsh_ctrl;
|
||||
|
||||
extern struct wcd_clsh_ctrl *wcd_clsh_ctrl_alloc(
|
||||
@ -45,5 +59,7 @@ extern int wcd_clsh_ctrl_set_state(struct wcd_clsh_ctrl *ctrl,
|
||||
enum wcd_clsh_event clsh_event,
|
||||
int nstate,
|
||||
enum wcd_clsh_mode mode);
|
||||
extern void wcd_clsh_set_hph_mode(struct wcd_clsh_ctrl *ctrl,
|
||||
int mode);
|
||||
|
||||
#endif /* _WCD_CLSH_V2_H_ */
|
||||
|
1475
sound/soc/codecs/wcd-mbhc-v2.c
Normal file
1475
sound/soc/codecs/wcd-mbhc-v2.c
Normal file
File diff suppressed because it is too large
Load Diff
340
sound/soc/codecs/wcd-mbhc-v2.h
Normal file
340
sound/soc/codecs/wcd-mbhc-v2.h
Normal file
@ -0,0 +1,340 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef __WCD_MBHC_V2_H__
|
||||
#define __WCD_MBHC_V2_H__
|
||||
|
||||
#include <sound/jack.h>
|
||||
|
||||
#define WCD_MBHC_FIELD(id, rreg, rmask) \
|
||||
[id] = { .reg = rreg, .mask = rmask }
|
||||
|
||||
enum wcd_mbhc_field_function {
|
||||
WCD_MBHC_L_DET_EN,
|
||||
WCD_MBHC_GND_DET_EN,
|
||||
WCD_MBHC_MECH_DETECTION_TYPE,
|
||||
WCD_MBHC_MIC_CLAMP_CTL,
|
||||
WCD_MBHC_ELECT_DETECTION_TYPE,
|
||||
WCD_MBHC_HS_L_DET_PULL_UP_CTRL,
|
||||
WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL,
|
||||
WCD_MBHC_HPHL_PLUG_TYPE,
|
||||
WCD_MBHC_GND_PLUG_TYPE,
|
||||
WCD_MBHC_SW_HPH_LP_100K_TO_GND,
|
||||
WCD_MBHC_ELECT_SCHMT_ISRC,
|
||||
WCD_MBHC_FSM_EN,
|
||||
WCD_MBHC_INSREM_DBNC,
|
||||
WCD_MBHC_BTN_DBNC,
|
||||
WCD_MBHC_HS_VREF,
|
||||
WCD_MBHC_HS_COMP_RESULT,
|
||||
WCD_MBHC_IN2P_CLAMP_STATE,
|
||||
WCD_MBHC_MIC_SCHMT_RESULT,
|
||||
WCD_MBHC_HPHL_SCHMT_RESULT,
|
||||
WCD_MBHC_HPHR_SCHMT_RESULT,
|
||||
WCD_MBHC_OCP_FSM_EN,
|
||||
WCD_MBHC_BTN_RESULT,
|
||||
WCD_MBHC_BTN_ISRC_CTL,
|
||||
WCD_MBHC_ELECT_RESULT,
|
||||
WCD_MBHC_MICB_CTRL, /* Pull-up and micb control */
|
||||
WCD_MBHC_HPH_CNP_WG_TIME,
|
||||
WCD_MBHC_HPHR_PA_EN,
|
||||
WCD_MBHC_HPHL_PA_EN,
|
||||
WCD_MBHC_HPH_PA_EN,
|
||||
WCD_MBHC_SWCH_LEVEL_REMOVE,
|
||||
WCD_MBHC_PULLDOWN_CTRL,
|
||||
WCD_MBHC_ANC_DET_EN,
|
||||
WCD_MBHC_FSM_STATUS,
|
||||
WCD_MBHC_MUX_CTL,
|
||||
WCD_MBHC_MOISTURE_STATUS,
|
||||
WCD_MBHC_HPHR_GND,
|
||||
WCD_MBHC_HPHL_GND,
|
||||
WCD_MBHC_HPHL_OCP_DET_EN,
|
||||
WCD_MBHC_HPHR_OCP_DET_EN,
|
||||
WCD_MBHC_HPHL_OCP_STATUS,
|
||||
WCD_MBHC_HPHR_OCP_STATUS,
|
||||
WCD_MBHC_ADC_EN,
|
||||
WCD_MBHC_ADC_COMPLETE,
|
||||
WCD_MBHC_ADC_TIMEOUT,
|
||||
WCD_MBHC_ADC_RESULT,
|
||||
WCD_MBHC_MICB2_VOUT,
|
||||
WCD_MBHC_ADC_MODE,
|
||||
WCD_MBHC_DETECTION_DONE,
|
||||
WCD_MBHC_ELECT_ISRC_EN,
|
||||
WCD_MBHC_REG_FUNC_MAX,
|
||||
};
|
||||
|
||||
#define WCD_MBHC_DEF_BUTTONS 8
|
||||
#define WCD_MBHC_KEYCODE_NUM 8
|
||||
#define WCD_MBHC_USLEEP_RANGE_MARGIN_US 100
|
||||
#define WCD_MBHC_THR_HS_MICB_MV 2700
|
||||
#define WCD_MONO_HS_MIN_THR 2
|
||||
|
||||
enum wcd_mbhc_detect_logic {
|
||||
WCD_DETECTION_LEGACY,
|
||||
WCD_DETECTION_ADC,
|
||||
};
|
||||
|
||||
enum wcd_mbhc_cs_mb_en_flag {
|
||||
WCD_MBHC_EN_CS = 0,
|
||||
WCD_MBHC_EN_MB,
|
||||
WCD_MBHC_EN_PULLUP,
|
||||
WCD_MBHC_EN_NONE,
|
||||
};
|
||||
|
||||
enum {
|
||||
WCD_MBHC_ELEC_HS_INS,
|
||||
WCD_MBHC_ELEC_HS_REM,
|
||||
};
|
||||
|
||||
enum wcd_mbhc_plug_type {
|
||||
MBHC_PLUG_TYPE_INVALID = -1,
|
||||
MBHC_PLUG_TYPE_NONE,
|
||||
MBHC_PLUG_TYPE_HEADSET,
|
||||
MBHC_PLUG_TYPE_HEADPHONE,
|
||||
MBHC_PLUG_TYPE_HIGH_HPH,
|
||||
MBHC_PLUG_TYPE_GND_MIC_SWAP,
|
||||
};
|
||||
|
||||
enum pa_dac_ack_flags {
|
||||
WCD_MBHC_HPHL_PA_OFF_ACK = 0,
|
||||
WCD_MBHC_HPHR_PA_OFF_ACK,
|
||||
};
|
||||
|
||||
enum wcd_mbhc_btn_det_mem {
|
||||
WCD_MBHC_BTN_DET_V_BTN_LOW,
|
||||
WCD_MBHC_BTN_DET_V_BTN_HIGH
|
||||
};
|
||||
|
||||
enum {
|
||||
MIC_BIAS_1 = 1,
|
||||
MIC_BIAS_2,
|
||||
MIC_BIAS_3,
|
||||
MIC_BIAS_4
|
||||
};
|
||||
|
||||
enum {
|
||||
MICB_PULLUP_ENABLE,
|
||||
MICB_PULLUP_DISABLE,
|
||||
MICB_ENABLE,
|
||||
MICB_DISABLE,
|
||||
};
|
||||
|
||||
enum wcd_notify_event {
|
||||
WCD_EVENT_INVALID,
|
||||
/* events for micbias ON and OFF */
|
||||
WCD_EVENT_PRE_MICBIAS_2_OFF,
|
||||
WCD_EVENT_POST_MICBIAS_2_OFF,
|
||||
WCD_EVENT_PRE_MICBIAS_2_ON,
|
||||
WCD_EVENT_POST_MICBIAS_2_ON,
|
||||
WCD_EVENT_PRE_DAPM_MICBIAS_2_OFF,
|
||||
WCD_EVENT_POST_DAPM_MICBIAS_2_OFF,
|
||||
WCD_EVENT_PRE_DAPM_MICBIAS_2_ON,
|
||||
WCD_EVENT_POST_DAPM_MICBIAS_2_ON,
|
||||
/* events for PA ON and OFF */
|
||||
WCD_EVENT_PRE_HPHL_PA_ON,
|
||||
WCD_EVENT_POST_HPHL_PA_OFF,
|
||||
WCD_EVENT_PRE_HPHR_PA_ON,
|
||||
WCD_EVENT_POST_HPHR_PA_OFF,
|
||||
WCD_EVENT_PRE_HPHL_PA_OFF,
|
||||
WCD_EVENT_PRE_HPHR_PA_OFF,
|
||||
WCD_EVENT_OCP_OFF,
|
||||
WCD_EVENT_OCP_ON,
|
||||
WCD_EVENT_LAST,
|
||||
};
|
||||
|
||||
enum wcd_mbhc_event_state {
|
||||
WCD_MBHC_EVENT_PA_HPHL,
|
||||
WCD_MBHC_EVENT_PA_HPHR,
|
||||
};
|
||||
|
||||
enum wcd_mbhc_hph_type {
|
||||
WCD_MBHC_HPH_NONE = 0,
|
||||
WCD_MBHC_HPH_MONO,
|
||||
WCD_MBHC_HPH_STEREO,
|
||||
};
|
||||
|
||||
/*
|
||||
* These enum definitions are directly mapped to the register
|
||||
* definitions
|
||||
*/
|
||||
|
||||
enum mbhc_hs_pullup_iref {
|
||||
I_DEFAULT = -1,
|
||||
I_OFF = 0,
|
||||
I_1P0_UA,
|
||||
I_2P0_UA,
|
||||
I_3P0_UA,
|
||||
};
|
||||
|
||||
enum mbhc_hs_pullup_iref_v2 {
|
||||
HS_PULLUP_I_DEFAULT = -1,
|
||||
HS_PULLUP_I_3P0_UA = 0,
|
||||
HS_PULLUP_I_2P25_UA,
|
||||
HS_PULLUP_I_1P5_UA,
|
||||
HS_PULLUP_I_0P75_UA,
|
||||
HS_PULLUP_I_1P125_UA = 0x05,
|
||||
HS_PULLUP_I_0P375_UA = 0x07,
|
||||
HS_PULLUP_I_2P0_UA,
|
||||
HS_PULLUP_I_1P0_UA = 0x0A,
|
||||
HS_PULLUP_I_0P5_UA,
|
||||
HS_PULLUP_I_0P25_UA = 0x0F,
|
||||
HS_PULLUP_I_0P125_UA = 0x17,
|
||||
HS_PULLUP_I_OFF,
|
||||
};
|
||||
|
||||
enum mbhc_moisture_rref {
|
||||
R_OFF,
|
||||
R_24_KOHM,
|
||||
R_84_KOHM,
|
||||
R_184_KOHM,
|
||||
};
|
||||
|
||||
struct wcd_mbhc_config {
|
||||
int btn_high[WCD_MBHC_DEF_BUTTONS];
|
||||
int btn_low[WCD_MBHC_DEF_BUTTONS];
|
||||
int v_hs_max;
|
||||
int num_btn;
|
||||
bool mono_stero_detection;
|
||||
bool (*swap_gnd_mic)(struct snd_soc_component *component, bool active);
|
||||
bool hs_ext_micbias;
|
||||
bool gnd_det_en;
|
||||
uint32_t linein_th;
|
||||
bool moisture_en;
|
||||
int mbhc_micbias;
|
||||
int anc_micbias;
|
||||
bool moisture_duty_cycle_en;
|
||||
bool hphl_swh; /*track HPHL switch NC / NO */
|
||||
bool gnd_swh; /*track GND switch NC / NO */
|
||||
u32 hs_thr;
|
||||
u32 hph_thr;
|
||||
u32 micb_mv;
|
||||
u32 moist_vref;
|
||||
u32 moist_iref;
|
||||
u32 moist_rref;
|
||||
};
|
||||
|
||||
struct wcd_mbhc_intr {
|
||||
int mbhc_sw_intr;
|
||||
int mbhc_btn_press_intr;
|
||||
int mbhc_btn_release_intr;
|
||||
int mbhc_hs_ins_intr;
|
||||
int mbhc_hs_rem_intr;
|
||||
int hph_left_ocp;
|
||||
int hph_right_ocp;
|
||||
};
|
||||
|
||||
struct wcd_mbhc_field {
|
||||
u16 reg;
|
||||
u8 mask;
|
||||
};
|
||||
|
||||
struct wcd_mbhc;
|
||||
|
||||
struct wcd_mbhc_cb {
|
||||
void (*update_cross_conn_thr)(struct snd_soc_component *component);
|
||||
void (*get_micbias_val)(struct snd_soc_component *component, int *mb);
|
||||
void (*bcs_enable)(struct snd_soc_component *component, bool bcs_enable);
|
||||
void (*compute_impedance)(struct snd_soc_component *component,
|
||||
uint32_t *zl, uint32_t *zr);
|
||||
void (*set_micbias_value)(struct snd_soc_component *component);
|
||||
void (*set_auto_zeroing)(struct snd_soc_component *component,
|
||||
bool enable);
|
||||
void (*clk_setup)(struct snd_soc_component *component, bool enable);
|
||||
bool (*micbias_enable_status)(struct snd_soc_component *component, int micb_num);
|
||||
void (*mbhc_bias)(struct snd_soc_component *component, bool enable);
|
||||
void (*set_btn_thr)(struct snd_soc_component *component,
|
||||
int *btn_low, int *btn_high,
|
||||
int num_btn, bool is_micbias);
|
||||
void (*hph_pull_up_control)(struct snd_soc_component *component,
|
||||
enum mbhc_hs_pullup_iref);
|
||||
int (*mbhc_micbias_control)(struct snd_soc_component *component,
|
||||
int micb_num, int req);
|
||||
void (*mbhc_micb_ramp_control)(struct snd_soc_component *component,
|
||||
bool enable);
|
||||
bool (*extn_use_mb)(struct snd_soc_component *component);
|
||||
int (*mbhc_micb_ctrl_thr_mic)(struct snd_soc_component *component,
|
||||
int micb_num, bool req_en);
|
||||
void (*mbhc_gnd_det_ctrl)(struct snd_soc_component *component,
|
||||
bool enable);
|
||||
void (*hph_pull_down_ctrl)(struct snd_soc_component *component,
|
||||
bool enable);
|
||||
void (*mbhc_moisture_config)(struct snd_soc_component *component);
|
||||
void (*update_anc_state)(struct snd_soc_component *component,
|
||||
bool enable, int anc_num);
|
||||
void (*hph_pull_up_control_v2)(struct snd_soc_component *component,
|
||||
int pull_up_cur);
|
||||
bool (*mbhc_get_moisture_status)(struct snd_soc_component *component);
|
||||
void (*mbhc_moisture_polling_ctrl)(struct snd_soc_component *component, bool enable);
|
||||
void (*mbhc_moisture_detect_en)(struct snd_soc_component *component, bool enable);
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_WCD_MBHC)
|
||||
int wcd_dt_parse_mbhc_data(struct device *dev, struct wcd_mbhc_config *cfg);
|
||||
int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg,
|
||||
struct snd_soc_jack *jack);
|
||||
void wcd_mbhc_stop(struct wcd_mbhc *mbhc);
|
||||
void wcd_mbhc_set_hph_type(struct wcd_mbhc *mbhc, int hph_type);
|
||||
int wcd_mbhc_get_hph_type(struct wcd_mbhc *mbhc);
|
||||
struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component,
|
||||
const struct wcd_mbhc_cb *mbhc_cb,
|
||||
const struct wcd_mbhc_intr *mbhc_cdc_intr_ids,
|
||||
struct wcd_mbhc_field *fields,
|
||||
bool impedance_det_en);
|
||||
int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
|
||||
uint32_t *zr);
|
||||
void wcd_mbhc_deinit(struct wcd_mbhc *mbhc);
|
||||
int wcd_mbhc_event_notify(struct wcd_mbhc *mbhc, unsigned long event);
|
||||
|
||||
#else
|
||||
static inline int wcd_dt_parse_mbhc_data(struct device *dev,
|
||||
struct wcd_mbhc_config *cfg)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline void wcd_mbhc_stop(struct wcd_mbhc *mbhc)
|
||||
{
|
||||
}
|
||||
|
||||
static inline struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component,
|
||||
const struct wcd_mbhc_cb *mbhc_cb,
|
||||
const struct wcd_mbhc_intr *mbhc_cdc_intr_ids,
|
||||
struct wcd_mbhc_field *fields,
|
||||
bool impedance_det_en)
|
||||
{
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
}
|
||||
|
||||
static inline void wcd_mbhc_set_hph_type(struct wcd_mbhc *mbhc, int hph_type)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int wcd_mbhc_get_hph_type(struct wcd_mbhc *mbhc)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline int wcd_mbhc_event_notify(struct wcd_mbhc *mbhc, unsigned long event)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline int wcd_mbhc_start(struct wcd_mbhc *mbhc,
|
||||
struct wcd_mbhc_config *mbhc_cfg,
|
||||
struct snd_soc_jack *jack)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc,
|
||||
uint32_t *zl,
|
||||
uint32_t *zr)
|
||||
{
|
||||
*zl = 0;
|
||||
*zr = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline void wcd_mbhc_deinit(struct wcd_mbhc *mbhc)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __WCD_MBHC_V2_H__ */
|
File diff suppressed because it is too large
Load Diff
320
sound/soc/codecs/wcd938x-sdw.c
Normal file
320
sound/soc/codecs/wcd938x-sdw.c
Normal file
@ -0,0 +1,320 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2021, Linaro Limited
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/component.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/soundwire/sdw.h>
|
||||
#include <linux/soundwire/sdw_type.h>
|
||||
#include <linux/soundwire/sdw_registers.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
#include "wcd938x.h"
|
||||
|
||||
#define SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(m) (0xE0 + 0x10 * (m))
|
||||
|
||||
static struct wcd938x_sdw_ch_info wcd938x_sdw_rx_ch_info[] = {
|
||||
WCD_SDW_CH(WCD938X_HPH_L, WCD938X_HPH_PORT, BIT(0)),
|
||||
WCD_SDW_CH(WCD938X_HPH_R, WCD938X_HPH_PORT, BIT(1)),
|
||||
WCD_SDW_CH(WCD938X_CLSH, WCD938X_CLSH_PORT, BIT(0)),
|
||||
WCD_SDW_CH(WCD938X_COMP_L, WCD938X_COMP_PORT, BIT(0)),
|
||||
WCD_SDW_CH(WCD938X_COMP_R, WCD938X_COMP_PORT, BIT(1)),
|
||||
WCD_SDW_CH(WCD938X_LO, WCD938X_LO_PORT, BIT(0)),
|
||||
WCD_SDW_CH(WCD938X_DSD_L, WCD938X_DSD_PORT, BIT(0)),
|
||||
WCD_SDW_CH(WCD938X_DSD_R, WCD938X_DSD_PORT, BIT(1)),
|
||||
};
|
||||
|
||||
static struct wcd938x_sdw_ch_info wcd938x_sdw_tx_ch_info[] = {
|
||||
WCD_SDW_CH(WCD938X_ADC1, WCD938X_ADC_1_2_PORT, BIT(0)),
|
||||
WCD_SDW_CH(WCD938X_ADC2, WCD938X_ADC_1_2_PORT, BIT(1)),
|
||||
WCD_SDW_CH(WCD938X_ADC3, WCD938X_ADC_3_4_PORT, BIT(0)),
|
||||
WCD_SDW_CH(WCD938X_ADC4, WCD938X_ADC_3_4_PORT, BIT(1)),
|
||||
WCD_SDW_CH(WCD938X_DMIC0, WCD938X_DMIC_0_3_MBHC_PORT, BIT(0)),
|
||||
WCD_SDW_CH(WCD938X_DMIC1, WCD938X_DMIC_0_3_MBHC_PORT, BIT(1)),
|
||||
WCD_SDW_CH(WCD938X_MBHC, WCD938X_DMIC_0_3_MBHC_PORT, BIT(2)),
|
||||
WCD_SDW_CH(WCD938X_DMIC2, WCD938X_DMIC_0_3_MBHC_PORT, BIT(2)),
|
||||
WCD_SDW_CH(WCD938X_DMIC3, WCD938X_DMIC_0_3_MBHC_PORT, BIT(3)),
|
||||
WCD_SDW_CH(WCD938X_DMIC4, WCD938X_DMIC_4_7_PORT, BIT(0)),
|
||||
WCD_SDW_CH(WCD938X_DMIC5, WCD938X_DMIC_4_7_PORT, BIT(1)),
|
||||
WCD_SDW_CH(WCD938X_DMIC6, WCD938X_DMIC_4_7_PORT, BIT(2)),
|
||||
WCD_SDW_CH(WCD938X_DMIC7, WCD938X_DMIC_4_7_PORT, BIT(3)),
|
||||
};
|
||||
|
||||
static struct sdw_dpn_prop wcd938x_dpn_prop[WCD938X_MAX_SWR_PORTS] = {
|
||||
{
|
||||
.num = 1,
|
||||
.type = SDW_DPN_SIMPLE,
|
||||
.min_ch = 1,
|
||||
.max_ch = 8,
|
||||
.simple_ch_prep_sm = true,
|
||||
}, {
|
||||
.num = 2,
|
||||
.type = SDW_DPN_SIMPLE,
|
||||
.min_ch = 1,
|
||||
.max_ch = 4,
|
||||
.simple_ch_prep_sm = true,
|
||||
}, {
|
||||
.num = 3,
|
||||
.type = SDW_DPN_SIMPLE,
|
||||
.min_ch = 1,
|
||||
.max_ch = 4,
|
||||
.simple_ch_prep_sm = true,
|
||||
}, {
|
||||
.num = 4,
|
||||
.type = SDW_DPN_SIMPLE,
|
||||
.min_ch = 1,
|
||||
.max_ch = 4,
|
||||
.simple_ch_prep_sm = true,
|
||||
}, {
|
||||
.num = 5,
|
||||
.type = SDW_DPN_SIMPLE,
|
||||
.min_ch = 1,
|
||||
.max_ch = 4,
|
||||
.simple_ch_prep_sm = true,
|
||||
}
|
||||
};
|
||||
|
||||
struct device *wcd938x_sdw_device_get(struct device_node *np)
|
||||
{
|
||||
return bus_find_device_by_of_node(&sdw_bus_type, np);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wcd938x_sdw_device_get);
|
||||
|
||||
int wcd938x_swr_get_current_bank(struct sdw_slave *sdev)
|
||||
{
|
||||
int bank;
|
||||
|
||||
bank = sdw_read(sdev, SDW_SCP_CTRL);
|
||||
|
||||
return ((bank & 0x40) ? 1 : 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wcd938x_swr_get_current_bank);
|
||||
|
||||
int wcd938x_sdw_hw_params(struct wcd938x_sdw_priv *wcd,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct sdw_port_config port_config[WCD938X_MAX_SWR_PORTS];
|
||||
unsigned long ch_mask;
|
||||
int i, j;
|
||||
|
||||
wcd->sconfig.ch_count = 1;
|
||||
wcd->active_ports = 0;
|
||||
for (i = 0; i < WCD938X_MAX_SWR_PORTS; i++) {
|
||||
ch_mask = wcd->port_config[i].ch_mask;
|
||||
|
||||
if (!ch_mask)
|
||||
continue;
|
||||
|
||||
for_each_set_bit(j, &ch_mask, 4)
|
||||
wcd->sconfig.ch_count++;
|
||||
|
||||
port_config[wcd->active_ports] = wcd->port_config[i];
|
||||
wcd->active_ports++;
|
||||
}
|
||||
|
||||
wcd->sconfig.bps = 1;
|
||||
wcd->sconfig.frame_rate = params_rate(params);
|
||||
if (wcd->is_tx)
|
||||
wcd->sconfig.direction = SDW_DATA_DIR_TX;
|
||||
else
|
||||
wcd->sconfig.direction = SDW_DATA_DIR_RX;
|
||||
|
||||
wcd->sconfig.type = SDW_STREAM_PCM;
|
||||
|
||||
return sdw_stream_add_slave(wcd->sdev, &wcd->sconfig,
|
||||
&port_config[0], wcd->active_ports,
|
||||
wcd->sruntime);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wcd938x_sdw_hw_params);
|
||||
|
||||
int wcd938x_sdw_free(struct wcd938x_sdw_priv *wcd,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
sdw_stream_remove_slave(wcd->sdev, wcd->sruntime);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wcd938x_sdw_free);
|
||||
|
||||
int wcd938x_sdw_set_sdw_stream(struct wcd938x_sdw_priv *wcd,
|
||||
struct snd_soc_dai *dai,
|
||||
void *stream, int direction)
|
||||
{
|
||||
wcd->sruntime = stream;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wcd938x_sdw_set_sdw_stream);
|
||||
|
||||
static int wcd9380_update_status(struct sdw_slave *slave,
|
||||
enum sdw_slave_status status)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd9380_bus_config(struct sdw_slave *slave,
|
||||
struct sdw_bus_params *params)
|
||||
{
|
||||
sdw_write(slave, SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(params->next_bank), 0x01);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd9380_interrupt_callback(struct sdw_slave *slave,
|
||||
struct sdw_slave_intr_status *status)
|
||||
{
|
||||
struct wcd938x_sdw_priv *wcd = dev_get_drvdata(&slave->dev);
|
||||
struct irq_domain *slave_irq = wcd->slave_irq;
|
||||
struct regmap *regmap = dev_get_regmap(&slave->dev, NULL);
|
||||
u32 sts1, sts2, sts3;
|
||||
|
||||
do {
|
||||
handle_nested_irq(irq_find_mapping(slave_irq, 0));
|
||||
regmap_read(regmap, WCD938X_DIGITAL_INTR_STATUS_0, &sts1);
|
||||
regmap_read(regmap, WCD938X_DIGITAL_INTR_STATUS_1, &sts2);
|
||||
regmap_read(regmap, WCD938X_DIGITAL_INTR_STATUS_2, &sts3);
|
||||
|
||||
} while (sts1 || sts2 || sts3);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct sdw_slave_ops wcd9380_slave_ops = {
|
||||
.update_status = wcd9380_update_status,
|
||||
.interrupt_callback = wcd9380_interrupt_callback,
|
||||
.bus_config = wcd9380_bus_config,
|
||||
};
|
||||
|
||||
static int wcd938x_sdw_component_bind(struct device *dev,
|
||||
struct device *master, void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wcd938x_sdw_component_unbind(struct device *dev,
|
||||
struct device *master, void *data)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct component_ops wcd938x_sdw_component_ops = {
|
||||
.bind = wcd938x_sdw_component_bind,
|
||||
.unbind = wcd938x_sdw_component_unbind,
|
||||
};
|
||||
|
||||
static int wcd9380_probe(struct sdw_slave *pdev,
|
||||
const struct sdw_device_id *id)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct wcd938x_sdw_priv *wcd;
|
||||
int ret;
|
||||
|
||||
wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL);
|
||||
if (!wcd)
|
||||
return -ENOMEM;
|
||||
|
||||
/**
|
||||
* Port map index starts with 0, however the data port for this codec
|
||||
* are from index 1
|
||||
*/
|
||||
if (of_property_read_bool(dev->of_node, "qcom,tx-port-mapping")) {
|
||||
wcd->is_tx = true;
|
||||
ret = of_property_read_u32_array(dev->of_node, "qcom,tx-port-mapping",
|
||||
&pdev->m_port_map[1],
|
||||
WCD938X_MAX_TX_SWR_PORTS);
|
||||
} else {
|
||||
ret = of_property_read_u32_array(dev->of_node, "qcom,rx-port-mapping",
|
||||
&pdev->m_port_map[1],
|
||||
WCD938X_MAX_SWR_PORTS);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
dev_info(dev, "Static Port mapping not specified\n");
|
||||
|
||||
wcd->sdev = pdev;
|
||||
dev_set_drvdata(dev, wcd);
|
||||
|
||||
pdev->prop.scp_int1_mask = SDW_SCP_INT1_IMPL_DEF |
|
||||
SDW_SCP_INT1_BUS_CLASH |
|
||||
SDW_SCP_INT1_PARITY;
|
||||
pdev->prop.lane_control_support = true;
|
||||
if (wcd->is_tx) {
|
||||
pdev->prop.source_ports = GENMASK(WCD938X_MAX_SWR_PORTS, 0);
|
||||
pdev->prop.src_dpn_prop = wcd938x_dpn_prop;
|
||||
wcd->ch_info = &wcd938x_sdw_tx_ch_info[0];
|
||||
pdev->prop.wake_capable = true;
|
||||
} else {
|
||||
pdev->prop.sink_ports = GENMASK(WCD938X_MAX_SWR_PORTS, 0);
|
||||
pdev->prop.sink_dpn_prop = wcd938x_dpn_prop;
|
||||
wcd->ch_info = &wcd938x_sdw_rx_ch_info[0];
|
||||
}
|
||||
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
return component_add(dev, &wcd938x_sdw_component_ops);
|
||||
}
|
||||
|
||||
static const struct sdw_device_id wcd9380_slave_id[] = {
|
||||
SDW_SLAVE_ENTRY(0x0217, 0x10d, 0),
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(sdw, wcd9380_slave_id);
|
||||
|
||||
static int __maybe_unused wcd938x_sdw_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct regmap *regmap = dev_get_regmap(dev, NULL);
|
||||
|
||||
if (regmap) {
|
||||
regcache_cache_only(regmap, true);
|
||||
regcache_mark_dirty(regmap);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused wcd938x_sdw_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct regmap *regmap = dev_get_regmap(dev, NULL);
|
||||
|
||||
if (regmap) {
|
||||
regcache_cache_only(regmap, false);
|
||||
regcache_sync(regmap);
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops wcd938x_sdw_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(wcd938x_sdw_runtime_suspend, wcd938x_sdw_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
|
||||
static struct sdw_driver wcd9380_codec_driver = {
|
||||
.probe = wcd9380_probe,
|
||||
.ops = &wcd9380_slave_ops,
|
||||
.id_table = wcd9380_slave_id,
|
||||
.driver = {
|
||||
.name = "wcd9380-codec",
|
||||
.pm = &wcd938x_sdw_pm_ops,
|
||||
}
|
||||
};
|
||||
module_sdw_driver(wcd9380_codec_driver);
|
||||
|
||||
MODULE_DESCRIPTION("WCD938X SDW codec driver");
|
||||
MODULE_LICENSE("GPL");
|
3737
sound/soc/codecs/wcd938x.c
Normal file
3737
sound/soc/codecs/wcd938x.c
Normal file
File diff suppressed because it is too large
Load Diff
718
sound/soc/codecs/wcd938x.h
Normal file
718
sound/soc/codecs/wcd938x.h
Normal file
@ -0,0 +1,718 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __WCD938X_H__
|
||||
#define __WCD938X_H__
|
||||
#include <linux/soundwire/sdw.h>
|
||||
#include <linux/soundwire/sdw_type.h>
|
||||
|
||||
#define WCD938X_BASE_ADDRESS (0x3000)
|
||||
#define WCD938X_ANA_PAGE_REGISTER (0x3000)
|
||||
#define WCD938X_ANA_BIAS (0x3001)
|
||||
#define WCD938X_ANA_RX_SUPPLIES (0x3008)
|
||||
#define WCD938X_RX_BIAS_EN_MASK BIT(0)
|
||||
#define WCD938X_REGULATOR_MODE_MASK BIT(1)
|
||||
#define WCD938X_REGULATOR_MODE_CLASS_AB 1
|
||||
#define WCD938X_VNEG_EN_MASK BIT(6)
|
||||
#define WCD938X_VPOS_EN_MASK BIT(7)
|
||||
#define WCD938X_ANA_HPH (0x3009)
|
||||
#define WCD938X_HPHR_REF_EN_MASK BIT(4)
|
||||
#define WCD938X_HPHL_REF_EN_MASK BIT(5)
|
||||
#define WCD938X_HPHR_EN_MASK BIT(6)
|
||||
#define WCD938X_HPHL_EN_MASK BIT(7)
|
||||
#define WCD938X_ANA_EAR (0x300A)
|
||||
#define WCD938X_ANA_EAR_COMPANDER_CTL (0x300B)
|
||||
#define WCD938X_GAIN_OVRD_REG_MASK BIT(7)
|
||||
#define WCD938X_EAR_GAIN_MASK GENMASK(6, 2)
|
||||
#define WCD938X_ANA_TX_CH1 (0x300E)
|
||||
#define WCD938X_ANA_TX_CH2 (0x300F)
|
||||
#define WCD938X_HPF1_INIT_MASK BIT(6)
|
||||
#define WCD938X_HPF2_INIT_MASK BIT(5)
|
||||
#define WCD938X_ANA_TX_CH3 (0x3010)
|
||||
#define WCD938X_ANA_TX_CH4 (0x3011)
|
||||
#define WCD938X_HPF3_INIT_MASK BIT(6)
|
||||
#define WCD938X_HPF4_INIT_MASK BIT(5)
|
||||
#define WCD938X_ANA_MICB1_MICB2_DSP_EN_LOGIC (0x3012)
|
||||
#define WCD938X_ANA_MICB3_DSP_EN_LOGIC (0x3013)
|
||||
#define WCD938X_ANA_MBHC_MECH (0x3014)
|
||||
#define WCD938X_MBHC_L_DET_EN_MASK BIT(7)
|
||||
#define WCD938X_MBHC_L_DET_EN BIT(7)
|
||||
#define WCD938X_MBHC_GND_DET_EN_MASK BIT(6)
|
||||
#define WCD938X_MBHC_MECH_DETECT_TYPE_MASK BIT(5)
|
||||
#define WCD938X_MBHC_MECH_DETECT_TYPE_INS 1
|
||||
#define WCD938X_MBHC_HPHL_PLUG_TYPE_MASK BIT(4)
|
||||
#define WCD938X_MBHC_HPHL_PLUG_TYPE_NO 1
|
||||
#define WCD938X_MBHC_GND_PLUG_TYPE_MASK BIT(3)
|
||||
#define WCD938X_MBHC_GND_PLUG_TYPE_NO 1
|
||||
#define WCD938X_MBHC_HSL_PULLUP_COMP_EN BIT(2)
|
||||
#define WCD938X_MBHC_HSG_PULLUP_COMP_EN BIT(1)
|
||||
#define WCD938X_MBHC_HPHL_100K_TO_GND_EN BIT(0)
|
||||
|
||||
#define WCD938X_ANA_MBHC_ELECT (0x3015)
|
||||
#define WCD938X_ANA_MBHC_BD_ISRC_CTL_MASK GENMASK(6, 4)
|
||||
#define WCD938X_ANA_MBHC_BD_ISRC_100UA GENMASK(5, 4)
|
||||
#define WCD938X_ANA_MBHC_BD_ISRC_OFF 0
|
||||
#define WCD938X_ANA_MBHC_BIAS_EN_MASK BIT(0)
|
||||
#define WCD938X_ANA_MBHC_BIAS_EN BIT(0)
|
||||
#define WCD938X_ANA_MBHC_ZDET (0x3016)
|
||||
#define WCD938X_ANA_MBHC_RESULT_1 (0x3017)
|
||||
#define WCD938X_ANA_MBHC_RESULT_2 (0x3018)
|
||||
#define WCD938X_ANA_MBHC_RESULT_3 (0x3019)
|
||||
#define WCD938X_MBHC_BTN_RESULT_MASK GENMASK(2, 0)
|
||||
#define WCD938X_ANA_MBHC_BTN0 (0x301A)
|
||||
#define WCD938X_MBHC_BTN_VTH_MASK GENMASK(7, 2)
|
||||
#define WCD938X_ANA_MBHC_BTN1 (0x301B)
|
||||
#define WCD938X_ANA_MBHC_BTN2 (0x301C)
|
||||
#define WCD938X_ANA_MBHC_BTN3 (0x301D)
|
||||
#define WCD938X_ANA_MBHC_BTN4 (0x301E)
|
||||
#define WCD938X_ANA_MBHC_BTN5 (0x301F)
|
||||
#define WCD938X_VTH_MASK GENMASK(7, 2)
|
||||
#define WCD938X_ANA_MBHC_BTN6 (0x3020)
|
||||
#define WCD938X_ANA_MBHC_BTN7 (0x3021)
|
||||
#define WCD938X_ANA_MICB1 (0x3022)
|
||||
#define WCD938X_MICB_VOUT_MASK GENMASK(5, 0)
|
||||
#define WCD938X_MICB_EN_MASK GENMASK(7, 6)
|
||||
#define WCD938X_MICB_DISABLE 0
|
||||
#define WCD938X_MICB_ENABLE 1
|
||||
#define WCD938X_MICB_PULL_UP 2
|
||||
#define WCD938X_MICB_PULL_DOWN 3
|
||||
#define WCD938X_ANA_MICB2 (0x3023)
|
||||
#define WCD938X_ANA_MICB2_ENABLE BIT(6)
|
||||
#define WCD938X_ANA_MICB2_ENABLE_MASK GENMASK(7, 6)
|
||||
#define WCD938X_ANA_MICB2_VOUT_MASK GENMASK(5, 0)
|
||||
#define WCD938X_ANA_MICB2_RAMP (0x3024)
|
||||
#define WCD938X_RAMP_EN_MASK BIT(7)
|
||||
#define WCD938X_RAMP_SHIFT_CTRL_MASK GENMASK(4, 2)
|
||||
#define WCD938X_ANA_MICB3 (0x3025)
|
||||
#define WCD938X_ANA_MICB4 (0x3026)
|
||||
#define WCD938X_BIAS_CTL (0x3028)
|
||||
#define WCD938X_BIAS_VBG_FINE_ADJ (0x3029)
|
||||
#define WCD938X_LDOL_VDDCX_ADJUST (0x3040)
|
||||
#define WCD938X_LDOL_DISABLE_LDOL (0x3041)
|
||||
#define WCD938X_MBHC_CTL_CLK (0x3056)
|
||||
#define WCD938X_MBHC_CTL_ANA (0x3057)
|
||||
#define WCD938X_MBHC_CTL_SPARE_1 (0x3058)
|
||||
#define WCD938X_MBHC_CTL_SPARE_2 (0x3059)
|
||||
#define WCD938X_MBHC_CTL_BCS (0x305A)
|
||||
#define WCD938X_MBHC_MOISTURE_DET_FSM_STATUS (0x305B)
|
||||
#define WCD938X_MBHC_TEST_CTL (0x305C)
|
||||
#define WCD938X_LDOH_MODE (0x3067)
|
||||
#define WCD938X_LDOH_EN_MASK BIT(7)
|
||||
#define WCD938X_LDOH_BIAS (0x3068)
|
||||
#define WCD938X_LDOH_STB_LOADS (0x3069)
|
||||
#define WCD938X_LDOH_SLOWRAMP (0x306A)
|
||||
#define WCD938X_MICB1_TEST_CTL_1 (0x306B)
|
||||
#define WCD938X_MICB1_TEST_CTL_2 (0x306C)
|
||||
#define WCD938X_MICB1_TEST_CTL_3 (0x306D)
|
||||
#define WCD938X_MICB2_TEST_CTL_1 (0x306E)
|
||||
#define WCD938X_MICB2_TEST_CTL_2 (0x306F)
|
||||
#define WCD938X_MICB2_TEST_CTL_3 (0x3070)
|
||||
#define WCD938X_MICB3_TEST_CTL_1 (0x3071)
|
||||
#define WCD938X_MICB3_TEST_CTL_2 (0x3072)
|
||||
#define WCD938X_MICB3_TEST_CTL_3 (0x3073)
|
||||
#define WCD938X_MICB4_TEST_CTL_1 (0x3074)
|
||||
#define WCD938X_MICB4_TEST_CTL_2 (0x3075)
|
||||
#define WCD938X_MICB4_TEST_CTL_3 (0x3076)
|
||||
#define WCD938X_TX_COM_ADC_VCM (0x3077)
|
||||
#define WCD938X_TX_COM_BIAS_ATEST (0x3078)
|
||||
#define WCD938X_TX_COM_SPARE1 (0x3079)
|
||||
#define WCD938X_TX_COM_SPARE2 (0x307A)
|
||||
#define WCD938X_TX_COM_TXFE_DIV_CTL (0x307B)
|
||||
#define WCD938X_TX_COM_TXFE_DIV_START (0x307C)
|
||||
#define WCD938X_TX_COM_SPARE3 (0x307D)
|
||||
#define WCD938X_TX_COM_SPARE4 (0x307E)
|
||||
#define WCD938X_TX_1_2_TEST_EN (0x307F)
|
||||
#define WCD938X_TX_1_2_ADC_IB (0x3080)
|
||||
#define WCD938X_TX_1_2_ATEST_REFCTL (0x3081)
|
||||
#define WCD938X_TX_1_2_TEST_CTL (0x3082)
|
||||
#define WCD938X_TX_1_2_TEST_BLK_EN1 (0x3083)
|
||||
#define WCD938X_TX_1_2_TXFE1_CLKDIV (0x3084)
|
||||
#define WCD938X_TX_1_2_SAR2_ERR (0x3085)
|
||||
#define WCD938X_TX_1_2_SAR1_ERR (0x3086)
|
||||
#define WCD938X_TX_3_4_TEST_EN (0x3087)
|
||||
#define WCD938X_TX_3_4_ADC_IB (0x3088)
|
||||
#define WCD938X_TX_3_4_ATEST_REFCTL (0x3089)
|
||||
#define WCD938X_TX_3_4_TEST_CTL (0x308A)
|
||||
#define WCD938X_TX_3_4_TEST_BLK_EN3 (0x308B)
|
||||
#define WCD938X_TX_3_4_TXFE3_CLKDIV (0x308C)
|
||||
#define WCD938X_TX_3_4_SAR4_ERR (0x308D)
|
||||
#define WCD938X_TX_3_4_SAR3_ERR (0x308E)
|
||||
#define WCD938X_TX_3_4_TEST_BLK_EN2 (0x308F)
|
||||
#define WCD938X_TX_3_4_TXFE2_CLKDIV (0x3090)
|
||||
#define WCD938X_TX_3_4_SPARE1 (0x3091)
|
||||
#define WCD938X_TX_3_4_TEST_BLK_EN4 (0x3092)
|
||||
#define WCD938X_TX_3_4_TXFE4_CLKDIV (0x3093)
|
||||
#define WCD938X_TX_3_4_SPARE2 (0x3094)
|
||||
#define WCD938X_CLASSH_MODE_1 (0x3097)
|
||||
#define WCD938X_CLASSH_MODE_2 (0x3098)
|
||||
#define WCD938X_CLASSH_MODE_3 (0x3099)
|
||||
#define WCD938X_CLASSH_CTRL_VCL_1 (0x309A)
|
||||
#define WCD938X_CLASSH_CTRL_VCL_2 (0x309B)
|
||||
#define WCD938X_CLASSH_CTRL_CCL_1 (0x309C)
|
||||
#define WCD938X_CLASSH_CTRL_CCL_2 (0x309D)
|
||||
#define WCD938X_CLASSH_CTRL_CCL_3 (0x309E)
|
||||
#define WCD938X_CLASSH_CTRL_CCL_4 (0x309F)
|
||||
#define WCD938X_CLASSH_CTRL_CCL_5 (0x30A0)
|
||||
#define WCD938X_CLASSH_BUCK_TMUX_A_D (0x30A1)
|
||||
#define WCD938X_CLASSH_BUCK_SW_DRV_CNTL (0x30A2)
|
||||
#define WCD938X_CLASSH_SPARE (0x30A3)
|
||||
#define WCD938X_FLYBACK_EN (0x30A4)
|
||||
#define WCD938X_EN_CUR_DET_MASK BIT(2)
|
||||
#define WCD938X_FLYBACK_VNEG_CTRL_1 (0x30A5)
|
||||
#define WCD938X_FLYBACK_VNEG_CTRL_2 (0x30A6)
|
||||
#define WCD938X_FLYBACK_VNEG_CTRL_3 (0x30A7)
|
||||
#define WCD938X_FLYBACK_VNEG_CTRL_4 (0x30A8)
|
||||
#define WCD938X_FLYBACK_VNEG_CTRL_5 (0x30A9)
|
||||
#define WCD938X_FLYBACK_VNEG_CTRL_6 (0x30AA)
|
||||
#define WCD938X_FLYBACK_VNEG_CTRL_7 (0x30AB)
|
||||
#define WCD938X_FLYBACK_VNEG_CTRL_8 (0x30AC)
|
||||
#define WCD938X_FLYBACK_VNEG_CTRL_9 (0x30AD)
|
||||
#define WCD938X_FLYBACK_VNEGDAC_CTRL_1 (0x30AE)
|
||||
#define WCD938X_FLYBACK_VNEGDAC_CTRL_2 (0x30AF)
|
||||
#define WCD938X_FLYBACK_VNEGDAC_CTRL_3 (0x30B0)
|
||||
#define WCD938X_FLYBACK_CTRL_1 (0x30B1)
|
||||
#define WCD938X_FLYBACK_TEST_CTL (0x30B2)
|
||||
#define WCD938X_RX_AUX_SW_CTL (0x30B3)
|
||||
#define WCD938X_RX_PA_AUX_IN_CONN (0x30B4)
|
||||
#define WCD938X_RX_TIMER_DIV (0x30B5)
|
||||
#define WCD938X_RX_OCP_CTL (0x30B6)
|
||||
#define WCD938X_RX_OCP_COUNT (0x30B7)
|
||||
#define WCD938X_RX_BIAS_EAR_DAC (0x30B8)
|
||||
#define WCD938X_RX_BIAS_EAR_AMP (0x30B9)
|
||||
#define WCD938X_RX_BIAS_HPH_LDO (0x30BA)
|
||||
#define WCD938X_RX_BIAS_HPH_PA (0x30BB)
|
||||
#define WCD938X_RX_BIAS_HPH_RDACBUFF_CNP2 (0x30BC)
|
||||
#define WCD938X_RX_BIAS_HPH_RDAC_LDO (0x30BD)
|
||||
#define WCD938X_RX_BIAS_HPH_CNP1 (0x30BE)
|
||||
#define WCD938X_RX_BIAS_HPH_LOWPOWER (0x30BF)
|
||||
#define WCD938X_RX_BIAS_AUX_DAC (0x30C0)
|
||||
#define WCD938X_RX_BIAS_AUX_AMP (0x30C1)
|
||||
#define WCD938X_RX_BIAS_VNEGDAC_BLEEDER (0x30C2)
|
||||
#define WCD938X_RX_BIAS_MISC (0x30C3)
|
||||
#define WCD938X_RX_BIAS_BUCK_RST (0x30C4)
|
||||
#define WCD938X_RX_BIAS_BUCK_VREF_ERRAMP (0x30C5)
|
||||
#define WCD938X_RX_BIAS_FLYB_ERRAMP (0x30C6)
|
||||
#define WCD938X_RX_BIAS_FLYB_BUFF (0x30C7)
|
||||
#define WCD938X_RX_BIAS_FLYB_MID_RST (0x30C8)
|
||||
#define WCD938X_HPH_L_STATUS (0x30C9)
|
||||
#define WCD938X_HPH_R_STATUS (0x30CA)
|
||||
#define WCD938X_HPH_CNP_EN (0x30CB)
|
||||
#define WCD938X_HPH_CNP_WG_CTL (0x30CC)
|
||||
#define WCD938X_HPH_CNP_WG_TIME (0x30CD)
|
||||
#define WCD938X_HPH_OCP_CTL (0x30CE)
|
||||
#define WCD938X_HPH_AUTO_CHOP (0x30CF)
|
||||
#define WCD938X_HPH_CHOP_CTL (0x30D0)
|
||||
#define WCD938X_HPH_PA_CTL1 (0x30D1)
|
||||
#define WCD938X_HPH_PA_CTL2 (0x30D2)
|
||||
#define WCD938X_HPHPA_GND_R_MASK BIT(6)
|
||||
#define WCD938X_HPHPA_GND_L_MASK BIT(4)
|
||||
#define WCD938X_HPH_L_EN (0x30D3)
|
||||
#define WCD938X_HPH_L_TEST (0x30D4)
|
||||
#define WCD938X_HPH_L_ATEST (0x30D5)
|
||||
#define WCD938X_HPH_R_EN (0x30D6)
|
||||
#define WCD938X_GAIN_SRC_SEL_MASK BIT(5)
|
||||
#define WCD938X_GAIN_SRC_SEL_REGISTER 1
|
||||
#define WCD938X_HPH_R_TEST (0x30D7)
|
||||
#define WCD938X_HPH_R_ATEST (0x30D8)
|
||||
#define WCD938X_HPHPA_GND_OVR_MASK BIT(1)
|
||||
#define WCD938X_HPH_RDAC_CLK_CTL1 (0x30D9)
|
||||
#define WCD938X_CHOP_CLK_EN_MASK BIT(7)
|
||||
#define WCD938X_HPH_RDAC_CLK_CTL2 (0x30DA)
|
||||
#define WCD938X_HPH_RDAC_LDO_CTL (0x30DB)
|
||||
#define WCD938X_HPH_RDAC_CHOP_CLK_LP_CTL (0x30DC)
|
||||
#define WCD938X_HPH_REFBUFF_UHQA_CTL (0x30DD)
|
||||
#define WCD938X_HPH_REFBUFF_LP_CTL (0x30DE)
|
||||
#define WCD938X_PREREF_FLIT_BYPASS_MASK BIT(0)
|
||||
#define WCD938X_HPH_L_DAC_CTL (0x30DF)
|
||||
#define WCD938X_HPH_R_DAC_CTL (0x30E0)
|
||||
#define WCD938X_HPH_SURGE_HPHLR_SURGE_COMP_SEL (0x30E1)
|
||||
#define WCD938X_HPH_SURGE_HPHLR_SURGE_EN (0x30E2)
|
||||
#define WCD938X_HPH_SURGE_HPHLR_SURGE_MISC1 (0x30E3)
|
||||
#define WCD938X_HPH_SURGE_HPHLR_SURGE_STATUS (0x30E4)
|
||||
#define WCD938X_EAR_EAR_EN_REG (0x30E9)
|
||||
#define WCD938X_EAR_EAR_PA_CON (0x30EA)
|
||||
#define WCD938X_EAR_EAR_SP_CON (0x30EB)
|
||||
#define WCD938X_EAR_EAR_DAC_CON (0x30EC)
|
||||
#define WCD938X_DAC_SAMPLE_EDGE_SEL_MASK BIT(7)
|
||||
#define WCD938X_EAR_EAR_CNP_FSM_CON (0x30ED)
|
||||
#define WCD938X_EAR_TEST_CTL (0x30EE)
|
||||
#define WCD938X_EAR_STATUS_REG_1 (0x30EF)
|
||||
#define WCD938X_EAR_STATUS_REG_2 (0x30F0)
|
||||
#define WCD938X_ANA_NEW_PAGE_REGISTER (0x3100)
|
||||
#define WCD938X_HPH_NEW_ANA_HPH2 (0x3101)
|
||||
#define WCD938X_HPH_NEW_ANA_HPH3 (0x3102)
|
||||
#define WCD938X_SLEEP_CTL (0x3103)
|
||||
#define WCD938X_SLEEP_WATCHDOG_CTL (0x3104)
|
||||
#define WCD938X_MBHC_NEW_ELECT_REM_CLAMP_CTL (0x311F)
|
||||
#define WCD938X_MBHC_NEW_CTL_1 (0x3120)
|
||||
#define WCD938X_MBHC_CTL_RCO_EN_MASK BIT(7)
|
||||
#define WCD938X_MBHC_CTL_RCO_EN BIT(7)
|
||||
#define WCD938X_MBHC_BTN_DBNC_MASK GENMASK(1, 0)
|
||||
#define WCD938X_MBHC_BTN_DBNC_T_16_MS 0x2
|
||||
#define WCD938X_MBHC_NEW_CTL_2 (0x3121)
|
||||
#define WCD938X_M_RTH_CTL_MASK GENMASK(3, 2)
|
||||
#define WCD938X_MBHC_HS_VREF_CTL_MASK GENMASK(1, 0)
|
||||
#define WCD938X_MBHC_HS_VREF_1P5_V 0x1
|
||||
#define WCD938X_MBHC_NEW_PLUG_DETECT_CTL (0x3122)
|
||||
#define WCD938X_MBHC_DBNC_TIMER_INSREM_DBNC_T_96_MS 0x6
|
||||
|
||||
#define WCD938X_MBHC_NEW_ZDET_ANA_CTL (0x3123)
|
||||
#define WCD938X_ZDET_RANGE_CTL_MASK GENMASK(3, 0)
|
||||
#define WCD938X_ZDET_MAXV_CTL_MASK GENMASK(6, 4)
|
||||
#define WCD938X_MBHC_NEW_ZDET_RAMP_CTL (0x3124)
|
||||
#define WCD938X_MBHC_NEW_FSM_STATUS (0x3125)
|
||||
#define WCD938X_MBHC_NEW_ADC_RESULT (0x3126)
|
||||
#define WCD938X_TX_NEW_AMIC_MUX_CFG (0x3127)
|
||||
#define WCD938X_AUX_AUXPA (0x3128)
|
||||
#define WCD938X_AUXPA_CLK_EN_MASK BIT(4)
|
||||
#define WCD938X_LDORXTX_MODE (0x3129)
|
||||
#define WCD938X_LDORXTX_CONFIG (0x312A)
|
||||
#define WCD938X_DIE_CRACK_DIE_CRK_DET_EN (0x312C)
|
||||
#define WCD938X_DIE_CRACK_DIE_CRK_DET_OUT (0x312D)
|
||||
#define WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL (0x3132)
|
||||
#define WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L (0x3133)
|
||||
#define WCD938X_HPH_NEW_INT_RDAC_VREF_CTL (0x3134)
|
||||
#define WCD938X_HPH_NEW_INT_RDAC_OVERRIDE_CTL (0x3135)
|
||||
#define WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R (0x3136)
|
||||
#define WCD938X_HPH_RES_DIV_MASK GENMASK(4, 0)
|
||||
#define WCD938X_HPH_NEW_INT_PA_MISC1 (0x3137)
|
||||
#define WCD938X_HPH_NEW_INT_PA_MISC2 (0x3138)
|
||||
#define WCD938X_HPH_NEW_INT_PA_RDAC_MISC (0x3139)
|
||||
#define WCD938X_HPH_NEW_INT_HPH_TIMER1 (0x313A)
|
||||
#define WCD938X_AUTOCHOP_TIMER_EN BIT(1)
|
||||
#define WCD938X_HPH_NEW_INT_HPH_TIMER2 (0x313B)
|
||||
#define WCD938X_HPH_NEW_INT_HPH_TIMER3 (0x313C)
|
||||
#define WCD938X_HPH_NEW_INT_HPH_TIMER4 (0x313D)
|
||||
#define WCD938X_HPH_NEW_INT_PA_RDAC_MISC2 (0x313E)
|
||||
#define WCD938X_HPH_NEW_INT_PA_RDAC_MISC3 (0x313F)
|
||||
#define WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW (0x3140)
|
||||
#define WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW (0x3141)
|
||||
#define WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI (0x3145)
|
||||
#define WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_ULP (0x3146)
|
||||
#define WCD938X_RX_NEW_INT_HPH_RDAC_LDO_LP (0x3147)
|
||||
#define WCD938X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL (0x31AF)
|
||||
#define WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL (0x31B0)
|
||||
#define WCD938X_MOISTURE_EN_POLLING_MASK BIT(2)
|
||||
#define WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT (0x31B1)
|
||||
#define WCD938X_HSDET_PULLUP_C_MASK GENMASK(4, 0)
|
||||
#define WCD938X_MBHC_NEW_INT_SPARE_2 (0x31B2)
|
||||
#define WCD938X_EAR_INT_NEW_EAR_CHOPPER_CON (0x31B7)
|
||||
#define WCD938X_EAR_INT_NEW_CNP_VCM_CON1 (0x31B8)
|
||||
#define WCD938X_EAR_INT_NEW_CNP_VCM_CON2 (0x31B9)
|
||||
#define WCD938X_EAR_INT_NEW_EAR_DYNAMIC_BIAS (0x31BA)
|
||||
#define WCD938X_AUX_INT_EN_REG (0x31BD)
|
||||
#define WCD938X_AUX_INT_PA_CTRL (0x31BE)
|
||||
#define WCD938X_AUX_INT_SP_CTRL (0x31BF)
|
||||
#define WCD938X_AUX_INT_DAC_CTRL (0x31C0)
|
||||
#define WCD938X_AUX_INT_CLK_CTRL (0x31C1)
|
||||
#define WCD938X_AUX_INT_TEST_CTRL (0x31C2)
|
||||
#define WCD938X_AUX_INT_STATUS_REG (0x31C3)
|
||||
#define WCD938X_AUX_INT_MISC (0x31C4)
|
||||
#define WCD938X_LDORXTX_INT_BIAS (0x31C5)
|
||||
#define WCD938X_LDORXTX_INT_STB_LOADS_DTEST (0x31C6)
|
||||
#define WCD938X_LDORXTX_INT_TEST0 (0x31C7)
|
||||
#define WCD938X_LDORXTX_INT_STARTUP_TIMER (0x31C8)
|
||||
#define WCD938X_LDORXTX_INT_TEST1 (0x31C9)
|
||||
#define WCD938X_LDORXTX_INT_STATUS (0x31CA)
|
||||
#define WCD938X_SLEEP_INT_WATCHDOG_CTL_1 (0x31D0)
|
||||
#define WCD938X_SLEEP_INT_WATCHDOG_CTL_2 (0x31D1)
|
||||
#define WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT1 (0x31D3)
|
||||
#define WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT2 (0x31D4)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L2 (0x31D5)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L1 (0x31D6)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L0 (0x31D7)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP1P2M (0x31D8)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP0P6M (0x31D9)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L2L1 (0x31DA)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L0 (0x31DB)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_ULP (0x31DC)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L2L1 (0x31DD)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L0 (0x31DE)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP (0x31DF)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_L2L1L0 (0x31E0)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP (0x31E1)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L2L1 (0x31E2)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L0ULP (0x31E3)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXADC_INT_L2 (0x31E4)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXADC_INT_L1 (0x31E5)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXADC_INT_L0 (0x31E6)
|
||||
#define WCD938X_TX_COM_NEW_INT_TXADC_INT_ULP (0x31E7)
|
||||
#define WCD938X_DIGITAL_PAGE_REGISTER (0x3400)
|
||||
#define WCD938X_DIGITAL_CHIP_ID0 (0x3401)
|
||||
#define WCD938X_DIGITAL_CHIP_ID1 (0x3402)
|
||||
#define WCD938X_DIGITAL_CHIP_ID2 (0x3403)
|
||||
#define WCD938X_DIGITAL_CHIP_ID3 (0x3404)
|
||||
#define WCD938X_DIGITAL_SWR_TX_CLK_RATE (0x3405)
|
||||
#define WCD938X_DIGITAL_CDC_RST_CTL (0x3406)
|
||||
#define WCD938X_DIGITAL_TOP_CLK_CFG (0x3407)
|
||||
#define WCD938X_DIGITAL_CDC_ANA_CLK_CTL (0x3408)
|
||||
#define WCD938X_ANA_RX_CLK_EN_MASK BIT(0)
|
||||
#define WCD938X_ANA_RX_DIV2_CLK_EN_MASK BIT(1)
|
||||
#define WCD938X_ANA_RX_DIV4_CLK_EN_MASK BIT(2)
|
||||
#define WCD938X_ANA_TX_CLK_EN_MASK BIT(3)
|
||||
#define WCD938X_ANA_TX_DIV2_CLK_EN_MASK BIT(4)
|
||||
#define WCD938X_ANA_TX_DIV4_CLK_EN_MASK BIT(5)
|
||||
#define WCD938X_DIGITAL_CDC_DIG_CLK_CTL (0x3409)
|
||||
#define WCD938X_TXD3_CLK_EN_MASK BIT(7)
|
||||
#define WCD938X_TXD2_CLK_EN_MASK BIT(6)
|
||||
#define WCD938X_TXD1_CLK_EN_MASK BIT(5)
|
||||
#define WCD938X_TXD0_CLK_EN_MASK BIT(4)
|
||||
#define WCD938X_TX_CLK_EN_MASK GENMASK(7, 4)
|
||||
#define WCD938X_RXD2_CLK_EN_MASK BIT(2)
|
||||
#define WCD938X_RXD1_CLK_EN_MASK BIT(1)
|
||||
#define WCD938X_RXD0_CLK_EN_MASK BIT(0)
|
||||
#define WCD938X_DIGITAL_SWR_RST_EN (0x340A)
|
||||
#define WCD938X_DIGITAL_CDC_PATH_MODE (0x340B)
|
||||
#define WCD938X_DIGITAL_CDC_RX_RST (0x340C)
|
||||
#define WCD938X_DIGITAL_CDC_RX0_CTL (0x340D)
|
||||
#define WCD938X_DEM_DITHER_ENABLE_MASK BIT(6)
|
||||
#define WCD938X_DIGITAL_CDC_RX1_CTL (0x340E)
|
||||
#define WCD938X_DIGITAL_CDC_RX2_CTL (0x340F)
|
||||
#define WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1 (0x3410)
|
||||
#define WCD938X_TXD0_MODE_MASK GENMASK(3, 0)
|
||||
#define WCD938X_TXD1_MODE_MASK GENMASK(7, 4)
|
||||
#define WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3 (0x3411)
|
||||
#define WCD938X_TXD2_MODE_MASK GENMASK(3, 0)
|
||||
#define WCD938X_TXD3_MODE_MASK GENMASK(7, 4)
|
||||
#define WCD938X_DIGITAL_CDC_COMP_CTL_0 (0x3414)
|
||||
#define WCD938X_HPHR_COMP_EN_MASK BIT(0)
|
||||
#define WCD938X_HPHL_COMP_EN_MASK BIT(1)
|
||||
#define WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL (0x3417)
|
||||
#define WCD938X_TX_SC_CLK_EN_MASK BIT(0)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_A1_0 (0x3418)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_A1_1 (0x3419)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_A2_0 (0x341A)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_A2_1 (0x341B)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_A3_0 (0x341C)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_A3_1 (0x341D)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_A4_0 (0x341E)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_A4_1 (0x341F)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_A5_0 (0x3420)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_A5_1 (0x3421)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_A6_0 (0x3422)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_A7_0 (0x3423)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_C_0 (0x3424)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_C_1 (0x3425)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_C_2 (0x3426)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_C_3 (0x3427)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_R1 (0x3428)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_R2 (0x3429)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_R3 (0x342A)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_R4 (0x342B)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_R5 (0x342C)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_R6 (0x342D)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_DSM_R7 (0x342E)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_A1_0 (0x342F)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_A1_1 (0x3430)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_A2_0 (0x3431)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_A2_1 (0x3432)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_A3_0 (0x3433)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_A3_1 (0x3434)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_A4_0 (0x3435)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_A4_1 (0x3436)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_A5_0 (0x3437)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_A5_1 (0x3438)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_A6_0 (0x3439)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_A7_0 (0x343A)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_C_0 (0x343B)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_C_1 (0x343C)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_C_2 (0x343D)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_C_3 (0x343E)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_R1 (0x343F)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_R2 (0x3440)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_R3 (0x3441)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_R4 (0x3442)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_R5 (0x3443)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_R6 (0x3444)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_DSM_R7 (0x3445)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_GAIN_RX_0 (0x3446)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_GAIN_RX_1 (0x3447)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_0 (0x3448)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_1 (0x3449)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_2 (0x344A)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_0 (0x344B)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_1 (0x344C)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_2 (0x344D)
|
||||
#define WCD938X_DIGITAL_CDC_HPH_GAIN_CTL (0x344E)
|
||||
#define WCD938X_HPHL_RX_EN_MASK BIT(2)
|
||||
#define WCD938X_HPHR_RX_EN_MASK BIT(3)
|
||||
#define WCD938X_DIGITAL_CDC_AUX_GAIN_CTL (0x344F)
|
||||
#define WCD938X_AUX_EN_MASK BIT(0)
|
||||
#define WCD938X_DIGITAL_CDC_EAR_PATH_CTL (0x3450)
|
||||
#define WCD938X_DIGITAL_CDC_SWR_CLH (0x3451)
|
||||
#define WCD938X_DIGITAL_SWR_CLH_BYP (0x3452)
|
||||
#define WCD938X_DIGITAL_CDC_TX0_CTL (0x3453)
|
||||
#define WCD938X_DIGITAL_CDC_TX1_CTL (0x3454)
|
||||
#define WCD938X_DIGITAL_CDC_TX2_CTL (0x3455)
|
||||
#define WCD938X_DIGITAL_CDC_TX_RST (0x3456)
|
||||
#define WCD938X_DIGITAL_CDC_REQ_CTL (0x3457)
|
||||
#define WCD938X_FS_RATE_4P8_MASK BIT(1)
|
||||
#define WCD938X_NO_NOTCH_MASK BIT(0)
|
||||
#define WCD938X_DIGITAL_CDC_RST (0x3458)
|
||||
#define WCD938X_DIGITAL_CDC_AMIC_CTL (0x345A)
|
||||
#define WCD938X_AMIC1_IN_SEL_DMIC 0
|
||||
#define WCD938X_AMIC1_IN_SEL_AMIC 0
|
||||
#define WCD938X_AMIC1_IN_SEL_MASK BIT(0)
|
||||
#define WCD938X_AMIC3_IN_SEL_MASK BIT(1)
|
||||
#define WCD938X_AMIC4_IN_SEL_MASK BIT(2)
|
||||
#define WCD938X_AMIC5_IN_SEL_MASK BIT(3)
|
||||
#define WCD938X_DIGITAL_CDC_DMIC_CTL (0x345B)
|
||||
#define WCD938X_DMIC_CLK_SCALING_EN_MASK GENMASK(2, 1)
|
||||
#define WCD938X_DIGITAL_CDC_DMIC1_CTL (0x345C)
|
||||
#define WCD938X_DMIC_CLK_EN_MASK BIT(3)
|
||||
#define WCD938X_DIGITAL_CDC_DMIC2_CTL (0x345D)
|
||||
#define WCD938X_DIGITAL_CDC_DMIC3_CTL (0x345E)
|
||||
#define WCD938X_DIGITAL_CDC_DMIC4_CTL (0x345F)
|
||||
#define WCD938X_DIGITAL_EFUSE_PRG_CTL (0x3460)
|
||||
#define WCD938X_DIGITAL_EFUSE_CTL (0x3461)
|
||||
#define WCD938X_DIGITAL_CDC_DMIC_RATE_1_2 (0x3462)
|
||||
#define WCD938X_DIGITAL_CDC_DMIC_RATE_3_4 (0x3463)
|
||||
#define WCD938X_DMIC1_RATE_MASK GENMASK(3, 0)
|
||||
#define WCD938X_DMIC2_RATE_MASK GENMASK(7, 4)
|
||||
#define WCD938X_DMIC3_RATE_MASK GENMASK(3, 0)
|
||||
#define WCD938X_DMIC4_RATE_MASK GENMASK(7, 4)
|
||||
#define WCD938X_DMIC4_RATE_2P4MHZ 3
|
||||
|
||||
#define WCD938X_DIGITAL_PDM_WD_CTL0 (0x3465)
|
||||
#define WCD938X_PDM_WD_EN_MASK GENMASK(2, 0)
|
||||
#define WCD938X_DIGITAL_PDM_WD_CTL1 (0x3466)
|
||||
#define WCD938X_DIGITAL_PDM_WD_CTL2 (0x3467)
|
||||
#define WCD938X_AUX_PDM_WD_EN_MASK GENMASK(2, 0)
|
||||
#define WCD938X_DIGITAL_INTR_MODE (0x346A)
|
||||
#define WCD938X_DIGITAL_INTR_MASK_0 (0x346B)
|
||||
#define WCD938X_DIGITAL_INTR_MASK_1 (0x346C)
|
||||
#define WCD938X_DIGITAL_INTR_MASK_2 (0x346D)
|
||||
#define WCD938X_DIGITAL_INTR_STATUS_0 (0x346E)
|
||||
#define WCD938X_DIGITAL_INTR_STATUS_1 (0x346F)
|
||||
#define WCD938X_DIGITAL_INTR_STATUS_2 (0x3470)
|
||||
#define WCD938X_DIGITAL_INTR_CLEAR_0 (0x3471)
|
||||
#define WCD938X_DIGITAL_INTR_CLEAR_1 (0x3472)
|
||||
#define WCD938X_DIGITAL_INTR_CLEAR_2 (0x3473)
|
||||
#define WCD938X_DIGITAL_INTR_LEVEL_0 (0x3474)
|
||||
#define WCD938X_DIGITAL_INTR_LEVEL_1 (0x3475)
|
||||
#define WCD938X_DIGITAL_INTR_LEVEL_2 (0x3476)
|
||||
#define WCD938X_DIGITAL_INTR_SET_0 (0x3477)
|
||||
#define WCD938X_DIGITAL_INTR_SET_1 (0x3478)
|
||||
#define WCD938X_DIGITAL_INTR_SET_2 (0x3479)
|
||||
#define WCD938X_DIGITAL_INTR_TEST_0 (0x347A)
|
||||
#define WCD938X_DIGITAL_INTR_TEST_1 (0x347B)
|
||||
#define WCD938X_DIGITAL_INTR_TEST_2 (0x347C)
|
||||
#define WCD938X_DIGITAL_TX_MODE_DBG_EN (0x347F)
|
||||
#define WCD938X_DIGITAL_TX_MODE_DBG_0_1 (0x3480)
|
||||
#define WCD938X_DIGITAL_TX_MODE_DBG_2_3 (0x3481)
|
||||
#define WCD938X_DIGITAL_LB_IN_SEL_CTL (0x3482)
|
||||
#define WCD938X_DIGITAL_LOOP_BACK_MODE (0x3483)
|
||||
#define WCD938X_DIGITAL_SWR_DAC_TEST (0x3484)
|
||||
#define WCD938X_DIGITAL_SWR_HM_TEST_RX_0 (0x3485)
|
||||
#define WCD938X_DIGITAL_SWR_HM_TEST_TX_0 (0x3486)
|
||||
#define WCD938X_DIGITAL_SWR_HM_TEST_RX_1 (0x3487)
|
||||
#define WCD938X_DIGITAL_SWR_HM_TEST_TX_1 (0x3488)
|
||||
#define WCD938X_DIGITAL_SWR_HM_TEST_TX_2 (0x3489)
|
||||
#define WCD938X_DIGITAL_SWR_HM_TEST_0 (0x348A)
|
||||
#define WCD938X_DIGITAL_SWR_HM_TEST_1 (0x348B)
|
||||
#define WCD938X_DIGITAL_PAD_CTL_SWR_0 (0x348C)
|
||||
#define WCD938X_DIGITAL_PAD_CTL_SWR_1 (0x348D)
|
||||
#define WCD938X_DIGITAL_I2C_CTL (0x348E)
|
||||
#define WCD938X_DIGITAL_CDC_TX_TANGGU_SW_MODE (0x348F)
|
||||
#define WCD938X_DIGITAL_EFUSE_TEST_CTL_0 (0x3490)
|
||||
#define WCD938X_DIGITAL_EFUSE_TEST_CTL_1 (0x3491)
|
||||
#define WCD938X_DIGITAL_EFUSE_T_DATA_0 (0x3492)
|
||||
#define WCD938X_DIGITAL_EFUSE_T_DATA_1 (0x3493)
|
||||
#define WCD938X_DIGITAL_PAD_CTL_PDM_RX0 (0x3494)
|
||||
#define WCD938X_DIGITAL_PAD_CTL_PDM_RX1 (0x3495)
|
||||
#define WCD938X_DIGITAL_PAD_CTL_PDM_TX0 (0x3496)
|
||||
#define WCD938X_DIGITAL_PAD_CTL_PDM_TX1 (0x3497)
|
||||
#define WCD938X_DIGITAL_PAD_CTL_PDM_TX2 (0x3498)
|
||||
#define WCD938X_DIGITAL_PAD_INP_DIS_0 (0x3499)
|
||||
#define WCD938X_DIGITAL_PAD_INP_DIS_1 (0x349A)
|
||||
#define WCD938X_DIGITAL_DRIVE_STRENGTH_0 (0x349B)
|
||||
#define WCD938X_DIGITAL_DRIVE_STRENGTH_1 (0x349C)
|
||||
#define WCD938X_DIGITAL_DRIVE_STRENGTH_2 (0x349D)
|
||||
#define WCD938X_DIGITAL_RX_DATA_EDGE_CTL (0x349E)
|
||||
#define WCD938X_DIGITAL_TX_DATA_EDGE_CTL (0x349F)
|
||||
#define WCD938X_DIGITAL_GPIO_MODE (0x34A0)
|
||||
#define WCD938X_DIGITAL_PIN_CTL_OE (0x34A1)
|
||||
#define WCD938X_DIGITAL_PIN_CTL_DATA_0 (0x34A2)
|
||||
#define WCD938X_DIGITAL_PIN_CTL_DATA_1 (0x34A3)
|
||||
#define WCD938X_DIGITAL_PIN_STATUS_0 (0x34A4)
|
||||
#define WCD938X_DIGITAL_PIN_STATUS_1 (0x34A5)
|
||||
#define WCD938X_DIGITAL_DIG_DEBUG_CTL (0x34A6)
|
||||
#define WCD938X_DIGITAL_DIG_DEBUG_EN (0x34A7)
|
||||
#define WCD938X_DIGITAL_ANA_CSR_DBG_ADD (0x34A8)
|
||||
#define WCD938X_DIGITAL_ANA_CSR_DBG_CTL (0x34A9)
|
||||
#define WCD938X_DIGITAL_SSP_DBG (0x34AA)
|
||||
#define WCD938X_DIGITAL_MODE_STATUS_0 (0x34AB)
|
||||
#define WCD938X_DIGITAL_MODE_STATUS_1 (0x34AC)
|
||||
#define WCD938X_DIGITAL_SPARE_0 (0x34AD)
|
||||
#define WCD938X_DIGITAL_SPARE_1 (0x34AE)
|
||||
#define WCD938X_DIGITAL_SPARE_2 (0x34AF)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_0 (0x34B0)
|
||||
#define WCD938X_ID_MASK GENMASK(4, 1)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_1 (0x34B1)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_2 (0x34B2)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_3 (0x34B3)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_4 (0x34B4)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_5 (0x34B5)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_6 (0x34B6)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_7 (0x34B7)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_8 (0x34B8)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_9 (0x34B9)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_10 (0x34BA)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_11 (0x34BB)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_12 (0x34BC)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_13 (0x34BD)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_14 (0x34BE)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_15 (0x34BF)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_16 (0x34C0)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_17 (0x34C1)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_18 (0x34C2)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_19 (0x34C3)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_20 (0x34C4)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_21 (0x34C5)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_22 (0x34C6)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_23 (0x34C7)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_24 (0x34C8)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_25 (0x34C9)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_26 (0x34CA)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_27 (0x34CB)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_28 (0x34CC)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_29 (0x34CD)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_30 (0x34CE)
|
||||
#define WCD938X_DIGITAL_EFUSE_REG_31 (0x34CF)
|
||||
#define WCD938X_DIGITAL_TX_REQ_FB_CTL_0 (0x34D0)
|
||||
#define WCD938X_DIGITAL_TX_REQ_FB_CTL_1 (0x34D1)
|
||||
#define WCD938X_DIGITAL_TX_REQ_FB_CTL_2 (0x34D2)
|
||||
#define WCD938X_DIGITAL_TX_REQ_FB_CTL_3 (0x34D3)
|
||||
#define WCD938X_DIGITAL_TX_REQ_FB_CTL_4 (0x34D4)
|
||||
#define WCD938X_DIGITAL_DEM_BYPASS_DATA0 (0x34D5)
|
||||
#define WCD938X_DIGITAL_DEM_BYPASS_DATA1 (0x34D6)
|
||||
#define WCD938X_DIGITAL_DEM_BYPASS_DATA2 (0x34D7)
|
||||
#define WCD938X_DIGITAL_DEM_BYPASS_DATA3 (0x34D8)
|
||||
#define WCD938X_MAX_REGISTER (WCD938X_DIGITAL_DEM_BYPASS_DATA3)
|
||||
|
||||
#define WCD938X_MAX_SWR_PORTS 5
|
||||
#define WCD938X_MAX_TX_SWR_PORTS 4
|
||||
#define WCD938X_MAX_SWR_CH_IDS 15
|
||||
|
||||
struct wcd938x_sdw_ch_info {
|
||||
int port_num;
|
||||
unsigned int ch_mask;
|
||||
};
|
||||
|
||||
#define WCD_SDW_CH(id, pn, cmask) \
|
||||
[id] = { \
|
||||
.port_num = pn, \
|
||||
.ch_mask = cmask, \
|
||||
}
|
||||
|
||||
enum wcd938x_tx_sdw_ports {
|
||||
WCD938X_ADC_1_2_PORT = 1,
|
||||
WCD938X_ADC_3_4_PORT,
|
||||
/* DMIC0_0, DMIC0_1, DMIC1_0, DMIC1_1 */
|
||||
WCD938X_DMIC_0_3_MBHC_PORT,
|
||||
WCD938X_DMIC_4_7_PORT,
|
||||
};
|
||||
|
||||
enum wcd938x_tx_sdw_channels {
|
||||
WCD938X_ADC1,
|
||||
WCD938X_ADC2,
|
||||
WCD938X_ADC3,
|
||||
WCD938X_ADC4,
|
||||
WCD938X_DMIC0,
|
||||
WCD938X_DMIC1,
|
||||
WCD938X_MBHC,
|
||||
WCD938X_DMIC2,
|
||||
WCD938X_DMIC3,
|
||||
WCD938X_DMIC4,
|
||||
WCD938X_DMIC5,
|
||||
WCD938X_DMIC6,
|
||||
WCD938X_DMIC7,
|
||||
};
|
||||
|
||||
enum wcd938x_rx_sdw_ports {
|
||||
WCD938X_HPH_PORT = 1,
|
||||
WCD938X_CLSH_PORT,
|
||||
WCD938X_COMP_PORT,
|
||||
WCD938X_LO_PORT,
|
||||
WCD938X_DSD_PORT,
|
||||
};
|
||||
|
||||
enum wcd938x_rx_sdw_channels {
|
||||
WCD938X_HPH_L,
|
||||
WCD938X_HPH_R,
|
||||
WCD938X_CLSH,
|
||||
WCD938X_COMP_L,
|
||||
WCD938X_COMP_R,
|
||||
WCD938X_LO,
|
||||
WCD938X_DSD_R,
|
||||
WCD938X_DSD_L,
|
||||
};
|
||||
enum {
|
||||
WCD938X_SDW_DIR_RX,
|
||||
WCD938X_SDW_DIR_TX,
|
||||
};
|
||||
|
||||
struct wcd938x_priv;
|
||||
struct wcd938x_sdw_priv {
|
||||
struct sdw_slave *sdev;
|
||||
struct sdw_stream_config sconfig;
|
||||
struct sdw_stream_runtime *sruntime;
|
||||
struct sdw_port_config port_config[WCD938X_MAX_SWR_PORTS];
|
||||
struct wcd938x_sdw_ch_info *ch_info;
|
||||
bool port_enable[WCD938X_MAX_SWR_CH_IDS];
|
||||
int port_map[WCD938X_MAX_SWR_PORTS];
|
||||
int active_ports;
|
||||
int num_ports;
|
||||
bool is_tx;
|
||||
struct wcd938x_priv *wcd938x;
|
||||
struct irq_domain *slave_irq;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_WCD938X_SDW)
|
||||
int wcd938x_sdw_free(struct wcd938x_sdw_priv *wcd,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai);
|
||||
int wcd938x_sdw_set_sdw_stream(struct wcd938x_sdw_priv *wcd,
|
||||
struct snd_soc_dai *dai,
|
||||
void *stream, int direction);
|
||||
int wcd938x_sdw_hw_params(struct wcd938x_sdw_priv *wcd,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai);
|
||||
|
||||
struct device *wcd938x_sdw_device_get(struct device_node *np);
|
||||
int wcd938x_swr_get_current_bank(struct sdw_slave *sdev);
|
||||
|
||||
#else
|
||||
|
||||
static inline int wcd938x_sdw_free(struct wcd938x_sdw_priv *wcd,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int wcd938x_sdw_set_sdw_stream(struct wcd938x_sdw_priv *wcd,
|
||||
struct snd_soc_dai *dai,
|
||||
void *stream, int direction)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int wcd938x_sdw_hw_params(struct wcd938x_sdw_priv *wcd,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline struct device *wcd938x_sdw_device_get(struct device_node *np)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int wcd938x_swr_get_current_bank(struct sdw_slave *sdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SND_SOC_WCD938X_SDW */
|
||||
#endif /* __WCD938X_H__ */
|
@ -30,7 +30,6 @@
|
||||
#include <sound/wm2200.h>
|
||||
|
||||
#include "wm2200.h"
|
||||
#include "wmfw.h"
|
||||
#include "wm_adsp.h"
|
||||
|
||||
#define WM2200_DSP_CONTROL_1 0x00
|
||||
|
@ -1989,7 +1989,7 @@ static unsigned int wm5102_digital_vu[] = {
|
||||
ARIZONA_DAC_DIGITAL_VOLUME_5R,
|
||||
};
|
||||
|
||||
static struct snd_compress_ops wm5102_compress_ops = {
|
||||
static const struct snd_compress_ops wm5102_compress_ops = {
|
||||
.open = wm5102_open,
|
||||
.free = wm_adsp_compr_free,
|
||||
.set_params = wm_adsp_compr_set_params,
|
||||
|
@ -2355,7 +2355,7 @@ static unsigned int wm5110_digital_vu[] = {
|
||||
ARIZONA_DAC_DIGITAL_VOLUME_6R,
|
||||
};
|
||||
|
||||
static struct snd_compress_ops wm5110_compress_ops = {
|
||||
static const struct snd_compress_ops wm5110_compress_ops = {
|
||||
.open = wm5110_open,
|
||||
.free = wm_adsp_compr_free,
|
||||
.set_params = wm_adsp_compr_set_params,
|
||||
|
@ -3219,9 +3219,8 @@ static int wm8962_beep_event(struct input_dev *dev, unsigned int type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t wm8962_beep_set(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
static ssize_t beep_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
|
||||
long int time;
|
||||
@ -3236,7 +3235,7 @@ static ssize_t wm8962_beep_set(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(beep, 0200, NULL, wm8962_beep_set);
|
||||
static DEVICE_ATTR_WO(beep);
|
||||
|
||||
static void wm8962_init_beep(struct snd_soc_component *component)
|
||||
{
|
||||
|
@ -303,9 +303,9 @@
|
||||
#define HALO_MPU_VIO_ERR_SRC_MASK 0x00007fff
|
||||
#define HALO_MPU_VIO_ERR_SRC_SHIFT 0
|
||||
|
||||
static struct wm_adsp_ops wm_adsp1_ops;
|
||||
static struct wm_adsp_ops wm_adsp2_ops[];
|
||||
static struct wm_adsp_ops wm_halo_ops;
|
||||
static const struct wm_adsp_ops wm_adsp1_ops;
|
||||
static const struct wm_adsp_ops wm_adsp2_ops[];
|
||||
static const struct wm_adsp_ops wm_halo_ops;
|
||||
|
||||
struct wm_adsp_buf {
|
||||
struct list_head list;
|
||||
@ -824,7 +824,7 @@ const struct soc_enum wm_adsp_fw_enum[] = {
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(wm_adsp_fw_enum);
|
||||
|
||||
static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp,
|
||||
static const struct wm_adsp_region *wm_adsp_find_region(struct wm_adsp *dsp,
|
||||
int type)
|
||||
{
|
||||
int i;
|
||||
@ -2240,7 +2240,7 @@ static void wmfw_v3_parse_id_header(struct wm_adsp *dsp,
|
||||
}
|
||||
|
||||
static int wm_adsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions,
|
||||
int *type, __be32 *base)
|
||||
const int *type, __be32 *base)
|
||||
{
|
||||
struct wm_adsp_alg_region *alg_region;
|
||||
int i;
|
||||
@ -2487,7 +2487,7 @@ out:
|
||||
static int wm_halo_create_regions(struct wm_adsp *dsp, __be32 id,
|
||||
__be32 xm_base, __be32 ym_base)
|
||||
{
|
||||
int types[] = {
|
||||
static const int types[] = {
|
||||
WMFW_ADSP2_XM, WMFW_HALO_XM_PACKED,
|
||||
WMFW_ADSP2_YM, WMFW_HALO_YM_PACKED
|
||||
};
|
||||
@ -4500,13 +4500,13 @@ irqreturn_t wm_halo_wdt_expire(int irq, void *data)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wm_halo_wdt_expire);
|
||||
|
||||
static struct wm_adsp_ops wm_adsp1_ops = {
|
||||
static const struct wm_adsp_ops wm_adsp1_ops = {
|
||||
.validate_version = wm_adsp_validate_version,
|
||||
.parse_sizes = wm_adsp1_parse_sizes,
|
||||
.region_to_reg = wm_adsp_region_to_reg,
|
||||
};
|
||||
|
||||
static struct wm_adsp_ops wm_adsp2_ops[] = {
|
||||
static const struct wm_adsp_ops wm_adsp2_ops[] = {
|
||||
{
|
||||
.sys_config_size = sizeof(struct wm_adsp_system_config_xm_hdr),
|
||||
.parse_sizes = wm_adsp2_parse_sizes,
|
||||
@ -4567,7 +4567,7 @@ static struct wm_adsp_ops wm_adsp2_ops[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct wm_adsp_ops wm_halo_ops = {
|
||||
static const struct wm_adsp_ops wm_halo_ops = {
|
||||
.sys_config_size = sizeof(struct wm_halo_system_config_xm_hdr),
|
||||
.parse_sizes = wm_adsp2_parse_sizes,
|
||||
.validate_version = wm_halo_validate_version,
|
||||
|
@ -64,7 +64,7 @@ struct wm_adsp {
|
||||
struct regmap *regmap;
|
||||
struct snd_soc_component *component;
|
||||
|
||||
struct wm_adsp_ops *ops;
|
||||
const struct wm_adsp_ops *ops;
|
||||
|
||||
unsigned int base;
|
||||
unsigned int base_sysinfo;
|
||||
|
@ -636,8 +636,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
|
||||
|
||||
dw_i2s_dai->ops = &dw_i2s_dai_ops;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
dev->i2s_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
dev->i2s_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(dev->i2s_base))
|
||||
return PTR_ERR(dev->i2s_base);
|
||||
|
||||
|
@ -351,6 +351,19 @@ config SND_SOC_IMX_RPMSG
|
||||
Say Y if you want to add support for SoC audio on an i.MX board with
|
||||
a rpmsg devices.
|
||||
|
||||
config SND_SOC_IMX_CARD
|
||||
tristate "SoC Audio Graph Sound Card support for i.MX boards"
|
||||
depends on OF && I2C
|
||||
select SND_SOC_AK4458
|
||||
select SND_SOC_AK5558
|
||||
select SND_SOC_IMX_PCM_DMA
|
||||
select SND_SOC_FSL_SAI
|
||||
select SND_SIMPLE_CARD_UTILS
|
||||
help
|
||||
This option enables audio sound card support for i.MX boards
|
||||
with OF-graph DT bindings.
|
||||
It also support DPCM of single CPU multi Codec ststem.
|
||||
|
||||
endif # SND_IMX_SOC
|
||||
|
||||
endmenu
|
||||
|
@ -71,6 +71,7 @@ snd-soc-imx-spdif-objs := imx-spdif.o
|
||||
snd-soc-imx-audmix-objs := imx-audmix.o
|
||||
snd-soc-imx-hdmi-objs := imx-hdmi.o
|
||||
snd-soc-imx-rpmsg-objs := imx-rpmsg.o
|
||||
snd-soc-imx-card-objs := imx-card.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
|
||||
obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o
|
||||
@ -79,3 +80,4 @@ obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
|
||||
obj-$(CONFIG_SND_SOC_IMX_AUDMIX) += snd-soc-imx-audmix.o
|
||||
obj-$(CONFIG_SND_SOC_IMX_HDMI) += snd-soc-imx-hdmi.o
|
||||
obj-$(CONFIG_SND_SOC_IMX_RPMSG) += snd-soc-imx-rpmsg.o
|
||||
obj-$(CONFIG_SND_SOC_IMX_CARD) += snd-soc-imx-card.o
|
||||
|
@ -540,7 +540,6 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
|
||||
struct device *codec_dev = NULL;
|
||||
const char *codec_dai_name;
|
||||
const char *codec_dev_name;
|
||||
unsigned int daifmt;
|
||||
u32 width;
|
||||
int ret;
|
||||
|
||||
@ -684,10 +683,10 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* Format info from DT is optional. */
|
||||
daifmt = snd_soc_of_parse_daifmt(np, NULL,
|
||||
&bitclkmaster, &framemaster);
|
||||
daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
|
||||
snd_soc_daifmt_parse_clock_provider_as_phandle(np, NULL, &bitclkmaster, &framemaster);
|
||||
if (bitclkmaster || framemaster) {
|
||||
unsigned int daifmt = snd_soc_daifmt_parse_format(np, NULL);
|
||||
|
||||
if (codec_np == bitclkmaster)
|
||||
daifmt |= (codec_np == framemaster) ?
|
||||
SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
|
||||
@ -709,7 +708,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
|
||||
of_node_put(framemaster);
|
||||
|
||||
if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) {
|
||||
dev_err(&pdev->dev, "failed to find codec device\n");
|
||||
dev_dbg(&pdev->dev, "failed to find codec device\n");
|
||||
ret = -EPROBE_DEFER;
|
||||
goto asrc_fail;
|
||||
}
|
||||
|
@ -1035,8 +1035,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
|
||||
asrc->private = asrc_priv;
|
||||
|
||||
/* Get the addresses and IRQ */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
|
@ -196,8 +196,7 @@ static int fsl_aud2htx_probe(struct platform_device *pdev)
|
||||
|
||||
aud2htx->pdev = pdev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
|
@ -1887,8 +1887,7 @@ static int fsl_easrc_probe(struct platform_device *pdev)
|
||||
easrc->private = easrc_priv;
|
||||
np = dev->of_node;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
regs = devm_ioremap_resource(dev, res);
|
||||
regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
@ -1901,10 +1900,8 @@ static int fsl_easrc_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(dev, "no irq for node %pOF\n", np);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, fsl_easrc_isr, 0,
|
||||
dev_name(dev), easrc);
|
||||
|
@ -969,8 +969,7 @@ static int fsl_esai_probe(struct platform_device *pdev)
|
||||
esai_priv->soc = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
/* Get the addresses and IRQ */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(regs))
|
||||
return PTR_ERR(regs);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user