Merge remote-tracking branch 'asoc/for-5.12' into asoc-linus
This commit is contained in:
commit
0969db0d8d
@ -71,9 +71,6 @@ properties:
|
||||
description: CPU to Codec rate channels.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
required:
|
||||
- remote-endpoint
|
||||
|
||||
ports:
|
||||
description: multi OF-Graph subnode
|
||||
type: object
|
||||
|
@ -15,9 +15,14 @@ properties:
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: ingenic,jz4770-codec
|
||||
- const: ingenic,jz4725b-codec
|
||||
- const: ingenic,jz4740-codec
|
||||
- enum:
|
||||
- ingenic,jz4770-codec
|
||||
- ingenic,jz4760-codec
|
||||
- ingenic,jz4725b-codec
|
||||
- ingenic,jz4740-codec
|
||||
- items:
|
||||
- const: ingenic,jz4760b-codec
|
||||
- const: ingenic,jz4760-codec
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -18,6 +18,7 @@ properties:
|
||||
enum:
|
||||
- intel,keembay-i2s
|
||||
- intel,keembay-tdm
|
||||
- intel,keembay-hdmi-i2s
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
@ -45,6 +46,16 @@ properties:
|
||||
- const: osc
|
||||
- const: apb_clk
|
||||
|
||||
dmas:
|
||||
items:
|
||||
- description: DMA TX channel
|
||||
- description: DMA RX channel
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: tx
|
||||
- const: rx
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#sound-dai-cells"
|
||||
@ -70,4 +81,6 @@ examples:
|
||||
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-names = "osc", "apb_clk";
|
||||
clocks = <&scmi_clk KEEM_BAY_PSS_AUX_I2S3>, <&scmi_clk KEEM_BAY_PSS_I2S3>;
|
||||
dmas = <&axi_dma0 29 &axi_dma0 33>;
|
||||
dma-names = "tx", "rx";
|
||||
};
|
||||
|
@ -23,6 +23,10 @@ properties:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of MT8192 ASoC platform.
|
||||
|
||||
mediatek,hdmi-codec:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of HDMI codec.
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
@ -35,6 +39,7 @@ examples:
|
||||
sound: mt8192-sound {
|
||||
compatible = "mediatek,mt8192_mt6359_rt1015_rt5682";
|
||||
mediatek,platform = <&afe>;
|
||||
mediatek,hdmi-codec = <&anx_bridge_dp>;
|
||||
pinctrl-names = "aud_clk_mosi_off",
|
||||
"aud_clk_mosi_on";
|
||||
pinctrl-0 = <&aud_clk_mosi_off>;
|
||||
|
@ -0,0 +1,190 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nvidia,tegra-audio-graph-card.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Audio Graph based Tegra sound card driver
|
||||
|
||||
description: |
|
||||
This is based on generic audio graph card driver along with additional
|
||||
customizations for Tegra platforms. It uses the same bindings with
|
||||
additional standard clock DT bindings required for Tegra.
|
||||
|
||||
maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nvidia,tegra210-audio-graph-card
|
||||
- nvidia,tegra186-audio-graph-card
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: pll_a
|
||||
- const: plla_out0
|
||||
|
||||
assigned-clocks:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
assigned-clock-parents:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
assigned-clock-rates:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- clocks
|
||||
- clock-names
|
||||
- assigned-clocks
|
||||
- assigned-clock-parents
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include<dt-bindings/clock/tegra210-car.h>
|
||||
|
||||
tegra_sound {
|
||||
compatible = "nvidia,tegra210-audio-graph-card";
|
||||
|
||||
clocks = <&tegra_car TEGRA210_CLK_PLL_A>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_A_OUT0>;
|
||||
clock-names = "pll_a", "plla_out0";
|
||||
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_PLL_A>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_A_OUT0>,
|
||||
<&tegra_car TEGRA210_CLK_EXTERN1>;
|
||||
assigned-clock-parents = <0>, <0>, <&tegra_car TEGRA210_CLK_PLL_A_OUT0>;
|
||||
assigned-clock-rates = <368640000>, <49152000>, <12288000>;
|
||||
|
||||
dais = /* FE */
|
||||
<&admaif1_port>,
|
||||
/* Router */
|
||||
<&xbar_i2s1_port>,
|
||||
/* I/O DAP Ports */
|
||||
<&i2s1_port>;
|
||||
|
||||
label = "jetson-tx1-ape";
|
||||
};
|
||||
|
||||
// The ports are defined for AHUB and its child devices.
|
||||
ahub@702d0800 {
|
||||
compatible = "nvidia,tegra210-ahub";
|
||||
reg = <0x702d0800 0x800>;
|
||||
clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>;
|
||||
clock-names = "ahub";
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x702d0000 0x702d0000 0x0000e400>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0x0>;
|
||||
xbar_admaif1_ep: endpoint {
|
||||
remote-endpoint = <&admaif1_ep>;
|
||||
};
|
||||
};
|
||||
|
||||
// ...
|
||||
|
||||
xbar_i2s1_port: port@a {
|
||||
reg = <0xa>;
|
||||
xbar_i2s1_ep: endpoint {
|
||||
remote-endpoint = <&i2s1_cif_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
admaif@702d0000 {
|
||||
compatible = "nvidia,tegra210-admaif";
|
||||
reg = <0x702d0000 0x800>;
|
||||
dmas = <&adma 1>, <&adma 1>,
|
||||
<&adma 2>, <&adma 2>,
|
||||
<&adma 3>, <&adma 3>,
|
||||
<&adma 4>, <&adma 4>,
|
||||
<&adma 5>, <&adma 5>,
|
||||
<&adma 6>, <&adma 6>,
|
||||
<&adma 7>, <&adma 7>,
|
||||
<&adma 8>, <&adma 8>,
|
||||
<&adma 9>, <&adma 9>,
|
||||
<&adma 10>, <&adma 10>;
|
||||
dma-names = "rx1", "tx1",
|
||||
"rx2", "tx2",
|
||||
"rx3", "tx3",
|
||||
"rx4", "tx4",
|
||||
"rx5", "tx5",
|
||||
"rx6", "tx6",
|
||||
"rx7", "tx7",
|
||||
"rx8", "tx8",
|
||||
"rx9", "tx9",
|
||||
"rx10", "tx10";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
admaif1_port: port@0 {
|
||||
reg = <0x0>;
|
||||
admaif1_ep: endpoint {
|
||||
remote-endpoint = <&xbar_admaif1_ep>;
|
||||
};
|
||||
};
|
||||
|
||||
// More ADMAIF ports to follow
|
||||
};
|
||||
};
|
||||
|
||||
i2s@702d1000 {
|
||||
compatible = "nvidia,tegra210-i2s";
|
||||
clocks = <&tegra_car TEGRA210_CLK_I2S0>;
|
||||
clock-names = "i2s";
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_I2S0>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>;
|
||||
assigned-clock-rates = <1536000>;
|
||||
reg = <0x702d1000 0x100>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0x0>;
|
||||
|
||||
i2s1_cif_ep: endpoint {
|
||||
remote-endpoint = <&xbar_i2s1_ep>;
|
||||
};
|
||||
};
|
||||
|
||||
i2s1_port: port@1 {
|
||||
reg = <0x1>;
|
||||
|
||||
i2s1_dap: endpoint {
|
||||
dai-format = "i2s";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -17,6 +17,9 @@ maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph-port.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^dspk@[0-9a-f]*$"
|
||||
@ -55,6 +58,19 @@ properties:
|
||||
The name can be "DSPK1" or "DSPKx", where x depends on the maximum
|
||||
available instances on a Tegra SoC.
|
||||
|
||||
ports:
|
||||
type: object
|
||||
properties:
|
||||
port@0:
|
||||
description: |
|
||||
DSPK ACIF (Audio Client Interface) port connected to the
|
||||
corresponding AHUB (Audio Hub) ACIF port.
|
||||
|
||||
port@1:
|
||||
description: |
|
||||
DSPK DAP (Digital Audio Port) interface which can be connected
|
||||
to external audio codec for playback.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@ -64,7 +80,7 @@ required:
|
||||
- assigned-clock-parents
|
||||
- sound-name-prefix
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -17,6 +17,9 @@ maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph-port.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^admaif@[0-9a-f]*$"
|
||||
@ -37,6 +40,14 @@ properties:
|
||||
|
||||
dma-names: true
|
||||
|
||||
ports:
|
||||
description: |
|
||||
Contains list of ACIF (Audio CIF) port nodes for ADMAIF channels.
|
||||
The number of port nodes depends on the number of ADMAIF channels
|
||||
that SoC may have. These are interfaced with respective ACIF ports
|
||||
in AHUB (Audio Hub). Each port is capable of data transfers in
|
||||
both directions.
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
@ -81,7 +92,7 @@ required:
|
||||
- dmas
|
||||
- dma-names
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -17,6 +17,9 @@ maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph-port.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^ahub@[0-9a-f]*$"
|
||||
@ -56,6 +59,13 @@ properties:
|
||||
|
||||
ranges: true
|
||||
|
||||
ports:
|
||||
description: |
|
||||
Contains list of ACIF (Audio CIF) port nodes for AHUB (Audio Hub).
|
||||
These are connected to ACIF interfaces of AHUB clients. Thus the
|
||||
number of port nodes depend on the number of clients that AHUB may
|
||||
have depending on the SoC revision.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@ -67,8 +77,7 @@ required:
|
||||
- "#size-cells"
|
||||
- ranges
|
||||
|
||||
additionalProperties:
|
||||
type: object
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -16,6 +16,9 @@ maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph-port.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^dmic@[0-9a-f]*$"
|
||||
@ -56,6 +59,19 @@ properties:
|
||||
The name can be "DMIC1" or "DMIC2" ... "DMICx", where x depends
|
||||
on the maximum available instances on a Tegra SoC.
|
||||
|
||||
ports:
|
||||
type: object
|
||||
properties:
|
||||
port@0:
|
||||
description: |
|
||||
DMIC ACIF (Audio Client Interface) port connected to the
|
||||
corresponding AHUB (Audio Hub) ACIF port.
|
||||
|
||||
port@1:
|
||||
description: |
|
||||
DMIC DAP (Digital Audio Port) interface which can be connected
|
||||
to external audio codec for capture.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@ -64,7 +80,7 @@ required:
|
||||
- assigned-clocks
|
||||
- assigned-clock-parents
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -16,6 +16,9 @@ maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: audio-graph-port.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^i2s@[0-9a-f]*$"
|
||||
@ -74,6 +77,19 @@ properties:
|
||||
The name can be "I2S1" or "I2S2" ... "I2Sx", where x depends
|
||||
on the maximum available instances on a Tegra SoC.
|
||||
|
||||
ports:
|
||||
type: object
|
||||
properties:
|
||||
port@0:
|
||||
description: |
|
||||
I2S ACIF (Audio Client Interface) port connected to the
|
||||
corresponding AHUB (Audio Hub) ACIF port.
|
||||
|
||||
port@1:
|
||||
description: |
|
||||
I2S DAP (Digital Audio Port) interface which can be connected
|
||||
to external audio codec for playback or capture.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@ -82,7 +98,7 @@ required:
|
||||
- assigned-clocks
|
||||
- assigned-clock-parents
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -0,0 +1,62 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/qcom,lpass-rx-macro.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: LPASS(Low Power Audio Subsystem) RX Macro audio codec DT bindings
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8250-lpass-rx-macro
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
maxItems: 5
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: npl
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- const: fsgen
|
||||
|
||||
clock-output-names:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/sound/qcom,q6afe.h>
|
||||
codec@3200000 {
|
||||
compatible = "qcom,sm8250-lpass-rx-macro";
|
||||
reg = <0x3200000 0x1000>;
|
||||
#sound-dai-cells = <1>;
|
||||
#clock-cells = <0>;
|
||||
clocks = <&audiocc 0>,
|
||||
<&audiocc 1>,
|
||||
<&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&vamacro>;
|
||||
clock-names = "mclk", "npl", "macro", "dcodec", "fsgen";
|
||||
clock-output-names = "mclk";
|
||||
};
|
@ -0,0 +1,67 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/qcom,lpass-tx-macro.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: LPASS(Low Power Audio Subsystem) TX Macro audio codec DT bindings
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8250-lpass-tx-macro
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
maxItems: 5
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: npl
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- const: fsgen
|
||||
|
||||
clock-output-names:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
qcom,dmic-sample-rate:
|
||||
description: dmic sample rate
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/sound/qcom,q6afe.h>
|
||||
codec@3220000 {
|
||||
compatible = "qcom,sm8250-lpass-tx-macro";
|
||||
reg = <0x3220000 0x1000>;
|
||||
#sound-dai-cells = <1>;
|
||||
#clock-cells = <0>;
|
||||
clocks = <&aoncc 0>,
|
||||
<&aoncc 1>,
|
||||
<&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&vamacro>;
|
||||
clock-names = "mclk", "npl", "macro", "dcodec", "fsgen";
|
||||
clock-output-names = "mclk";
|
||||
qcom,dmic-sample-rate = <600000>;
|
||||
};
|
@ -404,7 +404,7 @@ examples:
|
||||
/* DAI base */
|
||||
rcar_sound,dai {
|
||||
dai0 {
|
||||
playback = <&ssi5 &src5>;
|
||||
playback = <&ssi5>, <&src5>;
|
||||
capture = <&ssi6>;
|
||||
};
|
||||
dai1 {
|
||||
@ -430,8 +430,8 @@ examples:
|
||||
bitclock-master = <&rsnd_endpoint0>;
|
||||
frame-master = <&rsnd_endpoint0>;
|
||||
|
||||
playback = <&ssi0 &src0 &dvc0>;
|
||||
capture = <&ssi1 &src1 &dvc1>;
|
||||
playback = <&ssi0>, <&src0>, <&dvc0>;
|
||||
capture = <&ssi1>, <&src1>, <&dvc1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -37,10 +37,21 @@ Optional properties:
|
||||
- realtek,jd-src
|
||||
0: No JD is used
|
||||
1: using JD3 as JD source
|
||||
2: JD source for Intel HDA header
|
||||
|
||||
- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
|
||||
- realtek,reset-gpios : The GPIO that controls the CODEC's RESET pin.
|
||||
|
||||
- sound-name-prefix: Please refer to name-prefix.txt
|
||||
|
||||
- ports: A Codec may have a single or multiple I2S interfaces. These
|
||||
interfaces on Codec side can be described under 'ports' or 'port'.
|
||||
When the SoC or host device is connected to multiple interfaces of
|
||||
the Codec, the connectivity can be described using 'ports' property.
|
||||
If a single interface is used, then 'port' can be used. The usage
|
||||
depends on the platform or board design.
|
||||
Please refer to Documentation/devicetree/bindings/graph.txt
|
||||
|
||||
Pins on the device (for linking into audio routes) for RT5659/RT5658:
|
||||
|
||||
* DMIC L1
|
||||
|
@ -1,17 +0,0 @@
|
||||
SiRF internal audio CODEC
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "sirf,atlas6-audio-codec" or "sirf,prima2-audio-codec"
|
||||
|
||||
- reg : the register address of the device.
|
||||
|
||||
- clocks: the clock of SiRF internal audio codec
|
||||
|
||||
Example:
|
||||
|
||||
audiocodec: audiocodec@b0040000 {
|
||||
compatible = "sirf,atlas6-audio-codec";
|
||||
reg = <0xb0040000 0x10000>;
|
||||
clocks = <&clks 27>;
|
||||
};
|
@ -1,27 +0,0 @@
|
||||
* SiRF SoC USP module
|
||||
|
||||
Required properties:
|
||||
- compatible: "sirf,prima2-usp-pcm"
|
||||
- reg: Base address and size entries:
|
||||
- dmas: List of DMA controller phandle and DMA request line ordered pairs.
|
||||
- dma-names: Identifier string for each DMA request line in the dmas property.
|
||||
These strings correspond 1:1 with the ordered pairs in dmas.
|
||||
|
||||
One of the DMA channels will be responsible for transmission (should be
|
||||
named "tx") and one for reception (should be named "rx").
|
||||
|
||||
- clocks: USP controller clock source
|
||||
- pinctrl-names: Must contain a "default" entry.
|
||||
- pinctrl-NNN: One property must exist for each entry in pinctrl-names.
|
||||
|
||||
Example:
|
||||
usp0: usp@b0080000 {
|
||||
compatible = "sirf,prima2-usp-pcm";
|
||||
reg = <0xb0080000 0x10000>;
|
||||
clocks = <&clks 28>;
|
||||
dmas = <&dmac1 1>, <&dmac1 2>;
|
||||
dma-names = "rx", "tx";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&usp0_only_utfs_pins_a>;
|
||||
};
|
||||
|
@ -54,6 +54,10 @@ properties:
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
"#clock-cells":
|
||||
description: Configure the I2S device as MCLK clock provider.
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#sound-dai-cells"
|
||||
|
@ -9,6 +9,9 @@ Required properties:
|
||||
- reg : the I2C address of the device.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- clocks : The clock source of the mclk
|
||||
|
||||
- spk-mono: This is a boolean property. If present, the SPK_MONO bit
|
||||
of R51 (Class D Control 2) gets set, indicating that the speaker is
|
||||
in mono mode.
|
||||
@ -27,6 +30,7 @@ Example:
|
||||
wm8962: codec@1a {
|
||||
compatible = "wlf,wm8962";
|
||||
reg = <0x1a>;
|
||||
clocks = <&clks IMX6QDL_CLK_CKO>;
|
||||
|
||||
gpio-cfg = <
|
||||
0x0000 /* 0:Default */
|
||||
|
@ -1,30 +0,0 @@
|
||||
ZTE TDM DAI driver
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be one of the following.
|
||||
* zte,zx296718-tdm
|
||||
- reg : physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
|
||||
- clock-names: "wclk" for the wclk.
|
||||
"pclk" for the pclk.
|
||||
-#clock-cells: should be 1.
|
||||
- zte,tdm-dma-sysctrl : Reference to the sysctrl controller controlling
|
||||
the dma. includes:
|
||||
phandle of sysctrl.
|
||||
register offset in sysctrl for control dma.
|
||||
mask of the register that be written to sysctrl.
|
||||
|
||||
Example:
|
||||
|
||||
tdm: tdm@1487000 {
|
||||
compatible = "zte,zx296718-tdm";
|
||||
reg = <0x01487000 0x1000>;
|
||||
clocks = <&audiocrm AUDIO_TDM_WCLK>, <&audiocrm AUDIO_TDM_PCLK>;
|
||||
clock-names = "wclk", "pclk";
|
||||
#clock-cells = <1>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&tdm_global_pin>;
|
||||
zte,tdm-dma-sysctrl = <&sysctrl 0x10c 4>;
|
||||
};
|
@ -1,24 +0,0 @@
|
||||
ZTE ZX AUD96P22 Audio Codec
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "zte,zx-aud96p22"
|
||||
- #sound-dai-cells: Should be 0
|
||||
- reg: I2C bus slave address of AUD96P22
|
||||
|
||||
Example:
|
||||
|
||||
i2c0: i2c@1486000 {
|
||||
compatible = "zte,zx296718-i2c";
|
||||
reg = <0x01486000 0x1000>;
|
||||
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
clocks = <&audiocrm AUDIO_I2C0_WCLK>;
|
||||
clock-frequency = <1600000>;
|
||||
|
||||
aud96p22: codec@22 {
|
||||
compatible = "zte,zx-aud96p22";
|
||||
#sound-dai-cells = <0>;
|
||||
reg = <0x22>;
|
||||
};
|
||||
};
|
@ -1,45 +0,0 @@
|
||||
ZTE ZX296702 I2S controller
|
||||
|
||||
Required properties:
|
||||
- compatible : Must be one of:
|
||||
"zte,zx296718-i2s", "zte,zx296702-i2s"
|
||||
"zte,zx296702-i2s"
|
||||
- reg : Must contain I2S core's registers location and length
|
||||
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
|
||||
- clock-names: "wclk" for the wclk, "pclk" for the pclk to the I2S interface.
|
||||
- dmas: Pairs of phandle and specifier for the DMA channel that is used by
|
||||
the core. The core expects two dma channels for transmit.
|
||||
- dma-names : Must be "tx" and "rx"
|
||||
|
||||
For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties
|
||||
please check:
|
||||
* resource-names.txt
|
||||
* clock/clock-bindings.txt
|
||||
* dma/dma.txt
|
||||
|
||||
Example:
|
||||
i2s0: i2s@b005000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "zte,zx296718-i2s", "zte,zx296702-i2s";
|
||||
reg = <0x0b005000 0x1000>;
|
||||
clocks = <&audiocrm AUDIO_I2S0_WCLK>, <&audiocrm AUDIO_I2S0_PCLK>;
|
||||
clock-names = "wclk", "pclk";
|
||||
interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma 5>, <&dma 6>;
|
||||
dma-names = "tx", "rx";
|
||||
};
|
||||
|
||||
sound {
|
||||
compatible = "simple-audio-card";
|
||||
simple-audio-card,name = "zx296702_snd";
|
||||
simple-audio-card,format = "left_j";
|
||||
simple-audio-card,bitclock-master = <&sndcodec>;
|
||||
simple-audio-card,frame-master = <&sndcodec>;
|
||||
sndcpu: simple-audio-card,cpu {
|
||||
sound-dai = <&i2s0>;
|
||||
};
|
||||
|
||||
sndcodec: simple-audio-card,codec {
|
||||
sound-dai = <&acodec>;
|
||||
};
|
||||
};
|
@ -1,27 +0,0 @@
|
||||
ZTE ZX296702 SPDIF controller
|
||||
|
||||
Required properties:
|
||||
- compatible : Must be "zte,zx296702-spdif"
|
||||
- reg : Must contain SPDIF core's registers location and length
|
||||
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
|
||||
- clock-names: "tx" for the clock to the SPDIF interface.
|
||||
- dmas: Pairs of phandle and specifier for the DMA channel that is used by
|
||||
the core. The core expects one dma channel for transmit.
|
||||
- dma-names : Must be "tx"
|
||||
|
||||
For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties
|
||||
please check:
|
||||
* resource-names.txt
|
||||
* clock/clock-bindings.txt
|
||||
* dma/dma.txt
|
||||
|
||||
Example:
|
||||
spdif0: spdif0@b004000 {
|
||||
compatible = "zte,zx296702-spdif";
|
||||
reg = <0x0b004000 0x1000>;
|
||||
clocks = <&lsp0clk ZX296702_SPDIF0_DIV>;
|
||||
clock-names = "tx";
|
||||
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma 4>;
|
||||
dma-names = "tx";
|
||||
};
|
@ -797,17 +797,6 @@ const struct dev_pm_ops arizona_pm_ops = {
|
||||
EXPORT_SYMBOL_GPL(arizona_pm_ops);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
unsigned long arizona_of_get_type(struct device *dev)
|
||||
{
|
||||
const struct of_device_id *id = of_match_device(arizona_of_match, dev);
|
||||
|
||||
if (id)
|
||||
return (unsigned long)id->data;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arizona_of_get_type);
|
||||
|
||||
static int arizona_of_get_core_pdata(struct arizona *arizona)
|
||||
{
|
||||
struct arizona_pdata *pdata = &arizona->pdata;
|
||||
|
@ -23,14 +23,16 @@
|
||||
static int arizona_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
const void *match_data;
|
||||
struct arizona *arizona;
|
||||
const struct regmap_config *regmap_config = NULL;
|
||||
unsigned long type;
|
||||
unsigned long type = 0;
|
||||
int ret;
|
||||
|
||||
if (i2c->dev.of_node)
|
||||
type = arizona_of_get_type(&i2c->dev);
|
||||
else
|
||||
match_data = device_get_match_data(&i2c->dev);
|
||||
if (match_data)
|
||||
type = (unsigned long)match_data;
|
||||
else if (id)
|
||||
type = id->driver_data;
|
||||
|
||||
switch (type) {
|
||||
@ -115,6 +117,7 @@ static struct i2c_driver arizona_i2c_driver = {
|
||||
|
||||
module_i2c_driver(arizona_i2c_driver);
|
||||
|
||||
MODULE_SOFTDEP("pre: arizona_ldo1");
|
||||
MODULE_DESCRIPTION("Arizona I2C bus interface");
|
||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -7,7 +7,10 @@
|
||||
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
@ -15,22 +18,141 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/of.h>
|
||||
#include <uapi/linux/input-event-codes.h>
|
||||
|
||||
#include <linux/mfd/arizona/core.h>
|
||||
|
||||
#include "arizona.h"
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
const struct acpi_gpio_params reset_gpios = { 1, 0, false };
|
||||
const struct acpi_gpio_params ldoena_gpios = { 2, 0, false };
|
||||
|
||||
static const struct acpi_gpio_mapping arizona_acpi_gpios[] = {
|
||||
{ "reset-gpios", &reset_gpios, 1, },
|
||||
{ "wlf,ldoena-gpios", &ldoena_gpios, 1 },
|
||||
{ }
|
||||
};
|
||||
|
||||
/*
|
||||
* The ACPI resources for the device only describe external GPIO-s. They do
|
||||
* not provide mappings for the GPIO-s coming from the Arizona codec itself.
|
||||
*/
|
||||
static const struct gpiod_lookup arizona_soc_gpios[] = {
|
||||
{ "arizona", 2, "wlf,spkvdd-ena", 0, GPIO_ACTIVE_HIGH },
|
||||
{ "arizona", 4, "wlf,micd-pol", 0, GPIO_ACTIVE_LOW },
|
||||
};
|
||||
|
||||
/*
|
||||
* The AOSP 3.5 mm Headset: Accessory Specification gives the following values:
|
||||
* Function A Play/Pause: 0 ohm
|
||||
* Function D Voice assistant: 135 ohm
|
||||
* Function B Volume Up 240 ohm
|
||||
* Function C Volume Down 470 ohm
|
||||
* Minimum Mic DC resistance 1000 ohm
|
||||
* Minimum Ear speaker impedance 16 ohm
|
||||
* Note the first max value below must be less then the min. speaker impedance,
|
||||
* to allow CTIA/OMTP detection to work. The other max values are the closest
|
||||
* value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances.
|
||||
*/
|
||||
static const struct arizona_micd_range arizona_micd_aosp_ranges[] = {
|
||||
{ .max = 11, .key = KEY_PLAYPAUSE },
|
||||
{ .max = 186, .key = KEY_VOICECOMMAND },
|
||||
{ .max = 348, .key = KEY_VOLUMEUP },
|
||||
{ .max = 752, .key = KEY_VOLUMEDOWN },
|
||||
};
|
||||
|
||||
static void arizona_spi_acpi_remove_lookup(void *lookup)
|
||||
{
|
||||
gpiod_remove_lookup_table(lookup);
|
||||
}
|
||||
|
||||
static int arizona_spi_acpi_probe(struct arizona *arizona)
|
||||
{
|
||||
struct gpiod_lookup_table *lookup;
|
||||
acpi_status status;
|
||||
int ret;
|
||||
|
||||
/* Add mappings for the 2 ACPI declared GPIOs used for reset and ldo-ena */
|
||||
devm_acpi_dev_add_driver_gpios(arizona->dev, arizona_acpi_gpios);
|
||||
|
||||
/* Add lookups for the SoCs own GPIOs used for micdet-polarity and spkVDD-enable */
|
||||
lookup = devm_kzalloc(arizona->dev,
|
||||
struct_size(lookup, table, ARRAY_SIZE(arizona_soc_gpios) + 1),
|
||||
GFP_KERNEL);
|
||||
if (!lookup)
|
||||
return -ENOMEM;
|
||||
|
||||
lookup->dev_id = dev_name(arizona->dev);
|
||||
memcpy(lookup->table, arizona_soc_gpios, sizeof(arizona_soc_gpios));
|
||||
|
||||
gpiod_add_lookup_table(lookup);
|
||||
ret = devm_add_action_or_reset(arizona->dev, arizona_spi_acpi_remove_lookup, lookup);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable 32KHz clock from SoC to codec for jack-detect */
|
||||
status = acpi_evaluate_object(ACPI_HANDLE(arizona->dev), "CLKE", NULL, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
dev_warn(arizona->dev, "Failed to enable 32KHz clk ACPI error %d\n", status);
|
||||
|
||||
/*
|
||||
* Some DSDTs wrongly declare the IRQ trigger-type as IRQF_TRIGGER_FALLING
|
||||
* The IRQ line will stay low when a new IRQ event happens between reading
|
||||
* the IRQ status flags and acknowledging them. When the IRQ line stays
|
||||
* low like this the IRQ will never trigger again when its type is set
|
||||
* to IRQF_TRIGGER_FALLING. Correct the IRQ trigger-type to fix this.
|
||||
*
|
||||
* Note theoretically it is possible that some boards are not capable
|
||||
* of handling active low level interrupts. In that case setting the
|
||||
* flag to IRQF_TRIGGER_FALLING would not be a bug (and we would need
|
||||
* to work around this) but so far all known usages of IRQF_TRIGGER_FALLING
|
||||
* are a bug in the board's DSDT.
|
||||
*/
|
||||
arizona->pdata.irq_flags = IRQF_TRIGGER_LOW;
|
||||
|
||||
/* Wait 200 ms after jack insertion */
|
||||
arizona->pdata.micd_detect_debounce = 200;
|
||||
|
||||
/* Use standard AOSP values for headset-button mappings */
|
||||
arizona->pdata.micd_ranges = arizona_micd_aosp_ranges;
|
||||
arizona->pdata.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id arizona_acpi_match[] = {
|
||||
{
|
||||
.id = "WM510204",
|
||||
.driver_data = WM5102,
|
||||
},
|
||||
{
|
||||
.id = "WM510205",
|
||||
.driver_data = WM5102,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, arizona_acpi_match);
|
||||
#else
|
||||
static int arizona_spi_acpi_probe(struct arizona *arizona)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int arizona_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
const struct spi_device_id *id = spi_get_device_id(spi);
|
||||
const void *match_data;
|
||||
struct arizona *arizona;
|
||||
const struct regmap_config *regmap_config = NULL;
|
||||
unsigned long type;
|
||||
unsigned long type = 0;
|
||||
int ret;
|
||||
|
||||
if (spi->dev.of_node)
|
||||
type = arizona_of_get_type(&spi->dev);
|
||||
else
|
||||
match_data = device_get_match_data(&spi->dev);
|
||||
if (match_data)
|
||||
type = (unsigned long)match_data;
|
||||
else if (id)
|
||||
type = id->driver_data;
|
||||
|
||||
switch (type) {
|
||||
@ -75,6 +197,12 @@ static int arizona_spi_probe(struct spi_device *spi)
|
||||
arizona->dev = &spi->dev;
|
||||
arizona->irq = spi->irq;
|
||||
|
||||
if (has_acpi_companion(&spi->dev)) {
|
||||
ret = arizona_spi_acpi_probe(arizona);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return arizona_dev_init(arizona);
|
||||
}
|
||||
|
||||
@ -102,6 +230,7 @@ static struct spi_driver arizona_spi_driver = {
|
||||
.name = "arizona",
|
||||
.pm = &arizona_pm_ops,
|
||||
.of_match_table = of_match_ptr(arizona_of_match),
|
||||
.acpi_match_table = ACPI_PTR(arizona_acpi_match),
|
||||
},
|
||||
.probe = arizona_spi_probe,
|
||||
.remove = arizona_spi_remove,
|
||||
@ -110,6 +239,7 @@ static struct spi_driver arizona_spi_driver = {
|
||||
|
||||
module_spi_driver(arizona_spi_driver);
|
||||
|
||||
MODULE_SOFTDEP("pre: arizona_ldo1");
|
||||
MODULE_DESCRIPTION("Arizona SPI bus interface");
|
||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -50,13 +50,4 @@ int arizona_dev_exit(struct arizona *arizona);
|
||||
int arizona_irq_init(struct arizona *arizona);
|
||||
int arizona_irq_exit(struct arizona *arizona);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
unsigned long arizona_of_get_type(struct device *dev);
|
||||
#else
|
||||
static inline unsigned long arizona_of_get_type(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -4600,6 +4600,7 @@ enum ec_codec_i2s_rx_subcmd {
|
||||
EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH = 0x2,
|
||||
EC_CODEC_I2S_RX_SET_DAIFMT = 0x3,
|
||||
EC_CODEC_I2S_RX_SET_BCLK = 0x4,
|
||||
EC_CODEC_I2S_RX_RESET = 0x5,
|
||||
EC_CODEC_I2S_RX_SUBCMD_COUNT,
|
||||
};
|
||||
|
||||
|
@ -66,6 +66,9 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
|
||||
* @chan_name: Custom channel name to use when requesting DMA channel.
|
||||
* @fifo_size: FIFO size of the DAI controller in bytes
|
||||
* @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now
|
||||
* @peripheral_config: peripheral configuration for programming peripheral
|
||||
* for dmaengine transfer
|
||||
* @peripheral_size: peripheral configuration buffer size
|
||||
*/
|
||||
struct snd_dmaengine_dai_dma_data {
|
||||
dma_addr_t addr;
|
||||
@ -76,6 +79,8 @@ struct snd_dmaengine_dai_dma_data {
|
||||
const char *chan_name;
|
||||
unsigned int fifo_size;
|
||||
unsigned int flags;
|
||||
void *peripheral_config;
|
||||
size_t peripheral_size;
|
||||
};
|
||||
|
||||
void snd_dmaengine_pcm_set_config_from_dai_data(
|
||||
|
@ -9,8 +9,10 @@
|
||||
|
||||
#include <sound/simple_card_utils.h>
|
||||
|
||||
int graph_card_probe(struct snd_soc_card *card);
|
||||
int audio_graph_card_probe(struct snd_soc_card *card);
|
||||
|
||||
int graph_parse_of(struct asoc_simple_priv *priv, struct device *dev);
|
||||
int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev);
|
||||
|
||||
int audio_graph_remove(struct platform_device *pdev);
|
||||
|
||||
#endif /* __GRAPH_CARD_H */
|
||||
|
@ -34,6 +34,11 @@ struct hdmi_codec_daifmt {
|
||||
unsigned int frame_clk_inv:1;
|
||||
unsigned int bit_clk_master:1;
|
||||
unsigned int frame_clk_master:1;
|
||||
/* bit_fmt could be standard PCM format or
|
||||
* IEC958 encoded format. ALSA IEC958 plugin will pass
|
||||
* IEC958_SUBFRAME format to the underneath driver.
|
||||
*/
|
||||
snd_pcm_format_t bit_fmt;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -22,6 +22,8 @@ struct rt5645_platform_data {
|
||||
bool level_trigger_irq;
|
||||
/* Invert JD1_1 status polarity */
|
||||
bool inv_jd1_1;
|
||||
/* Invert HP detect status polarity */
|
||||
bool inv_hp_pol;
|
||||
|
||||
/* Value to asign to snd_soc_card.long_name */
|
||||
const char *long_name;
|
||||
|
@ -353,6 +353,12 @@ int snd_soc_component_test_bits(struct snd_soc_component *component,
|
||||
unsigned int reg, unsigned int mask,
|
||||
unsigned int value);
|
||||
|
||||
unsigned int snd_soc_component_read_field(struct snd_soc_component *component,
|
||||
unsigned int reg, unsigned int mask);
|
||||
int snd_soc_component_write_field(struct snd_soc_component *component,
|
||||
unsigned int reg, unsigned int mask,
|
||||
unsigned int val);
|
||||
|
||||
/* component wide operations */
|
||||
int snd_soc_component_set_sysclk(struct snd_soc_component *component,
|
||||
int clk_id, int source,
|
||||
|
@ -353,9 +353,9 @@ struct snd_soc_dai_driver {
|
||||
/* DAI capabilities */
|
||||
struct snd_soc_pcm_stream capture;
|
||||
struct snd_soc_pcm_stream playback;
|
||||
unsigned int symmetric_rates:1;
|
||||
unsigned int symmetric_rate:1;
|
||||
unsigned int symmetric_channels:1;
|
||||
unsigned int symmetric_samplebits:1;
|
||||
unsigned int symmetric_sample_bits:1;
|
||||
|
||||
/* probe ordering - for components with runtime dependencies */
|
||||
int probe_order;
|
||||
|
@ -685,9 +685,9 @@ struct snd_soc_dai_link {
|
||||
unsigned int ignore_suspend:1;
|
||||
|
||||
/* Symmetry requirements */
|
||||
unsigned int symmetric_rates:1;
|
||||
unsigned int symmetric_rate:1;
|
||||
unsigned int symmetric_channels:1;
|
||||
unsigned int symmetric_samplebits:1;
|
||||
unsigned int symmetric_sample_bits:1;
|
||||
|
||||
/* Do not create a PCM for this DAI link (Backend link) */
|
||||
unsigned int no_pcm:1;
|
||||
|
@ -58,9 +58,9 @@ struct sof_ext_man_header {
|
||||
/* Extended manifest elements types */
|
||||
enum sof_ext_man_elem_type {
|
||||
SOF_EXT_MAN_ELEM_FW_VERSION = 0,
|
||||
SOF_EXT_MAN_ELEM_WINDOW = SOF_IPC_EXT_WINDOW,
|
||||
SOF_EXT_MAN_ELEM_CC_VERSION = SOF_IPC_EXT_CC_INFO,
|
||||
SOF_EXT_MAN_ELEM_DBG_ABI = SOF_IPC_EXT_USER_ABI_INFO,
|
||||
SOF_EXT_MAN_ELEM_WINDOW = 1,
|
||||
SOF_EXT_MAN_ELEM_CC_VERSION = 2,
|
||||
SOF_EXT_MAN_ELEM_DBG_ABI = 4,
|
||||
SOF_EXT_MAN_ELEM_CONFIG_DATA = 5, /**< ABI3.17 */
|
||||
SOF_EXT_MAN_ELEM_PLATFORM_CONFIG_DATA = 6,
|
||||
};
|
||||
|
@ -125,6 +125,8 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
|
||||
}
|
||||
|
||||
slave_config->slave_id = dma_data->slave_id;
|
||||
slave_config->peripheral_config = dma_data->peripheral_config;
|
||||
slave_config->peripheral_size = dma_data->peripheral_size;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data);
|
||||
|
||||
|
@ -37,6 +37,23 @@ config SND_SOC_COMPRESS
|
||||
config SND_SOC_TOPOLOGY
|
||||
bool
|
||||
|
||||
config SND_SOC_TOPOLOGY_KUNIT_TESTS
|
||||
tristate "KUnit tests for SoC topology"
|
||||
depends on KUNIT
|
||||
depends on SND_SOC_TOPOLOGY
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
If you want to perform tests on ALSA SoC topology support say Y here.
|
||||
|
||||
This builds a module which can be later manually loaded to run KUNIT
|
||||
test cases against soc-topology.c API. This should be primarily used
|
||||
by developers to test their changes to ASoC.
|
||||
|
||||
Do note that it creates fake playback devices which do not interact
|
||||
well with userspace. When running tests one may want to disable
|
||||
userspace applications such as pulseaudio, to prevent unnecessary
|
||||
problems.
|
||||
|
||||
config SND_SOC_ACPI
|
||||
tristate
|
||||
|
||||
@ -62,7 +79,6 @@ source "sound/soc/qcom/Kconfig"
|
||||
source "sound/soc/rockchip/Kconfig"
|
||||
source "sound/soc/samsung/Kconfig"
|
||||
source "sound/soc/sh/Kconfig"
|
||||
source "sound/soc/sirf/Kconfig"
|
||||
source "sound/soc/sof/Kconfig"
|
||||
source "sound/soc/spear/Kconfig"
|
||||
source "sound/soc/sprd/Kconfig"
|
||||
@ -71,12 +87,10 @@ source "sound/soc/stm/Kconfig"
|
||||
source "sound/soc/sunxi/Kconfig"
|
||||
source "sound/soc/tegra/Kconfig"
|
||||
source "sound/soc/ti/Kconfig"
|
||||
source "sound/soc/txx9/Kconfig"
|
||||
source "sound/soc/uniphier/Kconfig"
|
||||
source "sound/soc/ux500/Kconfig"
|
||||
source "sound/soc/xilinx/Kconfig"
|
||||
source "sound/soc/xtensa/Kconfig"
|
||||
source "sound/soc/zte/Kconfig"
|
||||
|
||||
# Supported codecs
|
||||
source "sound/soc/codecs/Kconfig"
|
||||
|
@ -7,6 +7,11 @@ ifneq ($(CONFIG_SND_SOC_TOPOLOGY),)
|
||||
snd-soc-core-objs += soc-topology.o
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_SND_SOC_TOPOLOGY_KUNIT_TESTS),)
|
||||
# snd-soc-test-objs := soc-topology-test.o
|
||||
obj-$(CONFIG_SND_SOC_TOPOLOGY_KUNIT_TESTS) := soc-topology-test.o
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),)
|
||||
snd-soc-core-objs += soc-generic-dmaengine-pcm.o
|
||||
endif
|
||||
@ -45,7 +50,6 @@ obj-$(CONFIG_SND_SOC) += qcom/
|
||||
obj-$(CONFIG_SND_SOC) += rockchip/
|
||||
obj-$(CONFIG_SND_SOC) += samsung/
|
||||
obj-$(CONFIG_SND_SOC) += sh/
|
||||
obj-$(CONFIG_SND_SOC) += sirf/
|
||||
obj-$(CONFIG_SND_SOC) += sof/
|
||||
obj-$(CONFIG_SND_SOC) += spear/
|
||||
obj-$(CONFIG_SND_SOC) += sprd/
|
||||
@ -54,9 +58,7 @@ obj-$(CONFIG_SND_SOC) += stm/
|
||||
obj-$(CONFIG_SND_SOC) += sunxi/
|
||||
obj-$(CONFIG_SND_SOC) += tegra/
|
||||
obj-$(CONFIG_SND_SOC) += ti/
|
||||
obj-$(CONFIG_SND_SOC) += txx9/
|
||||
obj-$(CONFIG_SND_SOC) += uniphier/
|
||||
obj-$(CONFIG_SND_SOC) += ux500/
|
||||
obj-$(CONFIG_SND_SOC) += xilinx/
|
||||
obj-$(CONFIG_SND_SOC) += xtensa/
|
||||
obj-$(CONFIG_SND_SOC) += zte/
|
||||
|
@ -156,7 +156,7 @@ static const struct snd_soc_dai_ops axi_i2s_dai_ops = {
|
||||
static struct snd_soc_dai_driver axi_i2s_dai = {
|
||||
.probe = axi_i2s_dai_probe,
|
||||
.ops = &axi_i2s_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver axi_i2s_component = {
|
||||
|
@ -140,9 +140,7 @@ static int acp3x_1015_hw_params(struct snd_pcm_substream *substream,
|
||||
for_each_rtd_codec_dais(rtd, i, codec_dai) {
|
||||
if (strcmp(codec_dai->name, "rt1015-aif"))
|
||||
continue;
|
||||
ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK,
|
||||
64 * srate, 256 * srate);
|
||||
if (ret < 0)
|
||||
|
@ -541,7 +541,7 @@ static struct snd_soc_dai_driver atmel_i2s_dai = {
|
||||
.formats = ATMEL_I2S_FORMATS,
|
||||
},
|
||||
.ops = &atmel_i2s_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver atmel_i2s_component = {
|
||||
|
@ -34,86 +34,21 @@
|
||||
#include "atmel-pcm.h"
|
||||
|
||||
|
||||
static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
|
||||
int stream)
|
||||
{
|
||||
struct snd_pcm_substream *substream = pcm->streams[stream].substream;
|
||||
struct snd_dma_buffer *buf = &substream->dma_buffer;
|
||||
size_t size = ATMEL_SSC_DMABUF_SIZE;
|
||||
|
||||
buf->dev.type = SNDRV_DMA_TYPE_DEV;
|
||||
buf->dev.dev = pcm->card->dev;
|
||||
buf->private_data = NULL;
|
||||
buf->area = dma_alloc_coherent(pcm->card->dev, size,
|
||||
&buf->addr, GFP_KERNEL);
|
||||
pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%zu\n",
|
||||
(void *)buf->area, (void *)(long)buf->addr, size);
|
||||
|
||||
if (!buf->area)
|
||||
return -ENOMEM;
|
||||
|
||||
buf->bytes = size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atmel_pcm_mmap(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
return remap_pfn_range(vma, vma->vm_start,
|
||||
substream->dma_buffer.addr >> PAGE_SHIFT,
|
||||
vma->vm_end - vma->vm_start, vma->vm_page_prot);
|
||||
}
|
||||
|
||||
static int atmel_pcm_new(struct snd_soc_component *component,
|
||||
struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_card *card = rtd->card->snd_card;
|
||||
struct snd_pcm *pcm = rtd->pcm;
|
||||
int ret;
|
||||
|
||||
ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
|
||||
pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n");
|
||||
ret = atmel_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_PLAYBACK);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
|
||||
card->dev, ATMEL_SSC_DMABUF_SIZE,
|
||||
ATMEL_SSC_DMABUF_SIZE);
|
||||
|
||||
if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
|
||||
pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n");
|
||||
ret = atmel_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_CAPTURE);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void atmel_pcm_free(struct snd_soc_component *component,
|
||||
struct snd_pcm *pcm)
|
||||
{
|
||||
struct snd_pcm_substream *substream;
|
||||
struct snd_dma_buffer *buf;
|
||||
int stream;
|
||||
|
||||
for (stream = 0; stream < 2; stream++) {
|
||||
substream = pcm->streams[stream].substream;
|
||||
if (!substream)
|
||||
continue;
|
||||
|
||||
buf = &substream->dma_buffer;
|
||||
if (!buf->area)
|
||||
continue;
|
||||
dma_free_coherent(pcm->card->dev, buf->bytes,
|
||||
buf->area, buf->addr);
|
||||
buf->area = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*\
|
||||
@ -210,9 +145,6 @@ static int atmel_pcm_hw_params(struct snd_soc_component *component,
|
||||
/* this may get called several times by oss emulation
|
||||
* with different params */
|
||||
|
||||
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
|
||||
runtime->dma_bytes = params_buffer_bytes(params);
|
||||
|
||||
prtd->params = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream);
|
||||
prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
|
||||
|
||||
@ -384,9 +316,7 @@ static const struct snd_soc_component_driver atmel_soc_platform = {
|
||||
.prepare = atmel_pcm_prepare,
|
||||
.trigger = atmel_pcm_trigger,
|
||||
.pointer = atmel_pcm_pointer,
|
||||
.mmap = atmel_pcm_mmap,
|
||||
.pcm_construct = atmel_pcm_new,
|
||||
.pcm_destruct = atmel_pcm_free,
|
||||
};
|
||||
|
||||
int atmel_pcm_pdc_platform_register(struct device *dev)
|
||||
|
@ -859,8 +859,8 @@ static struct snd_soc_dai_driver mchp_i2s_mcc_dai = {
|
||||
.formats = MCHP_I2SMCC_FORMATS,
|
||||
},
|
||||
.ops = &mchp_i2s_mcc_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
.symmetric_channels = 1,
|
||||
};
|
||||
|
||||
|
@ -210,7 +210,7 @@ static const struct snd_soc_dai_ops au1xi2s_dai_ops = {
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver au1xi2s_dai_driver = {
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
.playback = {
|
||||
.rates = AU1XI2SC_RATES,
|
||||
.formats = AU1XI2SC_FMTS,
|
||||
|
@ -783,8 +783,8 @@ static struct snd_soc_dai_driver bcm2835_i2s_dai = {
|
||||
| SNDRV_PCM_FMTBIT_S32_LE
|
||||
},
|
||||
.ops = &bcm2835_i2s_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
};
|
||||
|
||||
static bool bcm2835_i2s_volatile_reg(struct device *dev, unsigned int reg)
|
||||
|
@ -212,7 +212,7 @@ static struct snd_soc_dai_driver bcm63xx_i2s_dai = {
|
||||
.formats = SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.ops = &bcm63xx_i2s_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_channels = 1,
|
||||
};
|
||||
|
||||
|
@ -636,36 +636,6 @@ static int cygnus_pcm_close(struct snd_soc_component *component,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cygnus_pcm_hw_params(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct cygnus_aio_port *aio;
|
||||
|
||||
aio = cygnus_dai_get_dma_data(substream);
|
||||
dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s port %d\n", __func__, aio->portnum);
|
||||
|
||||
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
|
||||
runtime->dma_bytes = params_buffer_bytes(params);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cygnus_pcm_hw_free(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct cygnus_aio_port *aio;
|
||||
|
||||
aio = cygnus_dai_get_dma_data(substream);
|
||||
dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s port %d\n", __func__, aio->portnum);
|
||||
|
||||
snd_pcm_set_runtime_buffer(substream, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cygnus_pcm_prepare(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
@ -730,87 +700,19 @@ static snd_pcm_uframes_t cygnus_pcm_pointer(struct snd_soc_component *component,
|
||||
return bytes_to_frames(substream->runtime, res);
|
||||
}
|
||||
|
||||
static int cygnus_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
|
||||
{
|
||||
struct snd_pcm_substream *substream = pcm->streams[stream].substream;
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_dma_buffer *buf = &substream->dma_buffer;
|
||||
size_t size;
|
||||
|
||||
size = cygnus_pcm_hw.buffer_bytes_max;
|
||||
|
||||
buf->dev.type = SNDRV_DMA_TYPE_DEV;
|
||||
buf->dev.dev = pcm->card->dev;
|
||||
buf->private_data = NULL;
|
||||
buf->area = dma_alloc_coherent(pcm->card->dev, size,
|
||||
&buf->addr, GFP_KERNEL);
|
||||
|
||||
dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "%s: size 0x%zx @ %pK\n",
|
||||
__func__, size, buf->area);
|
||||
|
||||
if (!buf->area) {
|
||||
dev_err(asoc_rtd_to_cpu(rtd, 0)->dev, "%s: dma_alloc failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
buf->bytes = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cygnus_dma_free_dma_buffers(struct snd_soc_component *component,
|
||||
struct snd_pcm *pcm)
|
||||
{
|
||||
struct snd_pcm_substream *substream;
|
||||
struct snd_dma_buffer *buf;
|
||||
|
||||
substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
|
||||
if (substream) {
|
||||
buf = &substream->dma_buffer;
|
||||
if (buf->area) {
|
||||
dma_free_coherent(pcm->card->dev, buf->bytes,
|
||||
buf->area, buf->addr);
|
||||
buf->area = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
|
||||
if (substream) {
|
||||
buf = &substream->dma_buffer;
|
||||
if (buf->area) {
|
||||
dma_free_coherent(pcm->card->dev, buf->bytes,
|
||||
buf->area, buf->addr);
|
||||
buf->area = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int cygnus_dma_new(struct snd_soc_component *component,
|
||||
struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
size_t size = cygnus_pcm_hw.buffer_bytes_max;
|
||||
struct snd_card *card = rtd->card->snd_card;
|
||||
struct snd_pcm *pcm = rtd->pcm;
|
||||
int ret;
|
||||
|
||||
if (!card->dev->dma_mask)
|
||||
card->dev->dma_mask = &cygnus_dma_dmamask;
|
||||
if (!card->dev->coherent_dma_mask)
|
||||
card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
|
||||
ret = cygnus_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_PLAYBACK);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
|
||||
ret = cygnus_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_CAPTURE);
|
||||
if (ret) {
|
||||
cygnus_dma_free_dma_buffers(component, pcm);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
|
||||
card->dev, size, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -818,13 +720,10 @@ static int cygnus_dma_new(struct snd_soc_component *component,
|
||||
static struct snd_soc_component_driver cygnus_soc_platform = {
|
||||
.open = cygnus_pcm_open,
|
||||
.close = cygnus_pcm_close,
|
||||
.hw_params = cygnus_pcm_hw_params,
|
||||
.hw_free = cygnus_pcm_hw_free,
|
||||
.prepare = cygnus_pcm_prepare,
|
||||
.trigger = cygnus_pcm_trigger,
|
||||
.pointer = cygnus_pcm_pointer,
|
||||
.pcm_construct = cygnus_dma_new,
|
||||
.pcm_destruct = cygnus_dma_free_dma_buffers,
|
||||
};
|
||||
|
||||
int cygnus_soc_platform_register(struct device *dev,
|
||||
|
@ -404,7 +404,7 @@ static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
|
||||
#define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
||||
static struct snd_soc_dai_driver ep93xx_i2s_dai = {
|
||||
.symmetric_rates= 1,
|
||||
.symmetric_rate = 1,
|
||||
.probe = ep93xx_i2s_dai_probe,
|
||||
.playback = {
|
||||
.channels_min = 2,
|
||||
|
@ -104,6 +104,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_ISABELLE
|
||||
imply SND_SOC_JZ4740_CODEC
|
||||
imply SND_SOC_JZ4725B_CODEC
|
||||
imply SND_SOC_JZ4760_CODEC
|
||||
imply SND_SOC_JZ4770_CODEC
|
||||
imply SND_SOC_LM4857
|
||||
imply SND_SOC_LM49453
|
||||
@ -227,6 +228,8 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_UDA1380
|
||||
imply SND_SOC_WCD9335
|
||||
imply SND_SOC_WCD934X
|
||||
imply SND_SOC_LPASS_RX_MACRO
|
||||
imply SND_SOC_LPASS_TX_MACRO
|
||||
imply SND_SOC_WL1273
|
||||
imply SND_SOC_WM0010
|
||||
imply SND_SOC_WM1250_EV1
|
||||
@ -712,7 +715,7 @@ config SND_SOC_CX2072X
|
||||
Enable support for Conexant CX20721 and CX20723 codec chips.
|
||||
|
||||
config SND_SOC_JZ4740_CODEC
|
||||
depends on MIPS || COMPILE_TEST
|
||||
depends on MACH_INGENIC || COMPILE_TEST
|
||||
depends on OF
|
||||
select REGMAP_MMIO
|
||||
tristate "Ingenic JZ4740 internal CODEC"
|
||||
@ -724,7 +727,7 @@ config SND_SOC_JZ4740_CODEC
|
||||
will be called snd-soc-jz4740-codec.
|
||||
|
||||
config SND_SOC_JZ4725B_CODEC
|
||||
depends on MIPS || COMPILE_TEST
|
||||
depends on MACH_INGENIC || COMPILE_TEST
|
||||
depends on OF
|
||||
select REGMAP
|
||||
tristate "Ingenic JZ4725B internal CODEC"
|
||||
@ -735,8 +738,20 @@ config SND_SOC_JZ4725B_CODEC
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called snd-soc-jz4725b-codec.
|
||||
|
||||
config SND_SOC_JZ4760_CODEC
|
||||
depends on MACH_INGENIC || COMPILE_TEST
|
||||
depends on OF
|
||||
select REGMAP
|
||||
tristate "Ingenic JZ4760 internal CODEC"
|
||||
help
|
||||
Enable support for the internal CODEC found in the JZ4760 SoC
|
||||
from Ingenic.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called snd-soc-jz4760-codec.
|
||||
|
||||
config SND_SOC_JZ4770_CODEC
|
||||
depends on MIPS || COMPILE_TEST
|
||||
depends on MACH_INGENIC || COMPILE_TEST
|
||||
depends on OF
|
||||
select REGMAP
|
||||
tristate "Ingenic JZ4770 internal CODEC"
|
||||
@ -1162,7 +1177,7 @@ config SND_SOC_RT5651
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_RT5659
|
||||
tristate
|
||||
tristate "Realtek RT5658/RT5659 Codec"
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_RT5660
|
||||
@ -1820,4 +1835,12 @@ config SND_SOC_LPASS_VA_MACRO
|
||||
depends on COMMON_CLK
|
||||
tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)"
|
||||
|
||||
config SND_SOC_LPASS_RX_MACRO
|
||||
depends on COMMON_CLK
|
||||
tristate "Qualcomm RX Macro in LPASS(Low Power Audio SubSystem)"
|
||||
|
||||
config SND_SOC_LPASS_TX_MACRO
|
||||
depends on COMMON_CLK
|
||||
tristate "Qualcomm TX Macro in LPASS(Low Power Audio SubSystem)"
|
||||
|
||||
endmenu
|
||||
|
@ -101,11 +101,14 @@ snd-soc-inno-rk3036-objs := inno_rk3036.o
|
||||
snd-soc-isabelle-objs := isabelle.o
|
||||
snd-soc-jz4740-codec-objs := jz4740.o
|
||||
snd-soc-jz4725b-codec-objs := jz4725b.o
|
||||
snd-soc-jz4760-codec-objs := jz4760.o
|
||||
snd-soc-jz4770-codec-objs := jz4770.o
|
||||
snd-soc-l3-objs := l3.o
|
||||
snd-soc-lm4857-objs := lm4857.o
|
||||
snd-soc-lm49453-objs := lm49453.o
|
||||
snd-soc-lochnagar-sc-objs := lochnagar-sc.o
|
||||
snd-soc-lpass-rx-macro-objs := lpass-rx-macro.o
|
||||
snd-soc-lpass-tx-macro-objs := lpass-tx-macro.o
|
||||
snd-soc-lpass-wsa-macro-objs := lpass-wsa-macro.o
|
||||
snd-soc-lpass-va-macro-objs := lpass-va-macro.o
|
||||
snd-soc-madera-objs := madera.o
|
||||
@ -201,7 +204,6 @@ snd-soc-sigmadsp-objs := sigmadsp.o
|
||||
snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o
|
||||
snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o
|
||||
snd-soc-si476x-objs := si476x.o
|
||||
snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o
|
||||
snd-soc-spdif-tx-objs := spdif_transmitter.o
|
||||
snd-soc-spdif-rx-objs := spdif_receiver.o
|
||||
snd-soc-ssm2305-objs := ssm2305.o
|
||||
@ -302,7 +304,6 @@ snd-soc-wm9713-objs := wm9713.o
|
||||
snd-soc-wm-hubs-objs := wm_hubs.o
|
||||
snd-soc-wsa881x-objs := wsa881x.o
|
||||
snd-soc-zl38060-objs := zl38060.o
|
||||
snd-soc-zx-aud96p22-objs := zx_aud96p22.o
|
||||
# Amp
|
||||
snd-soc-max9877-objs := max9877.o
|
||||
snd-soc-max98504-objs := max98504.o
|
||||
@ -418,6 +419,7 @@ obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o
|
||||
obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
|
||||
obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
|
||||
obj-$(CONFIG_SND_SOC_JZ4725B_CODEC) += snd-soc-jz4725b-codec.o
|
||||
obj-$(CONFIG_SND_SOC_JZ4760_CODEC) += snd-soc-jz4760-codec.o
|
||||
obj-$(CONFIG_SND_SOC_JZ4770_CODEC) += snd-soc-jz4770-codec.o
|
||||
obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
|
||||
obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
|
||||
@ -516,7 +518,6 @@ obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o
|
||||
obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o
|
||||
obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
|
||||
obj-$(CONFIG_SND_SOC_SIRF_AUDIO_CODEC) += sirf-audio-codec.o
|
||||
obj-$(CONFIG_SND_SOC_SSM2305) += snd-soc-ssm2305.o
|
||||
obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o
|
||||
obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
|
||||
@ -618,7 +619,6 @@ obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o
|
||||
obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
|
||||
obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o
|
||||
obj-$(CONFIG_SND_SOC_ZL38060) += snd-soc-zl38060.o
|
||||
obj-$(CONFIG_SND_SOC_ZX_AUD96P22) += snd-soc-zx-aud96p22.o
|
||||
|
||||
# Amp
|
||||
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
|
||||
@ -627,6 +627,8 @@ obj-$(CONFIG_SND_SOC_SIMPLE_AMPLIFIER) += snd-soc-simple-amplifier.o
|
||||
obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
|
||||
obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO) += snd-soc-lpass-wsa-macro.o
|
||||
obj-$(CONFIG_SND_SOC_LPASS_VA_MACRO) += snd-soc-lpass-va-macro.o
|
||||
obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o
|
||||
obj-$(CONFIG_SND_SOC_LPASS_TX_MACRO) += snd-soc-lpass-tx-macro.o
|
||||
|
||||
# Mux
|
||||
obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o
|
||||
|
@ -2384,7 +2384,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = {
|
||||
.formats = AB8500_SUPPORTED_FMT,
|
||||
},
|
||||
.ops = &ab8500_codec_ops,
|
||||
.symmetric_rates = 1
|
||||
.symmetric_rate = 1
|
||||
},
|
||||
{
|
||||
.name = "ab8500-codec-dai.1",
|
||||
@ -2397,7 +2397,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = {
|
||||
.formats = AB8500_SUPPORTED_FMT,
|
||||
},
|
||||
.ops = &ab8500_codec_ops,
|
||||
.symmetric_rates = 1
|
||||
.symmetric_rate = 1
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -890,7 +890,7 @@ static struct snd_soc_dai_driver adau1372_dai_driver = {
|
||||
.sig_bits = 24,
|
||||
},
|
||||
.ops = &adau1372_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int adau1372_setup_pll(struct adau1372 *adau1372, unsigned int rate)
|
||||
|
@ -1205,7 +1205,7 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = {
|
||||
.formats = ADAU1373_FORMATS,
|
||||
},
|
||||
.ops = &adau1373_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
{
|
||||
.id = 1,
|
||||
@ -1225,7 +1225,7 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = {
|
||||
.formats = ADAU1373_FORMATS,
|
||||
},
|
||||
.ops = &adau1373_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
{
|
||||
.id = 2,
|
||||
@ -1245,7 +1245,7 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = {
|
||||
.formats = ADAU1373_FORMATS,
|
||||
},
|
||||
.ops = &adau1373_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -653,7 +653,7 @@ static struct snd_soc_dai_driver adau1701_dai = {
|
||||
.formats = ADAU1701_FORMATS,
|
||||
},
|
||||
.ops = &adau1701_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
@ -1095,8 +1095,7 @@ void adau17x1_remove(struct device *dev)
|
||||
{
|
||||
struct adau *adau = dev_get_drvdata(dev);
|
||||
|
||||
if (adau->mclk)
|
||||
clk_disable_unprepare(adau->mclk);
|
||||
clk_disable_unprepare(adau->mclk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(adau17x1_remove);
|
||||
|
||||
|
@ -56,7 +56,7 @@ static struct snd_soc_dai_driver ak4554_dai = {
|
||||
.rates = SNDRV_PCM_RATE_8000_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
},
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver soc_component_dev_ak4554 = {
|
||||
|
@ -575,7 +575,7 @@ static struct snd_soc_dai_driver ak4613_dai = {
|
||||
.formats = AK4613_PCM_FMTBIT,
|
||||
},
|
||||
.ops = &ak4613_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int ak4613_suspend(struct snd_soc_component *component)
|
||||
|
@ -499,7 +499,7 @@ static struct snd_soc_dai_driver ak4641_dai[] = {
|
||||
.formats = AK4641_FORMATS,
|
||||
},
|
||||
.ops = &ak4641_i2s_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
{
|
||||
.name = "ak4641-voice",
|
||||
@ -519,7 +519,7 @@ static struct snd_soc_dai_driver ak4641_dai[] = {
|
||||
.formats = AK4641_FORMATS,
|
||||
},
|
||||
.ops = &ak4641_pcm_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -516,7 +516,7 @@ static struct snd_soc_dai_driver ak4642_dai = {
|
||||
.rates = SNDRV_PCM_RATE_8000_48000,
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE },
|
||||
.ops = &ak4642_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int ak4642_suspend(struct snd_soc_component *component)
|
||||
|
@ -1032,7 +1032,7 @@ static struct snd_soc_dai_driver alc5632_dai = {
|
||||
.formats = ALC5632_FORMATS,},
|
||||
|
||||
.ops = &alc5632_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -16,6 +16,14 @@
|
||||
#include <sound/soc.h>
|
||||
#include <sound/tlv.h>
|
||||
|
||||
/* Register 512 CPCAP_REG_VAUDIOC --- Audio Regulator and Bias Voltage */
|
||||
#define CPCAP_BIT_AUDIO_LOW_PWR 6
|
||||
#define CPCAP_BIT_AUD_LOWPWR_SPEED 5
|
||||
#define CPCAP_BIT_VAUDIOPRISTBY 4
|
||||
#define CPCAP_BIT_VAUDIO_MODE1 2
|
||||
#define CPCAP_BIT_VAUDIO_MODE0 1
|
||||
#define CPCAP_BIT_V_AUDIO_EN 0
|
||||
|
||||
/* Register 513 CPCAP_REG_CC --- CODEC */
|
||||
#define CPCAP_BIT_CDC_CLK2 15
|
||||
#define CPCAP_BIT_CDC_CLK1 14
|
||||
@ -221,6 +229,7 @@ struct cpcap_reg_info {
|
||||
};
|
||||
|
||||
static const struct cpcap_reg_info cpcap_default_regs[] = {
|
||||
{ CPCAP_REG_VAUDIOC, 0x003F, 0x0000 },
|
||||
{ CPCAP_REG_CC, 0xFFFF, 0x0000 },
|
||||
{ CPCAP_REG_CC, 0xFFFF, 0x0000 },
|
||||
{ CPCAP_REG_CDI, 0xBFFF, 0x0000 },
|
||||
@ -1371,8 +1380,121 @@ static int cpcap_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpcap_voice_set_mute(struct snd_soc_dai *dai,
|
||||
int mute, int direction)
|
||||
|
||||
/*
|
||||
* Configure codec for voice call if requested.
|
||||
*
|
||||
* We can configure most with snd_soc_dai_set_sysclk(), snd_soc_dai_set_fmt()
|
||||
* and snd_soc_dai_set_tdm_slot(). This function configures the rest of the
|
||||
* cpcap related hardware as CPU is not involved in the voice call.
|
||||
*/
|
||||
static int cpcap_voice_call(struct cpcap_audio *cpcap, struct snd_soc_dai *dai,
|
||||
bool voice_call)
|
||||
{
|
||||
int mask, err;
|
||||
|
||||
/* Modem to codec VAUDIO_MODE1 */
|
||||
mask = BIT(CPCAP_BIT_VAUDIO_MODE1);
|
||||
err = regmap_update_bits(cpcap->regmap, CPCAP_REG_VAUDIOC,
|
||||
mask, voice_call ? mask : 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Clear MIC1_MUX for call */
|
||||
mask = BIT(CPCAP_BIT_MIC1_MUX);
|
||||
err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
|
||||
mask, voice_call ? 0 : mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Set MIC2_MUX for call */
|
||||
mask = BIT(CPCAP_BIT_MB_ON1L) | BIT(CPCAP_BIT_MB_ON1R) |
|
||||
BIT(CPCAP_BIT_MIC2_MUX) | BIT(CPCAP_BIT_MIC2_PGA_EN);
|
||||
err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI,
|
||||
mask, voice_call ? mask : 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Enable LDSP for call */
|
||||
mask = BIT(CPCAP_BIT_A2_LDSP_L_EN) | BIT(CPCAP_BIT_A2_LDSP_R_EN);
|
||||
err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXOA,
|
||||
mask, voice_call ? mask : 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Enable CPCAP_BIT_PGA_CDC_EN for call */
|
||||
mask = BIT(CPCAP_BIT_PGA_CDC_EN);
|
||||
err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA,
|
||||
mask, voice_call ? mask : 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Unmute voice for call */
|
||||
if (dai) {
|
||||
err = snd_soc_dai_digital_mute(dai, !voice_call,
|
||||
SNDRV_PCM_STREAM_PLAYBACK);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Set modem to codec mic CDC and HPF for call */
|
||||
mask = BIT(CPCAP_BIT_MIC2_CDC_EN) | BIT(CPCAP_BIT_CDC_EN_RX) |
|
||||
BIT(CPCAP_BIT_AUDOHPF_1) | BIT(CPCAP_BIT_AUDOHPF_0) |
|
||||
BIT(CPCAP_BIT_AUDIHPF_1) | BIT(CPCAP_BIT_AUDIHPF_0);
|
||||
err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC,
|
||||
mask, voice_call ? mask : 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Enable modem to codec CDC for call*/
|
||||
mask = BIT(CPCAP_BIT_CDC_CLK_EN);
|
||||
err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
|
||||
mask, voice_call ? mask : 0);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cpcap_voice_set_tdm_slot(struct snd_soc_dai *dai,
|
||||
unsigned int tx_mask, unsigned int rx_mask,
|
||||
int slots, int slot_width)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
|
||||
int err, ts_mask, mask;
|
||||
bool voice_call;
|
||||
|
||||
/*
|
||||
* Primitive test for voice call, probably needs more checks
|
||||
* later on for 16-bit calls detected, Bluetooth headset etc.
|
||||
*/
|
||||
if (tx_mask == 0 && rx_mask == 1 && slot_width == 8)
|
||||
voice_call = true;
|
||||
else
|
||||
voice_call = false;
|
||||
|
||||
ts_mask = 0x7 << CPCAP_BIT_MIC2_TIMESLOT0;
|
||||
ts_mask |= 0x7 << CPCAP_BIT_MIC1_RX_TIMESLOT0;
|
||||
|
||||
mask = (tx_mask & 0x7) << CPCAP_BIT_MIC2_TIMESLOT0;
|
||||
mask |= (rx_mask & 0x7) << CPCAP_BIT_MIC1_RX_TIMESLOT0;
|
||||
|
||||
err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI,
|
||||
ts_mask, mask);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, slot_width * 1000);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = cpcap_voice_call(cpcap, dai, voice_call);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpcap_voice_set_mute(struct snd_soc_dai *dai, int mute, int direction)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component);
|
||||
@ -1393,6 +1515,7 @@ static const struct snd_soc_dai_ops cpcap_dai_voice_ops = {
|
||||
.hw_params = cpcap_voice_hw_params,
|
||||
.set_sysclk = cpcap_voice_set_dai_sysclk,
|
||||
.set_fmt = cpcap_voice_set_dai_fmt,
|
||||
.set_tdm_slot = cpcap_voice_set_tdm_slot,
|
||||
.mute_stream = cpcap_voice_set_mute,
|
||||
.no_capture_mute = 1,
|
||||
};
|
||||
|
@ -1011,6 +1011,18 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev)
|
||||
}
|
||||
priv->ec_capabilities = r.capabilities;
|
||||
|
||||
/* Reset EC codec i2s rx. */
|
||||
p.cmd = EC_CODEC_I2S_RX_RESET;
|
||||
ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX,
|
||||
(uint8_t *)&p, sizeof(p), NULL, 0);
|
||||
if (ret == -ENOPROTOOPT) {
|
||||
dev_info(dev,
|
||||
"Missing reset command. Please update EC firmware.\n");
|
||||
} else if (ret) {
|
||||
dev_err(dev, "failed to EC_CODEC_I2S_RESET: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
ret = devm_snd_soc_register_component(dev, &i2s_rx_component_driver,
|
||||
|
@ -194,7 +194,7 @@ static struct snd_soc_dai_driver cs35l32_dai[] = {
|
||||
.formats = CS35L32_FORMATS,
|
||||
},
|
||||
.ops = &cs35l32_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -691,7 +691,7 @@ static struct snd_soc_dai_driver cs35l33_dai = {
|
||||
.formats = CS35L33_FORMATS,
|
||||
},
|
||||
.ops = &cs35l33_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int cs35l33_set_hg_data(struct snd_soc_component *component,
|
||||
|
@ -666,7 +666,7 @@ static struct snd_soc_dai_driver cs35l34_dai = {
|
||||
.formats = CS35L34_FORMATS,
|
||||
},
|
||||
.ops = &cs35l34_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int cs35l34_boost_inductor(struct cs35l34_private *cs35l34,
|
||||
|
@ -692,7 +692,7 @@ static struct snd_soc_dai_driver cs35l35_dai[] = {
|
||||
.formats = CS35L35_FORMATS,
|
||||
},
|
||||
.ops = &cs35l35_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs35l35-pdm",
|
||||
|
@ -995,7 +995,7 @@ static struct snd_soc_dai_driver cs35l36_dai[] = {
|
||||
.formats = CS35L36_TX_FORMATS,
|
||||
},
|
||||
.ops = &cs35l36_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -585,7 +585,7 @@ static struct snd_soc_dai_driver cs4234_dai[] = {
|
||||
.formats = CS4234_FORMATS,
|
||||
},
|
||||
.ops = &cs4234_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -481,7 +481,7 @@ static struct snd_soc_dai_driver cs4271_dai = {
|
||||
.formats = CS4271_PCM_FORMATS,
|
||||
},
|
||||
.ops = &cs4271_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int cs4271_reset(struct snd_soc_component *component)
|
||||
|
@ -1250,6 +1250,7 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client,
|
||||
dev_err(&i2c_client->dev,
|
||||
"CS42L56 Device ID (%X). Expected %X\n",
|
||||
devid, CS42L56_DEVID);
|
||||
ret = -EINVAL;
|
||||
goto err_enable;
|
||||
}
|
||||
alpha_rev = reg & CS42L56_AREV_MASK;
|
||||
@ -1307,7 +1308,7 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client,
|
||||
ret = devm_snd_soc_register_component(&i2c_client->dev,
|
||||
&soc_component_dev_cs42l56, &cs42l56_dai, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err_enable;
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -1181,7 +1181,7 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
|
||||
.formats = CS42L73_FORMATS,
|
||||
},
|
||||
.ops = &cs42l73_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs42l73-asp",
|
||||
@ -1201,7 +1201,7 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
|
||||
.formats = CS42L73_FORMATS,
|
||||
},
|
||||
.ops = &cs42l73_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs42l73-vsp",
|
||||
@ -1221,7 +1221,7 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
|
||||
.formats = CS42L73_FORMATS,
|
||||
},
|
||||
.ops = &cs42l73_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1581,7 +1581,7 @@ static struct snd_soc_dai_driver cs43130_dai[] = {
|
||||
.formats = CS43130_PCM_FORMATS,
|
||||
},
|
||||
.ops = &cs43130_pcm_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs43130-asp-dop",
|
||||
@ -1594,7 +1594,7 @@ static struct snd_soc_dai_driver cs43130_dai[] = {
|
||||
.formats = CS43130_DOP_FORMATS,
|
||||
},
|
||||
.ops = &cs43130_dop_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs43130-xsp-dop",
|
||||
@ -1607,7 +1607,7 @@ static struct snd_soc_dai_driver cs43130_dai[] = {
|
||||
.formats = CS43130_DOP_FORMATS,
|
||||
},
|
||||
.ops = &cs43130_dop_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs43130-xsp-dsd",
|
||||
|
@ -189,7 +189,7 @@ static struct snd_soc_dai_driver cs4341_dai = {
|
||||
SNDRV_PCM_FMTBIT_S24_LE,
|
||||
},
|
||||
.ops = &cs4341_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver soc_component_cs4341 = {
|
||||
|
@ -250,7 +250,7 @@ static struct snd_soc_dai_driver cs4349_dai = {
|
||||
.formats = CS4349_PCM_FORMATS,
|
||||
},
|
||||
.ops = &cs4349_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver soc_component_dev_cs4349 = {
|
||||
|
@ -1160,8 +1160,8 @@ static struct snd_soc_dai_driver cs47l15_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l15-aif2",
|
||||
@ -1182,8 +1182,8 @@ static struct snd_soc_dai_driver cs47l15_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l15-aif3",
|
||||
@ -1204,8 +1204,8 @@ static struct snd_soc_dai_driver cs47l15_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l15-cpu-trace",
|
||||
|
@ -977,8 +977,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = {
|
||||
.formats = CS47L24_FORMATS,
|
||||
},
|
||||
.ops = &arizona_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l24-aif2",
|
||||
@ -999,8 +999,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = {
|
||||
.formats = CS47L24_FORMATS,
|
||||
},
|
||||
.ops = &arizona_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l24-aif3",
|
||||
@ -1021,8 +1021,8 @@ static struct snd_soc_dai_driver cs47l24_dai[] = {
|
||||
.formats = CS47L24_FORMATS,
|
||||
},
|
||||
.ops = &arizona_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l24-cpu-voicectrl",
|
||||
|
@ -1368,8 +1368,8 @@ static struct snd_soc_dai_driver cs47l35_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l35-aif2",
|
||||
@ -1390,8 +1390,8 @@ static struct snd_soc_dai_driver cs47l35_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l35-aif3",
|
||||
@ -1412,8 +1412,8 @@ static struct snd_soc_dai_driver cs47l35_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l35-slim1",
|
||||
|
@ -2269,8 +2269,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l85-aif2",
|
||||
@ -2291,8 +2291,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l85-aif3",
|
||||
@ -2313,8 +2313,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l85-aif4",
|
||||
@ -2335,8 +2335,8 @@ static struct snd_soc_dai_driver cs47l85_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l85-slim1",
|
||||
|
@ -2188,8 +2188,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l90-aif2",
|
||||
@ -2210,8 +2210,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l90-aif3",
|
||||
@ -2232,8 +2232,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l90-aif4",
|
||||
@ -2254,8 +2254,8 @@ static struct snd_soc_dai_driver cs47l90_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l90-slim1",
|
||||
|
@ -1704,8 +1704,8 @@ static struct snd_soc_dai_driver cs47l92_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l92-aif2",
|
||||
@ -1726,8 +1726,8 @@ static struct snd_soc_dai_driver cs47l92_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l92-aif3",
|
||||
@ -1748,8 +1748,8 @@ static struct snd_soc_dai_driver cs47l92_dai[] = {
|
||||
.formats = MADERA_FORMATS,
|
||||
},
|
||||
.ops = &madera_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
},
|
||||
{
|
||||
.name = "cs47l92-slim1",
|
||||
|
@ -869,7 +869,7 @@ static struct snd_soc_dai_driver cs53l30_dai = {
|
||||
.formats = CS53L30_FORMATS,
|
||||
},
|
||||
.ops = &cs53l30_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int cs53l30_component_probe(struct snd_soc_component *component)
|
||||
|
@ -1572,7 +1572,7 @@ static struct snd_soc_dai_driver soc_codec_cx2072x_dai[] = {
|
||||
.formats = CX2072X_FORMATS,
|
||||
},
|
||||
.ops = &cx2072x_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
{ /* plabayck only, return echo reference to Conexant DSP chip */
|
||||
.name = "cx2072x-dsp",
|
||||
|
@ -1059,7 +1059,7 @@ static struct snd_soc_dai_driver da7210_dai = {
|
||||
.formats = DA7210_FORMATS,
|
||||
},
|
||||
.ops = &da7210_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int da7210_probe(struct snd_soc_component *component)
|
||||
|
@ -1551,7 +1551,7 @@ static struct snd_soc_dai_driver da7213_dai = {
|
||||
.formats = DA7213_FORMATS,
|
||||
},
|
||||
.ops = &da7213_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int da7213_set_auto_pll(struct snd_soc_component *component, bool enable)
|
||||
|
@ -2194,9 +2194,9 @@ static struct snd_soc_dai_driver da7218_dai = {
|
||||
.formats = DA7218_FORMATS,
|
||||
},
|
||||
.ops = &da7218_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_channels = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
};
|
||||
|
||||
|
||||
@ -2278,14 +2278,12 @@ static irqreturn_t da7218_irq_thread(int irq, void *data)
|
||||
* DT
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id da7218_of_match[] = {
|
||||
{ .compatible = "dlg,da7217", .data = (void *) DA7217_DEV_ID },
|
||||
{ .compatible = "dlg,da7218", .data = (void *) DA7218_DEV_ID },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, da7218_of_match);
|
||||
#endif
|
||||
|
||||
static inline int da7218_of_get_id(struct device *dev)
|
||||
{
|
||||
@ -3311,7 +3309,7 @@ MODULE_DEVICE_TABLE(i2c, da7218_i2c_id);
|
||||
static struct i2c_driver da7218_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "da7218",
|
||||
.of_match_table = of_match_ptr(da7218_of_match),
|
||||
.of_match_table = da7218_of_match,
|
||||
},
|
||||
.probe = da7218_i2c_probe,
|
||||
.id_table = da7218_i2c_id,
|
||||
|
@ -1692,9 +1692,9 @@ static struct snd_soc_dai_driver da7219_dai = {
|
||||
.formats = DA7219_FORMATS,
|
||||
},
|
||||
.ops = &da7219_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
.symmetric_channels = 1,
|
||||
.symmetric_samplebits = 1,
|
||||
.symmetric_sample_bits = 1,
|
||||
};
|
||||
|
||||
|
||||
|
@ -1347,7 +1347,7 @@ static struct snd_soc_dai_driver da9055_dai = {
|
||||
.formats = DA9055_FORMATS,
|
||||
},
|
||||
.ops = &da9055_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int da9055_set_bias_level(struct snd_soc_component *component,
|
||||
|
@ -543,7 +543,7 @@ static struct snd_soc_dai_driver es8316_dai = {
|
||||
.formats = ES8316_FORMATS,
|
||||
},
|
||||
.ops = &es8316_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static void es8316_enable_micbias_for_mic_gnd_short_detect(
|
||||
@ -681,6 +681,9 @@ static void es8316_disable_jack_detect(struct snd_soc_component *component)
|
||||
{
|
||||
struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (!es8316->jack)
|
||||
return; /* Already disabled (or never enabled) */
|
||||
|
||||
disable_irq(es8316->irq);
|
||||
|
||||
mutex_lock(&es8316->lock);
|
||||
|
@ -715,7 +715,7 @@ static struct snd_soc_dai_driver es8328_dai = {
|
||||
.formats = ES8328_FORMATS,
|
||||
},
|
||||
.ops = &es8328_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int es8328_suspend(struct snd_soc_component *component)
|
||||
@ -809,8 +809,7 @@ static void es8328_remove(struct snd_soc_component *component)
|
||||
|
||||
es8328 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
if (es8328->clk)
|
||||
clk_disable_unprepare(es8328->clk);
|
||||
clk_disable_unprepare(es8328->clk);
|
||||
|
||||
regulator_bulk_disable(ARRAY_SIZE(es8328->supplies),
|
||||
es8328->supplies);
|
||||
|
@ -489,6 +489,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
|
||||
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);
|
||||
}
|
||||
@ -617,7 +618,8 @@ static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = {
|
||||
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
|
||||
SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
|
||||
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
|
||||
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
|
||||
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\
|
||||
SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
|
||||
|
||||
static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_soc_dai *dai)
|
||||
|
@ -325,7 +325,7 @@ static struct snd_soc_dai_driver rk3036_codec_dai_driver[] = {
|
||||
.formats = RK3036_CODEC_FMTS,
|
||||
},
|
||||
.ops = &rk3036_codec_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -214,7 +214,7 @@ static struct snd_soc_dai_driver jz4740_codec_dai = {
|
||||
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
|
||||
},
|
||||
.ops = &jz4740_codec_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static void jz4740_codec_wakeup(struct regmap *regmap)
|
||||
|
889
sound/soc/codecs/jz4760.c
Normal file
889
sound/soc/codecs/jz4760.c
Normal file
@ -0,0 +1,889 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Ingenic JZ4760 CODEC driver
|
||||
//
|
||||
// Copyright (C) 2021, Christophe Branchereau <cbranchereau@gmail.com>
|
||||
// Copyright (C) 2021, Paul Cercueil <paul@crapouillou.net>
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/time64.h>
|
||||
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/soc-dai.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
#include <sound/tlv.h>
|
||||
|
||||
#define ICDC_RGADW_OFFSET 0x00
|
||||
#define ICDC_RGDATA_OFFSET 0x04
|
||||
|
||||
/* ICDC internal register access control register(RGADW) */
|
||||
#define ICDC_RGADW_RGWR BIT(16)
|
||||
#define ICDC_RGADW_RGADDR_MASK GENMASK(14, 8)
|
||||
#define ICDC_RGADW_RGDIN_MASK GENMASK(7, 0)
|
||||
|
||||
/* ICDC internal register data output register (RGDATA)*/
|
||||
#define ICDC_RGDATA_IRQ BIT(8)
|
||||
#define ICDC_RGDATA_RGDOUT_MASK GENMASK(7, 0)
|
||||
|
||||
/* Internal register space, accessed through regmap */
|
||||
enum {
|
||||
JZ4760_CODEC_REG_SR,
|
||||
JZ4760_CODEC_REG_AICR,
|
||||
JZ4760_CODEC_REG_CR1,
|
||||
JZ4760_CODEC_REG_CR2,
|
||||
JZ4760_CODEC_REG_CR3,
|
||||
JZ4760_CODEC_REG_CR4,
|
||||
JZ4760_CODEC_REG_CCR1,
|
||||
JZ4760_CODEC_REG_CCR2,
|
||||
JZ4760_CODEC_REG_PMR1,
|
||||
JZ4760_CODEC_REG_PMR2,
|
||||
JZ4760_CODEC_REG_ICR,
|
||||
JZ4760_CODEC_REG_IFR,
|
||||
JZ4760_CODEC_REG_GCR1,
|
||||
JZ4760_CODEC_REG_GCR2,
|
||||
JZ4760_CODEC_REG_GCR3,
|
||||
JZ4760_CODEC_REG_GCR4,
|
||||
JZ4760_CODEC_REG_GCR5,
|
||||
JZ4760_CODEC_REG_GCR6,
|
||||
JZ4760_CODEC_REG_GCR7,
|
||||
JZ4760_CODEC_REG_GCR8,
|
||||
JZ4760_CODEC_REG_GCR9,
|
||||
JZ4760_CODEC_REG_AGC1,
|
||||
JZ4760_CODEC_REG_AGC2,
|
||||
JZ4760_CODEC_REG_AGC3,
|
||||
JZ4760_CODEC_REG_AGC4,
|
||||
JZ4760_CODEC_REG_AGC5,
|
||||
JZ4760_CODEC_REG_MIX1,
|
||||
JZ4760_CODEC_REG_MIX2,
|
||||
};
|
||||
|
||||
#define REG_AICR_DAC_ADWL_MASK GENMASK(7, 6)
|
||||
#define REG_AICR_DAC_SERIAL BIT(3)
|
||||
#define REG_AICR_DAC_I2S BIT(1)
|
||||
|
||||
#define REG_AICR_ADC_ADWL_MASK GENMASK(5, 4)
|
||||
|
||||
#define REG_AICR_ADC_SERIAL BIT(2)
|
||||
#define REG_AICR_ADC_I2S BIT(0)
|
||||
|
||||
#define REG_CR1_HP_LOAD BIT(7)
|
||||
#define REG_CR1_HP_MUTE BIT(5)
|
||||
#define REG_CR1_LO_MUTE_OFFSET 4
|
||||
#define REG_CR1_BTL_MUTE_OFFSET 3
|
||||
#define REG_CR1_OUTSEL_OFFSET 0
|
||||
#define REG_CR1_OUTSEL_MASK GENMASK(1, REG_CR1_OUTSEL_OFFSET)
|
||||
|
||||
#define REG_CR2_DAC_MONO BIT(7)
|
||||
#define REG_CR2_DAC_MUTE BIT(5)
|
||||
#define REG_CR2_DAC_NOMAD BIT(1)
|
||||
#define REG_CR2_DAC_RIGHT_ONLY BIT(0)
|
||||
|
||||
#define REG_CR3_ADC_INSEL_OFFSET 2
|
||||
#define REG_CR3_ADC_INSEL_MASK GENMASK(3, REG_CR3_ADC_INSEL_OFFSET)
|
||||
#define REG_CR3_MICSTEREO_OFFSET 1
|
||||
#define REG_CR3_MICDIFF_OFFSET 0
|
||||
|
||||
#define REG_CR4_ADC_HPF_OFFSET 7
|
||||
#define REG_CR4_ADC_RIGHT_ONLY BIT(0)
|
||||
|
||||
#define REG_CCR1_CRYSTAL_MASK GENMASK(3, 0)
|
||||
|
||||
#define REG_CCR2_DAC_FREQ_MASK GENMASK(7, 4)
|
||||
#define REG_CCR2_ADC_FREQ_MASK GENMASK(3, 0)
|
||||
|
||||
#define REG_PMR1_SB BIT(7)
|
||||
#define REG_PMR1_SB_SLEEP BIT(6)
|
||||
#define REG_PMR1_SB_AIP_OFFSET 5
|
||||
#define REG_PMR1_SB_LINE_OFFSET 4
|
||||
#define REG_PMR1_SB_MIC1_OFFSET 3
|
||||
#define REG_PMR1_SB_MIC2_OFFSET 2
|
||||
#define REG_PMR1_SB_BYPASS_OFFSET 1
|
||||
#define REG_PMR1_SB_MICBIAS_OFFSET 0
|
||||
|
||||
#define REG_PMR2_SB_ADC_OFFSET 4
|
||||
#define REG_PMR2_SB_HP_OFFSET 3
|
||||
#define REG_PMR2_SB_BTL_OFFSET 2
|
||||
#define REG_PMR2_SB_LOUT_OFFSET 1
|
||||
#define REG_PMR2_SB_DAC_OFFSET 0
|
||||
|
||||
#define REG_ICR_INT_FORM_MASK GENMASK(7, 6)
|
||||
#define REG_ICR_ALL_MASK GENMASK(5, 0)
|
||||
#define REG_ICR_JACK_MASK BIT(5)
|
||||
#define REG_ICR_SCMC_MASK BIT(4)
|
||||
#define REG_ICR_RUP_MASK BIT(3)
|
||||
#define REG_ICR_RDO_MASK BIT(2)
|
||||
#define REG_ICR_GUP_MASK BIT(1)
|
||||
#define REG_ICR_GDO_MASK BIT(0)
|
||||
|
||||
#define REG_IFR_ALL_MASK GENMASK(5, 0)
|
||||
#define REG_IFR_JACK BIT(6)
|
||||
#define REG_IFR_JACK_EVENT BIT(5)
|
||||
#define REG_IFR_SCMC BIT(4)
|
||||
#define REG_IFR_RUP BIT(3)
|
||||
#define REG_IFR_RDO BIT(2)
|
||||
#define REG_IFR_GUP BIT(1)
|
||||
#define REG_IFR_GDO BIT(0)
|
||||
|
||||
#define REG_GCR_GAIN_OFFSET 0
|
||||
#define REG_GCR_GAIN_MAX 0x1f
|
||||
|
||||
#define REG_GCR_RL BIT(7)
|
||||
|
||||
#define REG_GCR_GIM1_MASK GENMASK(5, 3)
|
||||
#define REG_GCR_GIM2_MASK GENMASK(2, 0)
|
||||
#define REG_GCR_GIM_GAIN_MAX 7
|
||||
|
||||
#define REG_AGC1_EN BIT(7)
|
||||
#define REG_AGC1_TARGET_MASK GENMASK(5, 2)
|
||||
|
||||
#define REG_AGC2_NG_THR_MASK GENMASK(6, 4)
|
||||
#define REG_AGC2_HOLD_MASK GENMASK(3, 0)
|
||||
|
||||
#define REG_AGC3_ATK_MASK GENMASK(7, 4)
|
||||
#define REG_AGC3_DCY_MASK GENMASK(3, 0)
|
||||
|
||||
#define REG_AGC4_AGC_MAX_MASK GENMASK(4, 0)
|
||||
|
||||
#define REG_AGC5_AGC_MIN_MASK GENMASK(4, 0)
|
||||
|
||||
#define REG_MIX1_MIX_REC_MASK GENMASK(7, 6)
|
||||
#define REG_MIX1_GIMIX_MASK GENMASK(4, 0)
|
||||
|
||||
#define REG_MIX2_DAC_MIX_MASK GENMASK(7, 6)
|
||||
#define REG_MIX2_GOMIX_MASK GENMASK(4, 0)
|
||||
|
||||
/* codec private data */
|
||||
struct jz_codec {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
void __iomem *base;
|
||||
struct clk *clk;
|
||||
};
|
||||
|
||||
static int jz4760_codec_set_bias_level(struct snd_soc_component *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
|
||||
struct regmap *regmap = jz_codec->regmap;
|
||||
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
/* Reset all interrupt flags. */
|
||||
regmap_write(regmap, JZ4760_CODEC_REG_IFR, REG_IFR_ALL_MASK);
|
||||
|
||||
regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB);
|
||||
msleep(250);
|
||||
regmap_clear_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP);
|
||||
msleep(400);
|
||||
break;
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB_SLEEP);
|
||||
regmap_set_bits(regmap, JZ4760_CODEC_REG_PMR1, REG_PMR1_SB);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jz4760_codec_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_component *codec = dai->component;
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* SYSCLK output from the codec to the AIC is required to keep the
|
||||
* DMA transfer going during playback when all audible outputs have
|
||||
* been disabled.
|
||||
*/
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
ret = snd_soc_dapm_force_enable_pin(dapm, "SYSCLK");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void jz4760_codec_shutdown(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_component *codec = dai->component;
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
snd_soc_dapm_disable_pin(dapm, "SYSCLK");
|
||||
}
|
||||
|
||||
|
||||
static int jz4760_codec_pcm_trigger(struct snd_pcm_substream *substream,
|
||||
int cmd, struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_component *codec = dai->component;
|
||||
int ret = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
|
||||
snd_soc_component_force_bias_level(codec, SND_SOC_BIAS_ON);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
/* do nothing */
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int jz4760_codec_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
|
||||
{
|
||||
struct snd_soc_component *codec = dai->component;
|
||||
struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
|
||||
unsigned int gain_bit = mute ? REG_IFR_GDO : REG_IFR_GUP;
|
||||
unsigned int val, reg;
|
||||
int change, err;
|
||||
|
||||
change = snd_soc_component_update_bits(codec, JZ4760_CODEC_REG_CR2,
|
||||
REG_CR2_DAC_MUTE,
|
||||
mute ? REG_CR2_DAC_MUTE : 0);
|
||||
if (change == 1) {
|
||||
regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_PMR2, &val);
|
||||
|
||||
if (val & BIT(REG_PMR2_SB_DAC_OFFSET))
|
||||
return 1;
|
||||
|
||||
err = regmap_read_poll_timeout(jz_codec->regmap,
|
||||
JZ4760_CODEC_REG_IFR,
|
||||
val, val & gain_bit,
|
||||
1000, 1 * USEC_PER_SEC);
|
||||
if (err) {
|
||||
dev_err(jz_codec->dev,
|
||||
"Timeout while setting digital mute: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* clear GUP/GDO flag */
|
||||
regmap_write(jz_codec->regmap, JZ4760_CODEC_REG_IFR, gain_bit);
|
||||
}
|
||||
|
||||
regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_CR2, ®);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* unit: 0.01dB */
|
||||
static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 100);
|
||||
static const DECLARE_TLV_DB_SCALE(adc_tlv, 0, 100, 0);
|
||||
static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 100);
|
||||
static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0);
|
||||
|
||||
/* Unconditional controls. */
|
||||
static const struct snd_kcontrol_new jz4760_codec_snd_controls[] = {
|
||||
/* record gain control */
|
||||
SOC_DOUBLE_R_TLV("PCM Capture Volume",
|
||||
JZ4760_CODEC_REG_GCR9, JZ4760_CODEC_REG_GCR8,
|
||||
REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 0, adc_tlv),
|
||||
|
||||
SOC_DOUBLE_R_TLV("Line In Bypass Playback Volume",
|
||||
JZ4760_CODEC_REG_GCR4, JZ4760_CODEC_REG_GCR3,
|
||||
REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv),
|
||||
|
||||
SOC_SINGLE("High-Pass Filter Capture Switch",
|
||||
JZ4760_CODEC_REG_CR4,
|
||||
REG_CR4_ADC_HPF_OFFSET, 1, 0),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new jz4760_codec_pcm_playback_controls[] = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Volume",
|
||||
.info = snd_soc_info_volsw,
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
|
||||
| SNDRV_CTL_ELEM_ACCESS_READWRITE,
|
||||
.tlv.p = dac_tlv,
|
||||
.get = snd_soc_dapm_get_volsw,
|
||||
.put = snd_soc_dapm_put_volsw,
|
||||
.private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR6,
|
||||
JZ4760_CODEC_REG_GCR5,
|
||||
REG_GCR_GAIN_OFFSET,
|
||||
REG_GCR_GAIN_MAX, 1),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new jz4760_codec_hp_playback_controls[] = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Volume",
|
||||
.info = snd_soc_info_volsw,
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ
|
||||
| SNDRV_CTL_ELEM_ACCESS_READWRITE,
|
||||
.tlv.p = out_tlv,
|
||||
.get = snd_soc_dapm_get_volsw,
|
||||
.put = snd_soc_dapm_put_volsw,
|
||||
.private_value = SOC_DOUBLE_R_VALUE(JZ4760_CODEC_REG_GCR2,
|
||||
JZ4760_CODEC_REG_GCR1,
|
||||
REG_GCR_GAIN_OFFSET,
|
||||
REG_GCR_GAIN_MAX, 1),
|
||||
},
|
||||
};
|
||||
|
||||
static int hpout_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
|
||||
struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
|
||||
unsigned int val;
|
||||
int err;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
/* unmute HP */
|
||||
regmap_clear_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1,
|
||||
REG_CR1_HP_MUTE);
|
||||
break;
|
||||
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
/* wait for ramp-up complete (RUP) */
|
||||
err = regmap_read_poll_timeout(jz_codec->regmap,
|
||||
JZ4760_CODEC_REG_IFR,
|
||||
val, val & REG_IFR_RUP,
|
||||
1000, 1 * USEC_PER_SEC);
|
||||
if (err) {
|
||||
dev_err(jz_codec->dev, "RUP timeout: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* clear RUP flag */
|
||||
regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR,
|
||||
REG_IFR_RUP);
|
||||
|
||||
break;
|
||||
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* mute HP */
|
||||
regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1,
|
||||
REG_CR1_HP_MUTE);
|
||||
|
||||
err = regmap_read_poll_timeout(jz_codec->regmap,
|
||||
JZ4760_CODEC_REG_IFR,
|
||||
val, val & REG_IFR_RDO,
|
||||
1000, 1 * USEC_PER_SEC);
|
||||
if (err) {
|
||||
dev_err(jz_codec->dev, "RDO timeout: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* clear RDO flag */
|
||||
regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR,
|
||||
REG_IFR_RDO);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * const jz4760_codec_hp_texts[] = {
|
||||
"PCM", "Line In", "Mic 1", "Mic 2"
|
||||
};
|
||||
|
||||
static const unsigned int jz4760_codec_hp_values[] = { 3, 2, 0, 1 };
|
||||
|
||||
static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_hp_enum,
|
||||
JZ4760_CODEC_REG_CR1,
|
||||
REG_CR1_OUTSEL_OFFSET,
|
||||
REG_CR1_OUTSEL_MASK >> REG_CR1_OUTSEL_OFFSET,
|
||||
jz4760_codec_hp_texts,
|
||||
jz4760_codec_hp_values);
|
||||
static const struct snd_kcontrol_new jz4760_codec_hp_source =
|
||||
SOC_DAPM_ENUM("Route", jz4760_codec_hp_enum);
|
||||
|
||||
static const char * const jz4760_codec_cap_texts[] = {
|
||||
"Line In", "Mic 1", "Mic 2"
|
||||
};
|
||||
|
||||
static const unsigned int jz4760_codec_cap_values[] = { 2, 0, 1 };
|
||||
|
||||
static SOC_VALUE_ENUM_SINGLE_DECL(jz4760_codec_cap_enum,
|
||||
JZ4760_CODEC_REG_CR3,
|
||||
REG_CR3_ADC_INSEL_OFFSET,
|
||||
REG_CR3_ADC_INSEL_MASK >> REG_CR3_ADC_INSEL_OFFSET,
|
||||
jz4760_codec_cap_texts,
|
||||
jz4760_codec_cap_values);
|
||||
static const struct snd_kcontrol_new jz4760_codec_cap_source =
|
||||
SOC_DAPM_ENUM("Route", jz4760_codec_cap_enum);
|
||||
|
||||
static const struct snd_kcontrol_new jz4760_codec_mic_controls[] = {
|
||||
SOC_DAPM_SINGLE("Stereo Capture Switch", JZ4760_CODEC_REG_CR3,
|
||||
REG_CR3_MICSTEREO_OFFSET, 1, 0),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new jz4760_codec_line_out_switch =
|
||||
SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1,
|
||||
REG_CR1_LO_MUTE_OFFSET, 0, 0);
|
||||
static const struct snd_kcontrol_new jz4760_codec_btl_out_switch =
|
||||
SOC_DAPM_SINGLE("Switch", JZ4760_CODEC_REG_CR1,
|
||||
REG_CR1_BTL_MUTE_OFFSET, 0, 0);
|
||||
|
||||
static const struct snd_soc_dapm_widget jz4760_codec_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_PGA_E("HP Out", JZ4760_CODEC_REG_PMR2,
|
||||
REG_PMR2_SB_HP_OFFSET, 1, NULL, 0, hpout_event,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
|
||||
SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
SND_SOC_DAPM_SWITCH("Line Out", JZ4760_CODEC_REG_PMR2,
|
||||
REG_PMR2_SB_LOUT_OFFSET, 1,
|
||||
&jz4760_codec_line_out_switch),
|
||||
|
||||
SND_SOC_DAPM_SWITCH("BTL Out", JZ4760_CODEC_REG_PMR2,
|
||||
REG_PMR2_SB_BTL_OFFSET, 1,
|
||||
&jz4760_codec_btl_out_switch),
|
||||
|
||||
SND_SOC_DAPM_PGA("Line In", JZ4760_CODEC_REG_PMR1,
|
||||
REG_PMR1_SB_LINE_OFFSET, 1, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_MUX("Headphones Source", SND_SOC_NOPM, 0, 0,
|
||||
&jz4760_codec_hp_source),
|
||||
|
||||
SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
|
||||
&jz4760_codec_cap_source),
|
||||
|
||||
SND_SOC_DAPM_PGA("Mic 1", JZ4760_CODEC_REG_PMR1,
|
||||
REG_PMR1_SB_MIC1_OFFSET, 1, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_PGA("Mic 2", JZ4760_CODEC_REG_PMR1,
|
||||
REG_PMR1_SB_MIC2_OFFSET, 1, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_PGA("Mic Diff", JZ4760_CODEC_REG_CR3,
|
||||
REG_CR3_MICDIFF_OFFSET, 0, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_MIXER("Mic", SND_SOC_NOPM, 0, 0,
|
||||
jz4760_codec_mic_controls,
|
||||
ARRAY_SIZE(jz4760_codec_mic_controls)),
|
||||
|
||||
SND_SOC_DAPM_PGA("Line In Bypass", JZ4760_CODEC_REG_PMR1,
|
||||
REG_PMR1_SB_BYPASS_OFFSET, 1, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_ADC("ADC", "Capture", JZ4760_CODEC_REG_PMR2,
|
||||
REG_PMR2_SB_ADC_OFFSET, 1),
|
||||
|
||||
SND_SOC_DAPM_DAC("DAC", "Playback", JZ4760_CODEC_REG_PMR2,
|
||||
REG_PMR2_SB_DAC_OFFSET, 1),
|
||||
|
||||
SND_SOC_DAPM_MIXER("PCM Playback", SND_SOC_NOPM, 0, 0,
|
||||
jz4760_codec_pcm_playback_controls,
|
||||
ARRAY_SIZE(jz4760_codec_pcm_playback_controls)),
|
||||
|
||||
SND_SOC_DAPM_MIXER("Headphones Playback", SND_SOC_NOPM, 0, 0,
|
||||
jz4760_codec_hp_playback_controls,
|
||||
ARRAY_SIZE(jz4760_codec_hp_playback_controls)),
|
||||
|
||||
SND_SOC_DAPM_SUPPLY("MICBIAS", JZ4760_CODEC_REG_PMR1,
|
||||
REG_PMR1_SB_MICBIAS_OFFSET, 1, NULL, 0),
|
||||
|
||||
SND_SOC_DAPM_INPUT("MIC1P"),
|
||||
SND_SOC_DAPM_INPUT("MIC1N"),
|
||||
SND_SOC_DAPM_INPUT("MIC2P"),
|
||||
SND_SOC_DAPM_INPUT("MIC2N"),
|
||||
|
||||
SND_SOC_DAPM_INPUT("LLINEIN"),
|
||||
SND_SOC_DAPM_INPUT("RLINEIN"),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("LHPOUT"),
|
||||
SND_SOC_DAPM_OUTPUT("RHPOUT"),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("LOUT"),
|
||||
SND_SOC_DAPM_OUTPUT("ROUT"),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("BTLP"),
|
||||
SND_SOC_DAPM_OUTPUT("BTLN"),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("SYSCLK"),
|
||||
};
|
||||
|
||||
/* Unconditional routes. */
|
||||
static const struct snd_soc_dapm_route jz4760_codec_dapm_routes[] = {
|
||||
{ "Mic 1", NULL, "MIC1P" },
|
||||
{ "Mic Diff", NULL, "MIC1N" },
|
||||
{ "Mic 1", NULL, "Mic Diff" },
|
||||
{ "Mic 2", NULL, "MIC2P" },
|
||||
{ "Mic Diff", NULL, "MIC2N" },
|
||||
{ "Mic 2", NULL, "Mic Diff" },
|
||||
|
||||
{ "Line In", NULL, "LLINEIN" },
|
||||
{ "Line In", NULL, "RLINEIN" },
|
||||
|
||||
{ "Mic", "Stereo Capture Switch", "Mic 1" },
|
||||
{ "Mic", "Stereo Capture Switch", "Mic 2" },
|
||||
{ "Headphones Source", "Mic 1", "Mic" },
|
||||
{ "Headphones Source", "Mic 2", "Mic" },
|
||||
{ "Capture Source", "Mic 1", "Mic" },
|
||||
{ "Capture Source", "Mic 2", "Mic" },
|
||||
|
||||
{ "Capture Source", "Line In", "Line In" },
|
||||
{ "Capture Source", "Mic 1", "Mic 1" },
|
||||
{ "Capture Source", "Mic 2", "Mic 2" },
|
||||
{ "ADC", NULL, "Capture Source" },
|
||||
|
||||
{ "Line In Bypass", NULL, "Line In" },
|
||||
|
||||
{ "Headphones Source", "Mic 1", "Mic 1" },
|
||||
{ "Headphones Source", "Mic 2", "Mic 2" },
|
||||
{ "Headphones Source", "Line In", "Line In Bypass" },
|
||||
{ "Headphones Source", "PCM", "Headphones Playback" },
|
||||
{ "HP Out", NULL, "Headphones Source" },
|
||||
|
||||
{ "LHPOUT", NULL, "HP Out" },
|
||||
{ "RHPOUT", NULL, "HP Out" },
|
||||
{ "Line Out", "Switch", "HP Out" },
|
||||
|
||||
{ "LOUT", NULL, "Line Out" },
|
||||
{ "ROUT", NULL, "Line Out" },
|
||||
{ "BTL Out", "Switch", "Line Out" },
|
||||
|
||||
{ "BTLP", NULL, "BTL Out"},
|
||||
{ "BTLN", NULL, "BTL Out"},
|
||||
|
||||
{ "PCM Playback", "Volume", "DAC" },
|
||||
{ "Headphones Playback", "Volume", "PCM Playback" },
|
||||
|
||||
{ "SYSCLK", NULL, "DAC" },
|
||||
};
|
||||
|
||||
static void jz4760_codec_codec_init_regs(struct snd_soc_component *codec)
|
||||
{
|
||||
struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
|
||||
struct regmap *regmap = jz_codec->regmap;
|
||||
|
||||
/* Collect updates for later sending. */
|
||||
regcache_cache_only(regmap, true);
|
||||
|
||||
/* default Amp output to PCM */
|
||||
regmap_set_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_OUTSEL_MASK);
|
||||
|
||||
/* Disable stereo mic */
|
||||
regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3,
|
||||
BIT(REG_CR3_MICSTEREO_OFFSET));
|
||||
|
||||
/* Set mic 1 as default source for ADC */
|
||||
regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR3,
|
||||
REG_CR3_ADC_INSEL_MASK);
|
||||
|
||||
/* ADC/DAC: serial + i2s */
|
||||
regmap_set_bits(regmap, JZ4760_CODEC_REG_AICR,
|
||||
REG_AICR_ADC_SERIAL | REG_AICR_ADC_I2S |
|
||||
REG_AICR_DAC_SERIAL | REG_AICR_DAC_I2S);
|
||||
|
||||
/* The generated IRQ is a high level */
|
||||
regmap_clear_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_INT_FORM_MASK);
|
||||
regmap_update_bits(regmap, JZ4760_CODEC_REG_ICR, REG_ICR_ALL_MASK,
|
||||
REG_ICR_JACK_MASK | REG_ICR_RUP_MASK |
|
||||
REG_ICR_RDO_MASK | REG_ICR_GUP_MASK |
|
||||
REG_ICR_GDO_MASK);
|
||||
|
||||
/* 12M oscillator */
|
||||
regmap_clear_bits(regmap, JZ4760_CODEC_REG_CCR1, REG_CCR1_CRYSTAL_MASK);
|
||||
|
||||
/* 0: 16ohm/220uF, 1: 10kohm/1uF */
|
||||
regmap_clear_bits(regmap, JZ4760_CODEC_REG_CR1, REG_CR1_HP_LOAD);
|
||||
|
||||
/* default to NOMAD */
|
||||
regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR2,
|
||||
REG_CR2_DAC_NOMAD);
|
||||
|
||||
/* disable automatic gain */
|
||||
regmap_clear_bits(regmap, JZ4760_CODEC_REG_AGC1, REG_AGC1_EN);
|
||||
|
||||
/* Independent L/R DAC gain control */
|
||||
regmap_clear_bits(regmap, JZ4760_CODEC_REG_GCR5,
|
||||
REG_GCR_RL);
|
||||
|
||||
/* Send collected updates. */
|
||||
regcache_cache_only(regmap, false);
|
||||
regcache_sync(regmap);
|
||||
}
|
||||
|
||||
static int jz4760_codec_codec_probe(struct snd_soc_component *codec)
|
||||
{
|
||||
struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
|
||||
|
||||
clk_prepare_enable(jz_codec->clk);
|
||||
|
||||
jz4760_codec_codec_init_regs(codec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void jz4760_codec_codec_remove(struct snd_soc_component *codec)
|
||||
{
|
||||
struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec);
|
||||
|
||||
clk_disable_unprepare(jz_codec->clk);
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver jz4760_codec_soc_codec_dev = {
|
||||
.probe = jz4760_codec_codec_probe,
|
||||
.remove = jz4760_codec_codec_remove,
|
||||
.set_bias_level = jz4760_codec_set_bias_level,
|
||||
.controls = jz4760_codec_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(jz4760_codec_snd_controls),
|
||||
.dapm_widgets = jz4760_codec_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(jz4760_codec_dapm_widgets),
|
||||
.dapm_routes = jz4760_codec_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(jz4760_codec_dapm_routes),
|
||||
.suspend_bias_off = 1,
|
||||
.use_pmdown_time = 1,
|
||||
};
|
||||
|
||||
static const unsigned int jz4760_codec_sample_rates[] = {
|
||||
96000, 48000, 44100, 32000,
|
||||
24000, 22050, 16000, 12000,
|
||||
11025, 9600, 8000,
|
||||
};
|
||||
|
||||
static int jz4760_codec_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component);
|
||||
unsigned int rate, bit_width;
|
||||
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
bit_width = 0;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S18_3LE:
|
||||
bit_width = 1;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S20_3LE:
|
||||
bit_width = 2;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_3LE:
|
||||
bit_width = 3;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (rate = 0; rate < ARRAY_SIZE(jz4760_codec_sample_rates); rate++) {
|
||||
if (jz4760_codec_sample_rates[rate] == params_rate(params))
|
||||
break;
|
||||
}
|
||||
|
||||
if (rate == ARRAY_SIZE(jz4760_codec_sample_rates))
|
||||
return -EINVAL;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR,
|
||||
REG_AICR_DAC_ADWL_MASK,
|
||||
FIELD_PREP(REG_AICR_DAC_ADWL_MASK, bit_width));
|
||||
regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2,
|
||||
REG_CCR2_DAC_FREQ_MASK,
|
||||
FIELD_PREP(REG_CCR2_DAC_FREQ_MASK, rate));
|
||||
} else {
|
||||
regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR,
|
||||
REG_AICR_ADC_ADWL_MASK,
|
||||
FIELD_PREP(REG_AICR_ADC_ADWL_MASK, bit_width));
|
||||
regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2,
|
||||
REG_CCR2_ADC_FREQ_MASK,
|
||||
FIELD_PREP(REG_CCR2_ADC_FREQ_MASK, rate));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops jz4760_codec_dai_ops = {
|
||||
.startup = jz4760_codec_startup,
|
||||
.shutdown = jz4760_codec_shutdown,
|
||||
.hw_params = jz4760_codec_hw_params,
|
||||
.trigger = jz4760_codec_pcm_trigger,
|
||||
.mute_stream = jz4760_codec_mute_stream,
|
||||
.no_capture_mute = 1,
|
||||
};
|
||||
|
||||
#define JZ_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
SNDRV_PCM_FMTBIT_S18_3LE | \
|
||||
SNDRV_PCM_FMTBIT_S20_3LE | \
|
||||
SNDRV_PCM_FMTBIT_S24_3LE)
|
||||
|
||||
static struct snd_soc_dai_driver jz4760_codec_dai = {
|
||||
.name = "jz4760-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000_96000,
|
||||
.formats = JZ_CODEC_FORMATS,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "Capture",
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000_96000,
|
||||
.formats = JZ_CODEC_FORMATS,
|
||||
},
|
||||
.ops = &jz4760_codec_dai_ops,
|
||||
};
|
||||
|
||||
static bool jz4760_codec_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
return reg == JZ4760_CODEC_REG_SR || reg == JZ4760_CODEC_REG_IFR;
|
||||
}
|
||||
|
||||
static bool jz4760_codec_writeable(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case JZ4760_CODEC_REG_SR:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static int jz4760_codec_io_wait(struct jz_codec *codec)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg,
|
||||
!(reg & ICDC_RGADW_RGWR),
|
||||
1000, 1 * USEC_PER_SEC);
|
||||
}
|
||||
|
||||
static int jz4760_codec_reg_read(void *context, unsigned int reg,
|
||||
unsigned int *val)
|
||||
{
|
||||
struct jz_codec *codec = context;
|
||||
unsigned int i;
|
||||
u32 tmp;
|
||||
int ret;
|
||||
|
||||
ret = jz4760_codec_io_wait(codec);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tmp = readl(codec->base + ICDC_RGADW_OFFSET);
|
||||
tmp &= ~ICDC_RGADW_RGADDR_MASK;
|
||||
tmp |= FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg);
|
||||
writel(tmp, codec->base + ICDC_RGADW_OFFSET);
|
||||
|
||||
/* wait 6+ cycles */
|
||||
for (i = 0; i < 6; i++)
|
||||
*val = readl(codec->base + ICDC_RGDATA_OFFSET) &
|
||||
ICDC_RGDATA_RGDOUT_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jz4760_codec_reg_write(void *context, unsigned int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
struct jz_codec *codec = context;
|
||||
int ret;
|
||||
|
||||
ret = jz4760_codec_io_wait(codec);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
writel(ICDC_RGADW_RGWR | FIELD_PREP(ICDC_RGADW_RGADDR_MASK, reg) | val,
|
||||
codec->base + ICDC_RGADW_OFFSET);
|
||||
|
||||
ret = jz4760_codec_io_wait(codec);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const u8 jz4760_codec_reg_defaults[] = {
|
||||
0x00, 0xFC, 0x1B, 0x20, 0x00, 0x80, 0x00, 0x00,
|
||||
0xFF, 0x1F, 0x3F, 0x00, 0x06, 0x06, 0x06, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x07, 0x44,
|
||||
0x1F, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static struct regmap_config jz4760_codec_regmap_config = {
|
||||
.reg_bits = 7,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = JZ4760_CODEC_REG_MIX2,
|
||||
.volatile_reg = jz4760_codec_volatile,
|
||||
.writeable_reg = jz4760_codec_writeable,
|
||||
|
||||
.reg_read = jz4760_codec_reg_read,
|
||||
.reg_write = jz4760_codec_reg_write,
|
||||
|
||||
.reg_defaults_raw = jz4760_codec_reg_defaults,
|
||||
.num_reg_defaults_raw = ARRAY_SIZE(jz4760_codec_reg_defaults),
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static int jz4760_codec_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct jz_codec *codec;
|
||||
int ret;
|
||||
|
||||
codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL);
|
||||
if (!codec)
|
||||
return -ENOMEM;
|
||||
|
||||
codec->dev = dev;
|
||||
|
||||
codec->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(codec->base)) {
|
||||
ret = PTR_ERR(codec->base);
|
||||
dev_err(dev, "Failed to ioremap mmio memory: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
codec->regmap = devm_regmap_init(dev, NULL, codec,
|
||||
&jz4760_codec_regmap_config);
|
||||
if (IS_ERR(codec->regmap))
|
||||
return PTR_ERR(codec->regmap);
|
||||
|
||||
codec->clk = devm_clk_get(dev, "aic");
|
||||
if (IS_ERR(codec->clk))
|
||||
return PTR_ERR(codec->clk);
|
||||
|
||||
platform_set_drvdata(pdev, codec);
|
||||
|
||||
ret = devm_snd_soc_register_component(dev, &jz4760_codec_soc_codec_dev,
|
||||
&jz4760_codec_dai, 1);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to register codec: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id jz4760_codec_of_matches[] = {
|
||||
{ .compatible = "ingenic,jz4760-codec", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, jz4760_codec_of_matches);
|
||||
|
||||
static struct platform_driver jz4760_codec_driver = {
|
||||
.probe = jz4760_codec_probe,
|
||||
.driver = {
|
||||
.name = "jz4760-codec",
|
||||
.of_match_table = jz4760_codec_of_matches,
|
||||
},
|
||||
};
|
||||
module_platform_driver(jz4760_codec_driver);
|
||||
|
||||
MODULE_DESCRIPTION("JZ4760 SoC internal codec driver");
|
||||
MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>");
|
||||
MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -1343,7 +1343,7 @@ static struct snd_soc_dai_driver lm49453_dai[] = {
|
||||
.formats = LM49453_FORMATS,
|
||||
},
|
||||
.ops = &lm49453_headset_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
},
|
||||
{
|
||||
.name = "LM49453 Speaker",
|
||||
|
@ -166,8 +166,8 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = {
|
||||
.formats = SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.ops = &lochnagar_sc_line_ops,
|
||||
.symmetric_rates = true,
|
||||
.symmetric_samplebits = true,
|
||||
.symmetric_rate = true,
|
||||
.symmetric_sample_bits = true,
|
||||
},
|
||||
{
|
||||
.name = "lochnagar-usb1",
|
||||
@ -186,8 +186,8 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = {
|
||||
.formats = SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.ops = &lochnagar_sc_usb_ops,
|
||||
.symmetric_rates = true,
|
||||
.symmetric_samplebits = true,
|
||||
.symmetric_rate = true,
|
||||
.symmetric_sample_bits = true,
|
||||
},
|
||||
{
|
||||
.name = "lochnagar-usb2",
|
||||
@ -206,8 +206,8 @@ static struct snd_soc_dai_driver lochnagar_sc_dai[] = {
|
||||
.formats = SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.ops = &lochnagar_sc_usb_ops,
|
||||
.symmetric_rates = true,
|
||||
.symmetric_samplebits = true,
|
||||
.symmetric_rate = true,
|
||||
.symmetric_sample_bits = true,
|
||||
},
|
||||
};
|
||||
|
||||
|
3599
sound/soc/codecs/lpass-rx-macro.c
Normal file
3599
sound/soc/codecs/lpass-rx-macro.c
Normal file
File diff suppressed because it is too large
Load Diff
1862
sound/soc/codecs/lpass-tx-macro.c
Normal file
1862
sound/soc/codecs/lpass-tx-macro.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -40,9 +40,11 @@
|
||||
#define CDC_WSA_TOP_I2S_CLK (0x00A4)
|
||||
#define CDC_WSA_TOP_I2S_RESET (0x00A8)
|
||||
#define CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 (0x0100)
|
||||
#define CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK GENMASK(5, 3)
|
||||
#define CDC_WSA_RX_INTX_2_SEL_MASK GENMASK(2, 0)
|
||||
#define CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK GENMASK(2, 0)
|
||||
#define CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK GENMASK(5, 3)
|
||||
#define CDC_WSA_RX_INP_MUX_RX_INT0_CFG1 (0x0104)
|
||||
#define CDC_WSA_RX_INTX_2_SEL_MASK GENMASK(2, 0)
|
||||
#define CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK GENMASK(5, 3)
|
||||
#define CDC_WSA_RX_INP_MUX_RX_INT1_CFG0 (0x0108)
|
||||
#define CDC_WSA_RX_INP_MUX_RX_INT1_CFG1 (0x010C)
|
||||
#define CDC_WSA_RX_INP_MUX_RX_MIX_CFG0 (0x0110)
|
||||
@ -229,8 +231,6 @@
|
||||
#define NUM_INTERPOLATORS 2
|
||||
#define WSA_NUM_CLKS_MAX 5
|
||||
#define WSA_MACRO_MCLK_FREQ 19200000
|
||||
#define WSA_MACRO_MUX_INP_SHFT 0x3
|
||||
#define WSA_MACRO_MUX_INP_MASK1 0x07
|
||||
#define WSA_MACRO_MUX_INP_MASK2 0x38
|
||||
#define WSA_MACRO_MUX_CFG_OFFSET 0x8
|
||||
#define WSA_MACRO_MUX_CFG1_OFFSET 0x4
|
||||
@ -843,7 +843,6 @@ static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
|
||||
u32 j, port;
|
||||
u16 int_mux_cfg0, int_mux_cfg1;
|
||||
u16 int_fs_reg;
|
||||
u8 int_mux_cfg0_val, int_mux_cfg1_val;
|
||||
u8 inp0_sel, inp1_sel, inp2_sel;
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct wsa_macro *wsa = snd_soc_component_get_drvdata(component);
|
||||
@ -865,15 +864,13 @@ static int wsa_macro_set_prim_interpolator_rate(struct snd_soc_dai *dai,
|
||||
*/
|
||||
for (j = 0; j < NUM_INTERPOLATORS; j++) {
|
||||
int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET;
|
||||
int_mux_cfg0_val = snd_soc_component_read(component,
|
||||
int_mux_cfg0);
|
||||
int_mux_cfg1_val = snd_soc_component_read(component,
|
||||
int_mux_cfg1);
|
||||
inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1;
|
||||
inp1_sel = (int_mux_cfg0_val >> WSA_MACRO_MUX_INP_SHFT) &
|
||||
WSA_MACRO_MUX_INP_MASK1;
|
||||
inp2_sel = (int_mux_cfg1_val >> WSA_MACRO_MUX_INP_SHFT) &
|
||||
WSA_MACRO_MUX_INP_MASK1;
|
||||
inp0_sel = snd_soc_component_read_field(component, int_mux_cfg0,
|
||||
CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK);
|
||||
inp1_sel = snd_soc_component_read_field(component, int_mux_cfg0,
|
||||
CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK);
|
||||
inp2_sel = snd_soc_component_read_field(component, int_mux_cfg1,
|
||||
CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK);
|
||||
|
||||
if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
|
||||
(inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
|
||||
(inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) {
|
||||
@ -912,9 +909,9 @@ static int wsa_macro_set_mix_interpolator_rate(struct snd_soc_dai *dai,
|
||||
|
||||
int_mux_cfg1 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG1;
|
||||
for (j = 0; j < NUM_INTERPOLATORS; j++) {
|
||||
int_mux_cfg1_val = snd_soc_component_read(component,
|
||||
int_mux_cfg1) &
|
||||
WSA_MACRO_MUX_INP_MASK1;
|
||||
int_mux_cfg1_val = snd_soc_component_read_field(component, int_mux_cfg1,
|
||||
CDC_WSA_RX_INTX_2_SEL_MASK);
|
||||
|
||||
if (int_mux_cfg1_val == int_2_inp + INTn_2_INP_SEL_RX0) {
|
||||
int_fs_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL +
|
||||
WSA_MACRO_RX_PATH_OFFSET * j;
|
||||
@ -1410,25 +1407,25 @@ static bool wsa_macro_adie_lb(struct snd_soc_component *component,
|
||||
int interp_idx)
|
||||
{
|
||||
u16 int_mux_cfg0, int_mux_cfg1;
|
||||
u8 int_mux_cfg0_val, int_mux_cfg1_val;
|
||||
u8 int_n_inp0, int_n_inp1, int_n_inp2;
|
||||
|
||||
int_mux_cfg0 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 + interp_idx * 8;
|
||||
int_mux_cfg1 = int_mux_cfg0 + 4;
|
||||
int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0);
|
||||
int_mux_cfg1_val = snd_soc_component_read(component, int_mux_cfg1);
|
||||
|
||||
int_n_inp0 = int_mux_cfg0_val & 0x0F;
|
||||
int_n_inp0 = snd_soc_component_read_field(component, int_mux_cfg0,
|
||||
CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK);
|
||||
if (int_n_inp0 == INTn_1_INP_SEL_DEC0 ||
|
||||
int_n_inp0 == INTn_1_INP_SEL_DEC1)
|
||||
return true;
|
||||
|
||||
int_n_inp1 = int_mux_cfg0_val >> 4;
|
||||
int_n_inp1 = snd_soc_component_read_field(component, int_mux_cfg0,
|
||||
CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK);
|
||||
if (int_n_inp1 == INTn_1_INP_SEL_DEC0 ||
|
||||
int_n_inp1 == INTn_1_INP_SEL_DEC1)
|
||||
return true;
|
||||
|
||||
int_n_inp2 = int_mux_cfg1_val >> 4;
|
||||
int_n_inp2 = snd_soc_component_read_field(component, int_mux_cfg1,
|
||||
CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK);
|
||||
if (int_n_inp2 == INTn_1_INP_SEL_DEC0 ||
|
||||
int_n_inp2 == INTn_1_INP_SEL_DEC1)
|
||||
return true;
|
||||
|
@ -262,6 +262,8 @@ static __maybe_unused int max98373_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX98373_PROBE_TIMEOUT 5000
|
||||
|
||||
static __maybe_unused int max98373_resume(struct device *dev)
|
||||
{
|
||||
struct sdw_slave *slave = dev_to_sdw_dev(dev);
|
||||
@ -275,7 +277,7 @@ static __maybe_unused int max98373_resume(struct device *dev)
|
||||
goto regmap_sync;
|
||||
|
||||
time = wait_for_completion_timeout(&slave->initialization_complete,
|
||||
msecs_to_jiffies(2000));
|
||||
msecs_to_jiffies(MAX98373_PROBE_TIMEOUT));
|
||||
if (!time) {
|
||||
dev_err(dev, "Initialization not complete, timed out\n");
|
||||
return -ETIMEDOUT;
|
||||
|
@ -489,7 +489,7 @@ static struct snd_soc_dai_driver max9860_dai = {
|
||||
SNDRV_PCM_FMTBIT_S32_LE,
|
||||
},
|
||||
.ops = &max9860_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
static int max9860_set_bias_level(struct snd_soc_component *component,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user