mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 12:44:11 +08:00
ASoC: Updates for v6.3
There's been quite a lot of activity this release, but not really one big feature - lots of new devices, plus a lot of cleanup and modernisation work spread throughout the subsystem: - More factoring out of common operations into helper functions by Morimoto-san. - DT schema conversons and stylistic nits. - Continued work on building out the new SOF IPC4 scheme. - Support for Awinc AT88395, Infineon PEB2466, Iron Device SMA1303, Mediatek MT8188, Realtek RT712, Renesas IDT821034, Samsung/Tesla FSD SoC I2S, and TI TAS5720A-Q1. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmPuKzoACgkQJNaLcl1U h9AO6wf/Us32gNLnLhT+YaPKouVq4KYpEXDeaIOdOCgs8RtonuCgURZ/D2TkzBVL EHLPp4QgqdIWo3FKkWgsXIOpO7R0//cj/vpccJ0PBe4VmvDinXq3dzGPPy6ZbHAS SatE5zItBKRUHaDliRk6S7IFEqJKwwlBqEzV0K41Q4EstYlIe+No0XIVDj3oRjHb jPmAD9XRPqsDaFFFb0NrVl9M/8HwBlc3j/Gnt19eJB/07IdgIr0S8mJn3qlFfGqu O8KgBo4+tvVMCQAxTVZ5exb/qTtK3gEPDuMi0eOKJz+g9wMJ4tRz+D8/8TQSmxmW lWORmNTx8jml7G4KirxIV4q4Lr0hRQ== =mB3t -----END PGP SIGNATURE----- Merge tag 'asoc-v6.3' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next ASoC: Updates for v6.3 There's been quite a lot of activity this release, but not really one big feature - lots of new devices, plus a lot of cleanup and modernisation work spread throughout the subsystem: - More factoring out of common operations into helper functions by Morimoto-san. - DT schema conversons and stylistic nits. - Continued work on building out the new SOF IPC4 scheme. - Support for Awinc AT88395, Infineon PEB2466, Iron Device SMA1303, Mediatek MT8188, Realtek RT712, Renesas IDT821034, Samsung/Tesla FSD SoC I2S, and TI TAS5720A-Q1.
This commit is contained in:
commit
1bdb78368f
@ -15,7 +15,9 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8186-dsp
|
||||
enum:
|
||||
- mediatek,mt8186-dsp
|
||||
- mediatek,mt8188-dsp
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
@ -1,19 +0,0 @@
|
||||
Analog Devices ADAU7002 Stereo PDM-to-I2S/TDM Converter
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: Must be "adi,adau7002"
|
||||
|
||||
Optional properties:
|
||||
|
||||
- IOVDD-supply: Phandle and specifier for the power supply providing the IOVDD
|
||||
supply as covered in Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
|
||||
If this property is not present it is assumed that the supply pin is
|
||||
hardwired to always on.
|
||||
|
||||
Example:
|
||||
adau7002: pdm-to-i2s {
|
||||
compatible = "adi,adau7002";
|
||||
IOVDD-supply = <&supply>;
|
||||
};
|
40
Documentation/devicetree/bindings/sound/adi,adau7002.yaml
Normal file
40
Documentation/devicetree/bindings/sound/adi,adau7002.yaml
Normal file
@ -0,0 +1,40 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/adi,adau7002.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices ADAU7002 Stereo PDM-to-I2S/TDM Converter
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: adi,adau7002
|
||||
|
||||
IOVDD-supply:
|
||||
description:
|
||||
IOVDD power supply, if skipped then it is assumed that the supply pin is
|
||||
hardwired to always on.
|
||||
|
||||
wakeup-delay-ms:
|
||||
description:
|
||||
Delay after power up needed for device to settle.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
audio-codec {
|
||||
compatible = "adi,adau7002";
|
||||
IOVDD-supply = <&pp1800_l15a>;
|
||||
#sound-dai-cells = <0>;
|
||||
wakeup-delay-ms = <80>;
|
||||
};
|
@ -25,6 +25,13 @@ properties:
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
ports:
|
||||
$ref: audio-graph-port.yaml#/definitions/ports
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
patternProperties:
|
||||
"^asahi-kasei,in[1-2]-single-end$":
|
||||
description: Input Pin 1 - 2.
|
||||
|
@ -1,34 +0,0 @@
|
||||
* Amlogic Audio FIFO controllers
|
||||
|
||||
Required properties:
|
||||
- compatible: 'amlogic,axg-toddr' or
|
||||
'amlogic,axg-toddr' or
|
||||
'amlogic,g12a-frddr' or
|
||||
'amlogic,g12a-toddr' or
|
||||
'amlogic,sm1-frddr' or
|
||||
'amlogic,sm1-toddr'
|
||||
- reg: physical base address of the controller and length of memory
|
||||
mapped region.
|
||||
- interrupts: interrupt specifier for the fifo.
|
||||
- clocks: phandle to the fifo peripheral clock provided by the audio
|
||||
clock controller.
|
||||
- resets: list of reset phandle, one for each entry reset-names.
|
||||
- reset-names: should contain the following:
|
||||
* "arb" : memory ARB line (required)
|
||||
* "rst" : dedicated device reset line (optional)
|
||||
- #sound-dai-cells: must be 0.
|
||||
- amlogic,fifo-depth: The size of the controller's fifo in bytes. This
|
||||
is useful for determining certain configuration such
|
||||
as the flush threshold of the fifo
|
||||
|
||||
Example of FRDDR A on the A113 SoC:
|
||||
|
||||
frddr_a: audio-controller@1c0 {
|
||||
compatible = "amlogic,axg-frddr";
|
||||
reg = <0x0 0x1c0 0x0 0x1c>;
|
||||
#sound-dai-cells = <0>;
|
||||
interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
|
||||
clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
|
||||
resets = <&arb AXG_ARB_FRDDR_A>;
|
||||
fifo-depth = <512>;
|
||||
};
|
112
Documentation/devicetree/bindings/sound/amlogic,axg-fifo.yaml
Normal file
112
Documentation/devicetree/bindings/sound/amlogic,axg-fifo.yaml
Normal file
@ -0,0 +1,112 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/amlogic,axg-fifo.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic AXG Audio FIFO controllers
|
||||
|
||||
maintainers:
|
||||
- Jerome Brunet <jbrunet@baylibre.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- amlogic,axg-toddr
|
||||
- amlogic,axg-frddr
|
||||
- items:
|
||||
- enum:
|
||||
- amlogic,g12a-toddr
|
||||
- amlogic,sm1-toddr
|
||||
- const: amlogic,axg-toddr
|
||||
- items:
|
||||
- enum:
|
||||
- amlogic,g12a-frddr
|
||||
- amlogic,sm1-frddr
|
||||
- const: amlogic,axg-frddr
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Peripheral clock
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
reset-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
amlogic,fifo-depth:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Size of the controller's fifo in bytes
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
- clocks
|
||||
- interrupts
|
||||
- resets
|
||||
- amlogic,fifo-depth
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- amlogic,g12a-toddr
|
||||
- amlogic,sm1-toddr
|
||||
- amlogic,g12a-frddr
|
||||
- amlogic,sm1-frddr
|
||||
|
||||
then:
|
||||
properties:
|
||||
resets:
|
||||
minItems: 2
|
||||
reset-names:
|
||||
items:
|
||||
- const: arb
|
||||
- const: rst
|
||||
required:
|
||||
- reset-names
|
||||
|
||||
else:
|
||||
properties:
|
||||
resets:
|
||||
maxItems: 1
|
||||
reset-names:
|
||||
const: arb
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/axg-audio-clkc.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h>
|
||||
#include <dt-bindings/reset/amlogic,meson-g12a-audio-reset.h>
|
||||
|
||||
audio-controller@1c0 {
|
||||
compatible = "amlogic,g12a-frddr", "amlogic,axg-frddr";
|
||||
reg = <0x1c0 0x1c>;
|
||||
#sound-dai-cells = <0>;
|
||||
clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
|
||||
interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
|
||||
resets = <&arb>, <&clkc_audio AUD_RESET_FRDDR_A>;
|
||||
reset-names = "arb", "rst";
|
||||
amlogic,fifo-depth = <512>;
|
||||
};
|
@ -1,29 +0,0 @@
|
||||
* Amlogic Audio PDM input
|
||||
|
||||
Required properties:
|
||||
- compatible: 'amlogic,axg-pdm' or
|
||||
'amlogic,g12a-pdm' or
|
||||
'amlogic,sm1-pdm'
|
||||
- reg: physical base address of the controller and length of memory
|
||||
mapped region.
|
||||
- clocks: list of clock phandle, one for each entry clock-names.
|
||||
- clock-names: should contain the following:
|
||||
* "pclk" : peripheral clock.
|
||||
* "dclk" : pdm digital clock
|
||||
* "sysclk" : dsp system clock
|
||||
- #sound-dai-cells: must be 0.
|
||||
|
||||
Optional property:
|
||||
- resets: phandle to the dedicated reset line of the pdm input.
|
||||
|
||||
Example of PDM on the A113 SoC:
|
||||
|
||||
pdm: audio-controller@ff632000 {
|
||||
compatible = "amlogic,axg-pdm";
|
||||
reg = <0x0 0xff632000 0x0 0x34>;
|
||||
#sound-dai-cells = <0>;
|
||||
clocks = <&clkc_audio AUD_CLKID_PDM>,
|
||||
<&clkc_audio AUD_CLKID_PDM_DCLK>,
|
||||
<&clkc_audio AUD_CLKID_PDM_SYSCLK>;
|
||||
clock-names = "pclk", "dclk", "sysclk";
|
||||
};
|
82
Documentation/devicetree/bindings/sound/amlogic,axg-pdm.yaml
Normal file
82
Documentation/devicetree/bindings/sound/amlogic,axg-pdm.yaml
Normal file
@ -0,0 +1,82 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/amlogic,axg-pdm.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic Audio AXG PDM input
|
||||
|
||||
maintainers:
|
||||
- Jerome Brunet <jbrunet@baylibre.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- amlogic,g12a-pdm
|
||||
- amlogic,sm1-pdm
|
||||
- const: amlogic,axg-pdm
|
||||
- const: amlogic,axg-pdm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Peripheral clock
|
||||
- description: PDM digital clock
|
||||
- description: DSP system clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk
|
||||
- const: dclk
|
||||
- const: sysclk
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- amlogic,g12a-pdm
|
||||
- amlogic,sm1-pdm
|
||||
then:
|
||||
required:
|
||||
- resets
|
||||
|
||||
else:
|
||||
properties:
|
||||
resets: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/axg-audio-clkc.h>
|
||||
|
||||
audio-controller@ff632000 {
|
||||
compatible = "amlogic,axg-pdm";
|
||||
reg = <0xff632000 0x34>;
|
||||
#sound-dai-cells = <0>;
|
||||
clocks = <&clkc_audio AUD_CLKID_PDM>,
|
||||
<&clkc_audio AUD_CLKID_PDM_DCLK>,
|
||||
<&clkc_audio AUD_CLKID_PDM_SYSCLK>;
|
||||
clock-names = "pclk", "dclk", "sysclk";
|
||||
};
|
@ -1,124 +0,0 @@
|
||||
Amlogic AXG sound card:
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: "amlogic,axg-sound-card"
|
||||
- model : User specified audio sound card name, one string
|
||||
|
||||
Optional properties:
|
||||
|
||||
- audio-aux-devs : List of phandles pointing to auxiliary devices
|
||||
- audio-widgets : Please refer to widgets.txt.
|
||||
- audio-routing : A list of the connections between audio components.
|
||||
|
||||
Subnodes:
|
||||
|
||||
- dai-link: Container for dai-link level properties and the CODEC
|
||||
sub-nodes. There should be at least one (and probably more)
|
||||
subnode of this type.
|
||||
|
||||
Required dai-link properties:
|
||||
|
||||
- sound-dai: phandle and port of the CPU DAI.
|
||||
|
||||
Required TDM Backend dai-link properties:
|
||||
- dai-format : CPU/CODEC common audio format
|
||||
|
||||
Optional TDM Backend dai-link properties:
|
||||
- dai-tdm-slot-rx-mask-{0,1,2,3}: Receive direction slot masks
|
||||
- dai-tdm-slot-tx-mask-{0,1,2,3}: Transmit direction slot masks
|
||||
When omitted, mask is assumed to have to no
|
||||
slots. A valid must have at one slot, so at
|
||||
least one these mask should be provided with
|
||||
an enabled slot.
|
||||
- dai-tdm-slot-num : Please refer to tdm-slot.txt.
|
||||
If omitted, slot number is set to accommodate the largest
|
||||
mask provided.
|
||||
- dai-tdm-slot-width : Please refer to tdm-slot.txt. default to 32 if omitted.
|
||||
- mclk-fs : Multiplication factor between stream rate and mclk
|
||||
|
||||
Backend dai-link subnodes:
|
||||
|
||||
- codec: dai-link representing backend links should have at least one subnode.
|
||||
One subnode for each codec of the dai-link.
|
||||
dai-link representing frontend links have no codec, therefore have no
|
||||
subnodes
|
||||
|
||||
Required codec subnodes properties:
|
||||
|
||||
- sound-dai: phandle and port of the CODEC DAI.
|
||||
|
||||
Optional codec subnodes properties:
|
||||
|
||||
- dai-tdm-slot-tx-mask : Please refer to tdm-slot.txt.
|
||||
- dai-tdm-slot-rx-mask : Please refer to tdm-slot.txt.
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "amlogic,axg-sound-card";
|
||||
model = "AXG-S420";
|
||||
audio-aux-devs = <&tdmin_a>, <&tdmout_c>;
|
||||
audio-widgets = "Line", "Lineout",
|
||||
"Line", "Linein",
|
||||
"Speaker", "Speaker1 Left",
|
||||
"Speaker", "Speaker1 Right";
|
||||
"Speaker", "Speaker2 Left",
|
||||
"Speaker", "Speaker2 Right";
|
||||
audio-routing = "TDMOUT_C IN 0", "FRDDR_A OUT 2",
|
||||
"SPDIFOUT IN 0", "FRDDR_A OUT 3",
|
||||
"TDM_C Playback", "TDMOUT_C OUT",
|
||||
"TDMIN_A IN 2", "TDM_C Capture",
|
||||
"TDMIN_A IN 5", "TDM_C Loopback",
|
||||
"TODDR_A IN 0", "TDMIN_A OUT",
|
||||
"Lineout", "Lineout AOUTL",
|
||||
"Lineout", "Lineout AOUTR",
|
||||
"Speaker1 Left", "SPK1 OUT_A",
|
||||
"Speaker2 Left", "SPK2 OUT_A",
|
||||
"Speaker1 Right", "SPK1 OUT_B",
|
||||
"Speaker2 Right", "SPK2 OUT_B",
|
||||
"Linein AINL", "Linein",
|
||||
"Linein AINR", "Linein";
|
||||
|
||||
dai-link@0 {
|
||||
sound-dai = <&frddr_a>;
|
||||
};
|
||||
|
||||
dai-link@1 {
|
||||
sound-dai = <&toddr_a>;
|
||||
};
|
||||
|
||||
dai-link@2 {
|
||||
sound-dai = <&tdmif_c>;
|
||||
dai-format = "i2s";
|
||||
dai-tdm-slot-tx-mask-2 = <1 1>;
|
||||
dai-tdm-slot-tx-mask-3 = <1 1>;
|
||||
dai-tdm-slot-rx-mask-1 = <1 1>;
|
||||
mclk-fs = <256>;
|
||||
|
||||
codec@0 {
|
||||
sound-dai = <&lineout>;
|
||||
};
|
||||
|
||||
codec@1 {
|
||||
sound-dai = <&speaker_amp1>;
|
||||
};
|
||||
|
||||
codec@2 {
|
||||
sound-dai = <&speaker_amp2>;
|
||||
};
|
||||
|
||||
codec@3 {
|
||||
sound-dai = <&linein>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
dai-link@3 {
|
||||
sound-dai = <&spdifout>;
|
||||
|
||||
codec {
|
||||
sound-dai = <&spdif_dit>;
|
||||
};
|
||||
};
|
||||
};
|
@ -0,0 +1,183 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/amlogic,axg-sound-card.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic AXG sound card
|
||||
|
||||
maintainers:
|
||||
- Jerome Brunet <jbrunet@baylibre.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: amlogic,axg-sound-card
|
||||
|
||||
audio-aux-devs:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: list of auxiliary devices
|
||||
|
||||
audio-routing:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
description:
|
||||
A list of the connections between audio components. Each entry is a
|
||||
pair of strings, the first being the connection's sink, the second
|
||||
being the connection's source.
|
||||
|
||||
audio-widgets:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
description:
|
||||
A list off component DAPM widget. Each entry is a pair of strings,
|
||||
the first being the widget type, the second being the widget name
|
||||
|
||||
model:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: User specified audio sound card name
|
||||
|
||||
patternProperties:
|
||||
"^dai-link-[0-9]+$":
|
||||
type: object
|
||||
additionalProperties: false
|
||||
description:
|
||||
Container for dai-link level properties and the CODEC sub-nodes.
|
||||
There should be at least one (and probably more) subnode of this type
|
||||
|
||||
properties:
|
||||
dai-format:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum: [ i2s, left-j, dsp_a ]
|
||||
|
||||
dai-tdm-slot-num:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Number of slots in use. If omitted, slot number is set to
|
||||
accommodate the largest mask provided.
|
||||
maximum: 32
|
||||
|
||||
dai-tdm-slot-width:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Width in bits for each slot
|
||||
enum: [ 8, 16, 20, 24, 32 ]
|
||||
default: 32
|
||||
|
||||
mclk-fs:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Multiplication factor between the frame rate and master clock
|
||||
rate
|
||||
|
||||
sound-dai:
|
||||
maxItems: 1
|
||||
description: phandle of the CPU DAI
|
||||
|
||||
patternProperties:
|
||||
"^dai-tdm-slot-(t|r)x-mask-[0-3]$":
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 32
|
||||
description:
|
||||
Transmit and receive cpu slot masks of each TDM lane
|
||||
When omitted, mask is assumed to have to no slots. A valid
|
||||
interface must have at least one slot, so at least one these
|
||||
mask should be provided with an enabled slot.
|
||||
|
||||
"^codec(-[0-9]+)?$":
|
||||
type: object
|
||||
additionalProperties: false
|
||||
description:
|
||||
dai-link representing backend links should have at least one subnode.
|
||||
One subnode for each codec of the dai-link. dai-link representing
|
||||
frontend links have no codec, therefore have no subnodes
|
||||
|
||||
properties:
|
||||
sound-dai:
|
||||
maxItems: 1
|
||||
description: phandle of the codec DAI
|
||||
|
||||
patternProperties:
|
||||
"^dai-tdm-slot-(t|r)x-mask$":
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 32
|
||||
description: Transmit and receive codec slot masks
|
||||
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
required:
|
||||
- model
|
||||
- dai-link-0
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sound {
|
||||
compatible = "amlogic,axg-sound-card";
|
||||
model = "AXG-S420";
|
||||
audio-aux-devs = <&tdmin_a>, <&tdmout_c>;
|
||||
audio-widgets = "Line", "Lineout",
|
||||
"Line", "Linein",
|
||||
"Speaker", "Speaker1 Left",
|
||||
"Speaker", "Speaker1 Right",
|
||||
"Speaker", "Speaker2 Left",
|
||||
"Speaker", "Speaker2 Right";
|
||||
audio-routing = "TDMOUT_C IN 0", "FRDDR_A OUT 2",
|
||||
"SPDIFOUT IN 0", "FRDDR_A OUT 3",
|
||||
"TDM_C Playback", "TDMOUT_C OUT",
|
||||
"TDMIN_A IN 2", "TDM_C Capture",
|
||||
"TDMIN_A IN 5", "TDM_C Loopback",
|
||||
"TODDR_A IN 0", "TDMIN_A OUT",
|
||||
"Lineout", "Lineout AOUTL",
|
||||
"Lineout", "Lineout AOUTR",
|
||||
"Speaker1 Left", "SPK1 OUT_A",
|
||||
"Speaker2 Left", "SPK2 OUT_A",
|
||||
"Speaker1 Right", "SPK1 OUT_B",
|
||||
"Speaker2 Right", "SPK2 OUT_B",
|
||||
"Linein AINL", "Linein",
|
||||
"Linein AINR", "Linein";
|
||||
|
||||
dai-link-0 {
|
||||
sound-dai = <&frddr_a>;
|
||||
};
|
||||
|
||||
dai-link-1 {
|
||||
sound-dai = <&toddr_a>;
|
||||
};
|
||||
|
||||
dai-link-2 {
|
||||
sound-dai = <&tdmif_c>;
|
||||
dai-format = "i2s";
|
||||
dai-tdm-slot-tx-mask-2 = <1 1>;
|
||||
dai-tdm-slot-tx-mask-3 = <1 1>;
|
||||
dai-tdm-slot-rx-mask-1 = <1 1>;
|
||||
mclk-fs = <256>;
|
||||
|
||||
codec-0 {
|
||||
sound-dai = <&lineout>;
|
||||
};
|
||||
|
||||
codec-1 {
|
||||
sound-dai = <&speaker_amp1>;
|
||||
};
|
||||
|
||||
codec-2 {
|
||||
sound-dai = <&speaker_amp2>;
|
||||
};
|
||||
|
||||
codec-3 {
|
||||
sound-dai = <&linein>;
|
||||
};
|
||||
};
|
||||
|
||||
dai-link-3 {
|
||||
sound-dai = <&spdifout>;
|
||||
|
||||
codec {
|
||||
sound-dai = <&spdif_dit>;
|
||||
};
|
||||
};
|
||||
};
|
@ -1,27 +0,0 @@
|
||||
* Amlogic Audio SPDIF Input
|
||||
|
||||
Required properties:
|
||||
- compatible: 'amlogic,axg-spdifin' or
|
||||
'amlogic,g12a-spdifin' or
|
||||
'amlogic,sm1-spdifin'
|
||||
- interrupts: interrupt specifier for the spdif input.
|
||||
- clocks: list of clock phandle, one for each entry clock-names.
|
||||
- clock-names: should contain the following:
|
||||
* "pclk" : peripheral clock.
|
||||
* "refclk" : spdif input reference clock
|
||||
- #sound-dai-cells: must be 0.
|
||||
|
||||
Optional property:
|
||||
- resets: phandle to the dedicated reset line of the spdif input.
|
||||
|
||||
Example on the A113 SoC:
|
||||
|
||||
spdifin: audio-controller@400 {
|
||||
compatible = "amlogic,axg-spdifin";
|
||||
reg = <0x0 0x400 0x0 0x30>;
|
||||
#sound-dai-cells = <0>;
|
||||
interrupts = <GIC_SPI 87 IRQ_TYPE_EDGE_RISING>;
|
||||
clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
|
||||
<&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
|
||||
clock-names = "pclk", "refclk";
|
||||
};
|
@ -0,0 +1,86 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/amlogic,axg-spdifin.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic Audio AXG SPDIF Input
|
||||
|
||||
maintainers:
|
||||
- Jerome Brunet <jbrunet@baylibre.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: amlogic,axg-spdifin
|
||||
- items:
|
||||
- enum:
|
||||
- amlogic,g12a-spdifin
|
||||
- amlogic,sm1-spdifin
|
||||
- const: amlogic,axg-spdifin
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Peripheral clock
|
||||
- description: SPDIF input reference clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk
|
||||
- const: refclk
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- amlogic,g12a-spdifin
|
||||
- amlogic,sm1-spdifin
|
||||
then:
|
||||
required:
|
||||
- resets
|
||||
|
||||
else:
|
||||
properties:
|
||||
resets: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/axg-audio-clkc.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
audio-controller@400 {
|
||||
compatible = "amlogic,axg-spdifin";
|
||||
reg = <0x400 0x30>;
|
||||
#sound-dai-cells = <0>;
|
||||
interrupts = <GIC_SPI 87 IRQ_TYPE_EDGE_RISING>;
|
||||
clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
|
||||
<&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
|
||||
clock-names = "pclk", "refclk";
|
||||
};
|
@ -1,25 +0,0 @@
|
||||
* Amlogic Audio SPDIF Output
|
||||
|
||||
Required properties:
|
||||
- compatible: 'amlogic,axg-spdifout' or
|
||||
'amlogic,g12a-spdifout' or
|
||||
'amlogic,sm1-spdifout'
|
||||
- clocks: list of clock phandle, one for each entry clock-names.
|
||||
- clock-names: should contain the following:
|
||||
* "pclk" : peripheral clock.
|
||||
* "mclk" : master clock
|
||||
- #sound-dai-cells: must be 0.
|
||||
|
||||
Optional property:
|
||||
- resets: phandle to the dedicated reset line of the spdif output.
|
||||
|
||||
Example on the A113 SoC:
|
||||
|
||||
spdifout: audio-controller@480 {
|
||||
compatible = "amlogic,axg-spdifout";
|
||||
reg = <0x0 0x480 0x0 0x50>;
|
||||
#sound-dai-cells = <0>;
|
||||
clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
|
||||
<&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
|
||||
clock-names = "pclk", "mclk";
|
||||
};
|
@ -0,0 +1,79 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/amlogic,axg-spdifout.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic Audio AXG SPDIF Output
|
||||
|
||||
maintainers:
|
||||
- Jerome Brunet <jbrunet@baylibre.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: amlogic,axg-spdifout
|
||||
- items:
|
||||
- enum:
|
||||
- amlogic,g12a-spdifout
|
||||
- amlogic,sm1-spdifout
|
||||
- const: amlogic,axg-spdifout
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Peripheral clock
|
||||
- description: SPDIF output master clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk
|
||||
- const: mclk
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- amlogic,g12a-spdifout
|
||||
- amlogic,sm1-spdifout
|
||||
then:
|
||||
required:
|
||||
- resets
|
||||
|
||||
else:
|
||||
properties:
|
||||
resets: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/axg-audio-clkc.h>
|
||||
|
||||
audio-controller@480 {
|
||||
compatible = "amlogic,axg-spdifout";
|
||||
reg = <0x480 0x50>;
|
||||
#sound-dai-cells = <0>;
|
||||
clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
|
||||
<&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
|
||||
clock-names = "pclk", "mclk";
|
||||
};
|
@ -1,36 +0,0 @@
|
||||
* Amlogic Audio TDM formatters
|
||||
|
||||
Required properties:
|
||||
- compatible: 'amlogic,axg-tdmin' or
|
||||
'amlogic,axg-tdmout' or
|
||||
'amlogic,g12a-tdmin' or
|
||||
'amlogic,g12a-tdmout' or
|
||||
'amlogic,sm1-tdmin' or
|
||||
'amlogic,sm1-tdmout
|
||||
- reg: physical base address of the controller and length of memory
|
||||
mapped region.
|
||||
- clocks: list of clock phandle, one for each entry clock-names.
|
||||
- clock-names: should contain the following:
|
||||
* "pclk" : peripheral clock.
|
||||
* "sclk" : bit clock.
|
||||
* "sclk_sel" : bit clock input multiplexer.
|
||||
* "lrclk" : sample clock
|
||||
* "lrclk_sel": sample clock input multiplexer
|
||||
|
||||
Optional property:
|
||||
- resets: phandle to the dedicated reset line of the tdm formatter.
|
||||
|
||||
Example of TDMOUT_A on the S905X2 SoC:
|
||||
|
||||
tdmout_a: audio-controller@500 {
|
||||
compatible = "amlogic,axg-tdmout";
|
||||
reg = <0x0 0x500 0x0 0x40>;
|
||||
resets = <&clkc_audio AUD_RESET_TDMOUT_A>;
|
||||
clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
|
||||
<&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
|
||||
<&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
|
||||
<&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>,
|
||||
<&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>;
|
||||
clock-names = "pclk", "sclk", "sclk_sel",
|
||||
"lrclk", "lrclk_sel";
|
||||
};
|
@ -0,0 +1,88 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/amlogic,axg-tdm-formatters.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic Audio AXG TDM formatters
|
||||
|
||||
maintainers:
|
||||
- Jerome Brunet <jbrunet@baylibre.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,g12a-tdmout
|
||||
- amlogic,sm1-tdmout
|
||||
- amlogic,axg-tdmout
|
||||
- amlogic,g12a-tdmin
|
||||
- amlogic,sm1-tdmin
|
||||
- amlogic,axg-tdmin
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Peripheral clock
|
||||
- description: Bit clock
|
||||
- description: Bit clock input multiplexer
|
||||
- description: Sample clock
|
||||
- description: Sample clock input multiplexer
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pclk
|
||||
- const: sclk
|
||||
- const: sclk_sel
|
||||
- const: lrclk
|
||||
- const: lrclk_sel
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
allOf:
|
||||
- $ref: component-common.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- amlogic,g12a-tdmin
|
||||
- amlogic,sm1-tdmin
|
||||
- amlogic,g12a-tdmout
|
||||
- amlogic,sm1-tdmout
|
||||
then:
|
||||
required:
|
||||
- resets
|
||||
|
||||
else:
|
||||
properties:
|
||||
resets: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/axg-audio-clkc.h>
|
||||
#include <dt-bindings/reset/amlogic,meson-g12a-audio-reset.h>
|
||||
|
||||
audio-controller@500 {
|
||||
compatible = "amlogic,g12a-tdmout";
|
||||
reg = <0x500 0x40>;
|
||||
resets = <&clkc_audio AUD_RESET_TDMOUT_A>;
|
||||
clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
|
||||
<&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
|
||||
<&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
|
||||
<&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>,
|
||||
<&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>;
|
||||
clock-names = "pclk", "sclk", "sclk_sel",
|
||||
"lrclk", "lrclk_sel";
|
||||
};
|
@ -1,22 +0,0 @@
|
||||
* Amlogic Audio TDM Interfaces
|
||||
|
||||
Required properties:
|
||||
- compatible: 'amlogic,axg-tdm-iface'
|
||||
- clocks: list of clock phandle, one for each entry clock-names.
|
||||
- clock-names: should contain the following:
|
||||
* "sclk" : bit clock.
|
||||
* "lrclk": sample clock
|
||||
* "mclk" : master clock
|
||||
-> optional if the interface is in clock slave mode.
|
||||
- #sound-dai-cells: must be 0.
|
||||
|
||||
Example of TDM_A on the A113 SoC:
|
||||
|
||||
tdmif_a: audio-controller@0 {
|
||||
compatible = "amlogic,axg-tdm-iface";
|
||||
#sound-dai-cells = <0>;
|
||||
clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
|
||||
<&clkc_audio AUD_CLKID_MST_A_SCLK>,
|
||||
<&clkc_audio AUD_CLKID_MST_A_LRCLK>;
|
||||
clock-names = "mclk", "sclk", "lrclk";
|
||||
};
|
@ -0,0 +1,55 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/amlogic,axg-tdm-iface.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic Audio TDM Interfaces
|
||||
|
||||
maintainers:
|
||||
- Jerome Brunet <jbrunet@baylibre.com>
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: amlogic,axg-tdm-iface
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
items:
|
||||
- description: Bit clock
|
||||
- description: Sample clock
|
||||
- description: Master clock #optional
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: sclk
|
||||
- const: lrclk
|
||||
- const: mclk
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#sound-dai-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/axg-audio-clkc.h>
|
||||
|
||||
audio-controller {
|
||||
compatible = "amlogic,axg-tdm-iface";
|
||||
#sound-dai-cells = <0>;
|
||||
clocks = <&clkc_audio AUD_CLKID_MST_A_SCLK>,
|
||||
<&clkc_audio AUD_CLKID_MST_A_LRCLK>,
|
||||
<&clkc_audio AUD_CLKID_MST_A_MCLK>;
|
||||
clock-names = "sclk", "lrclk", "mclk";
|
||||
};
|
@ -62,7 +62,7 @@ patternProperties:
|
||||
description: phandle of the CPU DAI
|
||||
|
||||
patternProperties:
|
||||
"^codec-[0-9]+$":
|
||||
"^codec(-[0-9]+)?$":
|
||||
type: object
|
||||
additionalProperties: false
|
||||
description: |-
|
||||
|
@ -11,32 +11,24 @@ maintainers:
|
||||
|
||||
select: false
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/graph.yaml#/$defs/port-base
|
||||
definitions:
|
||||
port-base:
|
||||
$ref: /schemas/graph.yaml#/$defs/port-base
|
||||
properties:
|
||||
convert-rate:
|
||||
$ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-rate"
|
||||
convert-channels:
|
||||
$ref: "/schemas/sound/dai-params.yaml#/$defs/dai-channels"
|
||||
convert-sample-format:
|
||||
$ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-format"
|
||||
mclk-fs:
|
||||
$ref: "simple-card.yaml#/definitions/mclk-fs"
|
||||
|
||||
properties:
|
||||
prefix:
|
||||
description: "device name prefix"
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
convert-rate:
|
||||
$ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-rate"
|
||||
convert-channels:
|
||||
$ref: "/schemas/sound/dai-params.yaml#/$defs/dai-channels"
|
||||
convert-sample-format:
|
||||
$ref: "/schemas/sound/dai-params.yaml#/$defs/dai-sample-format"
|
||||
|
||||
patternProperties:
|
||||
"^endpoint(@[0-9a-f]+)?":
|
||||
endpoint-base:
|
||||
$ref: /schemas/graph.yaml#/$defs/endpoint-base
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
mclk-fs:
|
||||
description: |
|
||||
Multiplication factor between stream rate and codec mclk.
|
||||
When defined, mclk-fs property defined in dai-link sub nodes are
|
||||
ignored.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
$ref: "simple-card.yaml#/definitions/mclk-fs"
|
||||
frame-inversion:
|
||||
description: dai-link uses frame clock inversion
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
@ -53,6 +45,15 @@ patternProperties:
|
||||
oneOf:
|
||||
- $ref: /schemas/types.yaml#/definitions/flag
|
||||
- $ref: /schemas/types.yaml#/definitions/phandle
|
||||
clocks:
|
||||
description: Indicates system clock
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
system-clock-frequency:
|
||||
$ref: "simple-card.yaml#/definitions/system-clock-frequency"
|
||||
system-clock-direction-out:
|
||||
$ref: "simple-card.yaml#/definitions/system-clock-direction-out"
|
||||
system-clock-fixed:
|
||||
$ref: "simple-card.yaml#/definitions/system-clock-fixed"
|
||||
|
||||
dai-format:
|
||||
description: audio format.
|
||||
@ -100,4 +101,24 @@ patternProperties:
|
||||
minimum: 1
|
||||
maximum: 64
|
||||
|
||||
ports:
|
||||
$ref: "#/definitions/port-base"
|
||||
unevaluatedProperties: false
|
||||
patternProperties:
|
||||
"^port(@[0-9a-f]+)?$":
|
||||
$ref: "#/definitions/port-base"
|
||||
unevaluatedProperties: false
|
||||
patternProperties:
|
||||
"^endpoint(@[0-9a-f]+)?":
|
||||
$ref: "#/definitions/endpoint-base"
|
||||
unevaluatedProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: "#/definitions/port-base"
|
||||
|
||||
patternProperties:
|
||||
"^endpoint(@[0-9a-f]+)?":
|
||||
$ref: "#/definitions/endpoint-base"
|
||||
unevaluatedProperties: false
|
||||
|
||||
additionalProperties: true
|
||||
|
53
Documentation/devicetree/bindings/sound/awinic,aw88395.yaml
Normal file
53
Documentation/devicetree/bindings/sound/awinic,aw88395.yaml
Normal file
@ -0,0 +1,53 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/awinic,aw88395.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Awinic AW88395 Smart Audio Amplifier
|
||||
|
||||
maintainers:
|
||||
- Weidong Wang <wangweidong.a@awinic.com>
|
||||
|
||||
description:
|
||||
The Awinic AW88395 is an I2S/TDM input, high efficiency
|
||||
digital Smart K audio amplifier with an integrated 10.25V
|
||||
smart boost convert.
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: awinic,aw88395
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#sound-dai-cells'
|
||||
- reset-gpios
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
audio-codec@34 {
|
||||
compatible = "awinic,aw88395";
|
||||
reg = <0x34>;
|
||||
#sound-dai-cells = <0>;
|
||||
reset-gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
@ -22,6 +22,9 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
'#sound-dai-cells':
|
||||
description:
|
||||
The first cell indicating the audio interface.
|
||||
@ -42,7 +45,7 @@ properties:
|
||||
Configures the peak current by monitoring the current through the boost FET.
|
||||
Range starts at 1600 mA and goes to a maximum of 4500 mA with increments
|
||||
of 50 mA. See section 4.3.6 of the datasheet for details.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 1600
|
||||
maximum: 4500
|
||||
default: 4500
|
||||
@ -51,7 +54,7 @@ properties:
|
||||
description:
|
||||
Boost inductor value, expressed in nH. Valid
|
||||
values include 1000, 1200, 1500 and 2200.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 1000
|
||||
maximum: 2200
|
||||
|
||||
@ -60,7 +63,7 @@ properties:
|
||||
Total equivalent boost capacitance on the VBST
|
||||
and VAMP pins, derated at 11 volts DC. The value must be rounded to the
|
||||
nearest integer and expressed in uF.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
cirrus,asp-sdout-hiz:
|
||||
description:
|
||||
@ -70,7 +73,7 @@ properties:
|
||||
1 = Hi-Z during unused slots but logic 0 while all transmit channels disabled
|
||||
2 = (Default) Logic 0 during unused slots, but Hi-Z while all transmit channels disabled
|
||||
3 = Hi-Z during unused slots and while all transmit channels disabled
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
default: 2
|
||||
@ -84,7 +87,7 @@ properties:
|
||||
enable boost voltage.
|
||||
0 = Internal Boost
|
||||
1 = External Boost
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
|
||||
@ -109,7 +112,7 @@ properties:
|
||||
1 = GPIO
|
||||
2 = Sync
|
||||
3 = MCLK input
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
|
||||
@ -136,7 +139,7 @@ properties:
|
||||
3 = MCLK input
|
||||
4 = Push-pull INTB (active low)
|
||||
5 = Push-pull INT (active high)
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 5
|
||||
|
||||
@ -176,21 +179,23 @@ unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cs35l41: cs35l41@2 {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "cirrus,cs35l41";
|
||||
reg = <2>;
|
||||
VA-supply = <&dummy_vreg>;
|
||||
VP-supply = <&dummy_vreg>;
|
||||
reset-gpios = <&gpio 110 0>;
|
||||
cs35l41: speaker-amp@2 {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "cirrus,cs35l41";
|
||||
reg = <2>;
|
||||
VA-supply = <&dummy_vreg>;
|
||||
VP-supply = <&dummy_vreg>;
|
||||
reset-gpios = <&gpio 110 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
cirrus,boost-type = <0>;
|
||||
cirrus,boost-peak-milliamp = <4500>;
|
||||
cirrus,boost-ind-nanohenry = <1000>;
|
||||
cirrus,boost-cap-microfarad = <15>;
|
||||
cirrus,boost-type = <0>;
|
||||
cirrus,boost-peak-milliamp = <4500>;
|
||||
cirrus,boost-ind-nanohenry = <1000>;
|
||||
cirrus,boost-cap-microfarad = <15>;
|
||||
};
|
||||
};
|
||||
|
@ -0,0 +1,21 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/component-common.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Audio Component Common Properties
|
||||
|
||||
maintainers:
|
||||
- Jerome Brunet <jbrunet@baylibre.com>
|
||||
|
||||
properties:
|
||||
sound-name-prefix:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: |
|
||||
Card implementing the routing property define the connection between
|
||||
audio components as list of string pair. Component using the same
|
||||
sink/source names may use this property to prepend the name of their
|
||||
sinks/sources with the provided string.
|
||||
|
||||
additionalProperties: true
|
@ -9,15 +9,10 @@ title: Digital Audio Interface Common Properties
|
||||
maintainers:
|
||||
- Jerome Brunet <jbrunet@baylibre.com>
|
||||
|
||||
properties:
|
||||
sound-name-prefix:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: |
|
||||
Card implementing the routing property define the connection between
|
||||
audio components as list of string pair. Component using the same
|
||||
sink/source names may use this property to prepend the name of their
|
||||
sinks/sources with the provided string.
|
||||
allOf:
|
||||
- $ref: component-common.yaml#
|
||||
|
||||
properties:
|
||||
'#sound-dai-cells': true
|
||||
|
||||
additionalProperties: true
|
||||
|
@ -76,10 +76,14 @@ properties:
|
||||
minItems: 4
|
||||
|
||||
dmas:
|
||||
maxItems: 2
|
||||
items:
|
||||
- description: DMA controller phandle and request line for RX
|
||||
- description: DMA controller phandle and request line for TX
|
||||
|
||||
dma-names:
|
||||
maxItems: 2
|
||||
items:
|
||||
- const: rx
|
||||
- const: tx
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
@ -142,31 +146,6 @@ properties:
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fsl,vf610-sai
|
||||
then:
|
||||
properties:
|
||||
dmas:
|
||||
items:
|
||||
- description: DMA controller phandle and request line for TX
|
||||
- description: DMA controller phandle and request line for RX
|
||||
dma-names:
|
||||
items:
|
||||
- const: tx
|
||||
- const: rx
|
||||
else:
|
||||
properties:
|
||||
dmas:
|
||||
items:
|
||||
- description: DMA controller phandle and request line for RX
|
||||
- description: DMA controller phandle and request line for TX
|
||||
dma-names:
|
||||
items:
|
||||
- const: rx
|
||||
- const: tx
|
||||
- if:
|
||||
required:
|
||||
- fsl,sai-asynchronous
|
||||
@ -199,9 +178,8 @@ examples:
|
||||
<&clks VF610_CLK_SAI2>,
|
||||
<&clks 0>, <&clks 0>;
|
||||
clock-names = "bus", "mclk1", "mclk2", "mclk3";
|
||||
dma-names = "tx", "rx";
|
||||
dmas = <&edma0 0 21>,
|
||||
<&edma0 0 20>;
|
||||
dma-names = "rx", "tx";
|
||||
dmas = <&edma0 0 20>, <&edma0 0 21>;
|
||||
big-endian;
|
||||
lsb-first;
|
||||
};
|
||||
|
@ -21,6 +21,7 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,imx8mp-xcvr
|
||||
- fsl,imx93-xcvr
|
||||
|
||||
reg:
|
||||
items:
|
||||
|
@ -75,6 +75,18 @@ patternProperties:
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
platform:
|
||||
description: Holds subnode which includes the phandle of q6apm platform device.
|
||||
type: object
|
||||
properties:
|
||||
sound-dai:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- link-name
|
||||
- cpu
|
||||
|
@ -0,0 +1,91 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/infineon,peb2466.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Infineon PEB2466 codec
|
||||
|
||||
maintainers:
|
||||
- Herve Codina <herve.codina@bootlin.com>
|
||||
|
||||
description: |
|
||||
The Infineon PEB2466 codec is a programmable DSP-based four channels codec
|
||||
with filters capabilities.
|
||||
|
||||
The time-slots used by the codec must be set and so, the properties
|
||||
'dai-tdm-slot-num', 'dai-tdm-slot-width', 'dai-tdm-slot-tx-mask' and
|
||||
'dai-tdm-slot-rx-mask' must be present in the sound card node for sub-nodes
|
||||
that involve the codec. The codec uses one 8bit time-slot per channel.
|
||||
'dai-tdm-tdm-slot-with' must be set to 8.
|
||||
|
||||
The PEB2466 codec also supports 28 gpios (signaling pins).
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: infineon,peb2466
|
||||
|
||||
reg:
|
||||
description:
|
||||
SPI device address.
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Master clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 8192000
|
||||
|
||||
reset-gpios:
|
||||
description:
|
||||
GPIO used to reset the device.
|
||||
maxItems: 1
|
||||
|
||||
firmware-name:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
Filters coefficients file to load. If this property is omitted, internal
|
||||
filters are disabled.
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
'#gpio-cells':
|
||||
const: 2
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#sound-dai-cells'
|
||||
- gpio-controller
|
||||
- '#gpio-cells'
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
audio-codec@0 {
|
||||
compatible = "infineon,peb2466";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <8192000>;
|
||||
reset-gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
|
||||
#sound-dai-cells = <0>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
@ -0,0 +1,48 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/irondevice,sma1303.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Iron Device SMA1303 Audio Amplifier
|
||||
|
||||
maintainers:
|
||||
- Kiseok Jo <kiseok.jo@irondevice.com>
|
||||
|
||||
description:
|
||||
SMA1303 digital class-D audio amplifier
|
||||
with an integrated boost converter.
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- irondevice,sma1303
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#sound-dai-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
amplifier@1e {
|
||||
compatible = "irondevice,sma1303";
|
||||
reg = <0x1e>;
|
||||
#sound-dai-cells = <1>;
|
||||
};
|
||||
};
|
@ -1,59 +0,0 @@
|
||||
MAX98090 audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "maxim,max98090" or "maxim,max98091".
|
||||
|
||||
- reg : The I2C address of the device.
|
||||
|
||||
- interrupts : The CODEC's interrupt output.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- clocks: The phandle of the master clock to the CODEC
|
||||
|
||||
- clock-names: Should be "mclk"
|
||||
|
||||
- #sound-dai-cells : should be 0.
|
||||
|
||||
- maxim,dmic-freq: Frequency at which to clock DMIC
|
||||
|
||||
- maxim,micbias: Micbias voltage applies to the analog mic, valid voltages value are:
|
||||
0 - 2.2v
|
||||
1 - 2.55v
|
||||
2 - 2.4v
|
||||
3 - 2.8v
|
||||
|
||||
Pins on the device (for linking into audio routes):
|
||||
|
||||
* MIC1
|
||||
* MIC2
|
||||
* DMICL
|
||||
* DMICR
|
||||
* IN1
|
||||
* IN2
|
||||
* IN3
|
||||
* IN4
|
||||
* IN5
|
||||
* IN6
|
||||
* IN12
|
||||
* IN34
|
||||
* IN56
|
||||
* HPL
|
||||
* HPR
|
||||
* SPKL
|
||||
* SPKR
|
||||
* RCVL
|
||||
* RCVR
|
||||
* MICBIAS
|
||||
|
||||
Example:
|
||||
|
||||
audio-codec@10 {
|
||||
compatible = "maxim,max98090";
|
||||
reg = <0x10>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <TEGRA_GPIO(H, 4) IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
@ -1,22 +0,0 @@
|
||||
MAX98095 audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "maxim,max98095".
|
||||
|
||||
- reg : The I2C address of the device.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- clocks: The phandle of the master clock to the CODEC
|
||||
|
||||
- clock-names: Should be "mclk"
|
||||
|
||||
Example:
|
||||
|
||||
max98095: codec@11 {
|
||||
compatible = "maxim,max98095";
|
||||
reg = <0x11>;
|
||||
};
|
84
Documentation/devicetree/bindings/sound/maxim,max98090.yaml
Normal file
84
Documentation/devicetree/bindings/sound/maxim,max98090.yaml
Normal file
@ -0,0 +1,84 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/maxim,max98090.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Maxim Integrated MAX98090/MAX98091 audio codecs
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
|
||||
description: |
|
||||
Pins on the device (for linking into audio routes):
|
||||
MIC1, MIC2, DMICL, DMICR, IN1, IN2, IN3, IN4, IN5, IN6, IN12, IN34, IN56,
|
||||
HPL, HPR, SPKL, SPKR, RCVL, RCVR, MICBIAS
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- maxim,max98090
|
||||
- maxim,max98091
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: master clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
maxim,dmic-freq:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
default: 2500000
|
||||
description:
|
||||
DMIC clock frequency
|
||||
|
||||
maxim,micbias:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 0, 1, 2, 3 ]
|
||||
default: 3
|
||||
description: |
|
||||
Micbias voltage applied to the analog mic, valid voltages value are:
|
||||
0 - 2.2v
|
||||
1 - 2.55v
|
||||
2 - 2.4v
|
||||
3 - 2.8v
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
audio-codec@10 {
|
||||
compatible = "maxim,max98090";
|
||||
reg = <0x10>;
|
||||
interrupt-parent = <&gpx3>;
|
||||
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
|
||||
clocks = <&i2s0 0>;
|
||||
clock-names = "mclk";
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
};
|
54
Documentation/devicetree/bindings/sound/maxim,max98095.yaml
Normal file
54
Documentation/devicetree/bindings/sound/maxim,max98095.yaml
Normal file
@ -0,0 +1,54 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/maxim,max98095.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Maxim Integrated MAX98095 audio codec
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- maxim,max98095
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: master clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
audio-codec@11 {
|
||||
compatible = "maxim,max98095";
|
||||
reg = <0x11>;
|
||||
clocks = <&i2s0 0>;
|
||||
clock-names = "mclk";
|
||||
};
|
||||
};
|
208
Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
Normal file
208
Documentation/devicetree/bindings/sound/mediatek,mt8188-afe.yaml
Normal file
@ -0,0 +1,208 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mediatek,mt8188-afe.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek AFE PCM controller for mt8188
|
||||
|
||||
maintainers:
|
||||
- Trevor Wu <trevor.wu@mediatek.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8188-afe
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
const: audiosys
|
||||
|
||||
mediatek,topckgen:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle of the mediatek topckgen controller
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: 26M clock
|
||||
- description: audio pll1 clock
|
||||
- description: audio pll2 clock
|
||||
- description: clock divider for i2si1_mck
|
||||
- description: clock divider for i2si2_mck
|
||||
- description: clock divider for i2so1_mck
|
||||
- description: clock divider for i2so2_mck
|
||||
- description: clock divider for dptx_mck
|
||||
- description: a1sys hoping clock
|
||||
- description: audio intbus clock
|
||||
- description: audio hires clock
|
||||
- description: audio local bus clock
|
||||
- description: mux for dptx_mck
|
||||
- description: mux for i2so1_mck
|
||||
- description: mux for i2so2_mck
|
||||
- description: mux for i2si1_mck
|
||||
- description: mux for i2si2_mck
|
||||
- description: audio 26m clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: clk26m
|
||||
- const: apll1
|
||||
- const: apll2
|
||||
- const: apll12_div0
|
||||
- const: apll12_div1
|
||||
- const: apll12_div2
|
||||
- const: apll12_div3
|
||||
- const: apll12_div9
|
||||
- const: a1sys_hp_sel
|
||||
- const: aud_intbus_sel
|
||||
- const: audio_h_sel
|
||||
- const: audio_local_bus_sel
|
||||
- const: dptx_m_sel
|
||||
- const: i2so1_m_sel
|
||||
- const: i2so2_m_sel
|
||||
- const: i2si1_m_sel
|
||||
- const: i2si2_m_sel
|
||||
- const: adsp_audio_26m
|
||||
|
||||
mediatek,etdm-in1-cowork-source:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
etdm modules can share the same external clock pin. Specify
|
||||
which etdm clock source is required by this etdm in module.
|
||||
enum:
|
||||
- 1 # etdm2_in
|
||||
- 2 # etdm1_out
|
||||
- 3 # etdm2_out
|
||||
|
||||
mediatek,etdm-in2-cowork-source:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
etdm modules can share the same external clock pin. Specify
|
||||
which etdm clock source is required by this etdm in module.
|
||||
enum:
|
||||
- 0 # etdm1_in
|
||||
- 2 # etdm1_out
|
||||
- 3 # etdm2_out
|
||||
|
||||
mediatek,etdm-out1-cowork-source:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
etdm modules can share the same external clock pin. Specify
|
||||
which etdm clock source is required by this etdm out module.
|
||||
enum:
|
||||
- 0 # etdm1_in
|
||||
- 1 # etdm2_in
|
||||
- 3 # etdm2_out
|
||||
|
||||
mediatek,etdm-out2-cowork-source:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
etdm modules can share the same external clock pin. Specify
|
||||
which etdm clock source is required by this etdm out module.
|
||||
enum:
|
||||
- 0 # etdm1_in
|
||||
- 1 # etdm2_in
|
||||
- 2 # etdm1_out
|
||||
|
||||
patternProperties:
|
||||
"^mediatek,etdm-in[1-2]-chn-disabled$":
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
minItems: 1
|
||||
maxItems: 16
|
||||
description:
|
||||
This is a list of channel IDs which should be disabled.
|
||||
By default, all data received from ETDM pins will be outputed to
|
||||
memory. etdm in supports disable_out in direct mode(w/o interconn),
|
||||
so user can disable the specified channels by the property.
|
||||
uniqueItems: true
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
|
||||
"^mediatek,etdm-in[1-2]-multi-pin-mode$":
|
||||
type: boolean
|
||||
description: if present, the etdm data mode is I2S.
|
||||
|
||||
"^mediatek,etdm-out[1-3]-multi-pin-mode$":
|
||||
type: boolean
|
||||
description: if present, the etdm data mode is I2S.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- resets
|
||||
- reset-names
|
||||
- mediatek,topckgen
|
||||
- power-domains
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
afe@10b10000 {
|
||||
compatible = "mediatek,mt8188-afe";
|
||||
reg = <0x10b10000 0x10000>;
|
||||
interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
resets = <&watchdog 14>;
|
||||
reset-names = "audiosys";
|
||||
mediatek,topckgen = <&topckgen>;
|
||||
power-domains = <&spm 13>; //MT8188_POWER_DOMAIN_AUDIO
|
||||
mediatek,etdm-in2-cowork-source = <2>;
|
||||
mediatek,etdm-out2-cowork-source = <0>;
|
||||
mediatek,etdm-in1-multi-pin-mode;
|
||||
mediatek,etdm-in1-chn-disabled = /bits/ 8 <0x0 0x2>;
|
||||
clocks = <&clk26m>,
|
||||
<&apmixedsys 9>, //CLK_APMIXED_APLL1
|
||||
<&apmixedsys 10>, //CLK_APMIXED_APLL2
|
||||
<&topckgen 186>, //CLK_TOP_APLL12_CK_DIV0
|
||||
<&topckgen 187>, //CLK_TOP_APLL12_CK_DIV1
|
||||
<&topckgen 188>, //CLK_TOP_APLL12_CK_DIV2
|
||||
<&topckgen 189>, //CLK_TOP_APLL12_CK_DIV3
|
||||
<&topckgen 191>, //CLK_TOP_APLL12_CK_DIV9
|
||||
<&topckgen 83>, //CLK_TOP_A1SYS_HP
|
||||
<&topckgen 31>, //CLK_TOP_AUD_INTBUS
|
||||
<&topckgen 32>, //CLK_TOP_AUDIO_H
|
||||
<&topckgen 69>, //CLK_TOP_AUDIO_LOCAL_BUS
|
||||
<&topckgen 81>, //CLK_TOP_DPTX
|
||||
<&topckgen 77>, //CLK_TOP_I2SO1
|
||||
<&topckgen 78>, //CLK_TOP_I2SO2
|
||||
<&topckgen 79>, //CLK_TOP_I2SI1
|
||||
<&topckgen 80>, //CLK_TOP_I2SI2
|
||||
<&adsp_audio26m 0>; //CLK_AUDIODSP_AUDIO26M
|
||||
clock-names = "clk26m",
|
||||
"apll1",
|
||||
"apll2",
|
||||
"apll12_div0",
|
||||
"apll12_div1",
|
||||
"apll12_div2",
|
||||
"apll12_div3",
|
||||
"apll12_div9",
|
||||
"a1sys_hp_sel",
|
||||
"aud_intbus_sel",
|
||||
"audio_h_sel",
|
||||
"audio_local_bus_sel",
|
||||
"dptx_m_sel",
|
||||
"i2so1_m_sel",
|
||||
"i2so2_m_sel",
|
||||
"i2si1_m_sel",
|
||||
"i2si2_m_sel",
|
||||
"adsp_audio_26m";
|
||||
};
|
||||
|
||||
...
|
@ -0,0 +1,97 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mediatek,mt8188-mt6359.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek MT8188 ASoC sound card
|
||||
|
||||
maintainers:
|
||||
- Trevor Wu <trevor.wu@mediatek.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8188-mt6359-evb
|
||||
|
||||
model:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: User specified audio sound card name
|
||||
|
||||
audio-routing:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
description:
|
||||
A list of the connections between audio components. Each entry is a
|
||||
sink/source pair of strings. Valid names could be the input or output
|
||||
widgets of audio components, power supplies, MicBias of codec and the
|
||||
software switch.
|
||||
|
||||
mediatek,platform:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle of MT8188 ASoC platform.
|
||||
|
||||
patternProperties:
|
||||
"^dai-link-[0-9]+$":
|
||||
type: object
|
||||
description:
|
||||
Container for dai-link level properties and CODEC sub-nodes.
|
||||
|
||||
properties:
|
||||
link-name:
|
||||
description:
|
||||
This property corresponds to the name of the BE dai-link to which
|
||||
we are going to update parameters in this node.
|
||||
items:
|
||||
enum:
|
||||
- ADDA_BE
|
||||
- DPTX_BE
|
||||
- ETDM1_IN_BE
|
||||
- ETDM2_IN_BE
|
||||
- ETDM1_OUT_BE
|
||||
- ETDM2_OUT_BE
|
||||
- ETDM3_OUT_BE
|
||||
- PCM1_BE
|
||||
|
||||
codec:
|
||||
description: Holds subnode which indicates codec dai.
|
||||
type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
sound-dai:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- link-name
|
||||
- codec
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- mediatek,platform
|
||||
|
||||
examples:
|
||||
- |
|
||||
sound {
|
||||
compatible = "mediatek,mt8188-mt6359-evb";
|
||||
mediatek,platform = <&afe>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&aud_pins_default>;
|
||||
audio-routing =
|
||||
"Headphone", "Headphone L",
|
||||
"Headphone", "Headphone R",
|
||||
"AIN1", "Headset Mic";
|
||||
dai-link-0 {
|
||||
link-name = "ETDM3_OUT_BE";
|
||||
|
||||
codec {
|
||||
sound-dai = <&hdmi0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mchp,i2s-mcc.yaml#
|
||||
$id: http://devicetree.org/schemas/sound/microchip,sama7g5-i2smcc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip I2S Multi-Channel Controller
|
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/microchip,pdmc.yaml#
|
||||
$id: http://devicetree.org/schemas/sound/microchip,sama7g5-pdmc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip Pulse Density Microphone Controller
|
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mchp,spdifrx.yaml#
|
||||
$id: http://devicetree.org/schemas/sound/microchip,sama7g5-spdifrx.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip S/PDIF Rx Controller
|
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mchp,spdiftx.yaml#
|
||||
$id: http://devicetree.org/schemas/sound/microchip,sama7g5-spdiftx.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip S/PDIF Tx Controller
|
@ -1,16 +0,0 @@
|
||||
NAU8822 audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "nuvoton,nau8822"
|
||||
|
||||
- reg : the I2C address of the device.
|
||||
|
||||
Example:
|
||||
|
||||
codec: nau8822@1a {
|
||||
compatible = "nuvoton,nau8822";
|
||||
reg = <0x1a>;
|
||||
};
|
46
Documentation/devicetree/bindings/sound/nuvoton,nau8822.yaml
Normal file
46
Documentation/devicetree/bindings/sound/nuvoton,nau8822.yaml
Normal file
@ -0,0 +1,46 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nuvoton,nau8822.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NAU8822 audio CODEC
|
||||
|
||||
description: |
|
||||
24 bit stereo audio codec with speaker driver.
|
||||
This device supports I2C/SPI.
|
||||
|
||||
maintainers:
|
||||
- David Lin <CTLIN0@nuvoton.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nuvoton,nau8822
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
nuvoton,spk-btl:
|
||||
description:
|
||||
If set, configure the two loudspeaker outputs as a Bridge Tied Load output
|
||||
to drive a high power external loudspeaker.
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
codec@1a {
|
||||
compatible = "nuvoton,nau8822";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
};
|
@ -35,7 +35,7 @@ properties:
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
maxItems: 7
|
||||
maxItems: 10
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
@ -65,6 +65,9 @@ properties:
|
||||
power-domain-names:
|
||||
maxItems: 1
|
||||
|
||||
required-opps:
|
||||
maxItems: 1
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
@ -75,7 +78,7 @@ properties:
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"^dai-link@[0-9a-f]$":
|
||||
"^dai-link@[0-9a-f]+$":
|
||||
type: object
|
||||
description: |
|
||||
LPASS CPU dai node for each I2S device or Soundwire device. Bindings of each node
|
||||
@ -121,6 +124,8 @@ allOf:
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahbix-clk
|
||||
@ -135,6 +140,9 @@ allOf:
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 7
|
||||
maxItems: 7
|
||||
clock-names:
|
||||
items:
|
||||
- const: ahbix-clk
|
||||
@ -153,33 +161,31 @@ allOf:
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
clock-names:
|
||||
oneOf:
|
||||
- items: #for I2S
|
||||
- const: pcnoc-sway-clk
|
||||
- const: audio-core
|
||||
- const: mclk0
|
||||
- const: pcnoc-mport-clk
|
||||
- const: mi2s-bit-clk0
|
||||
- const: mi2s-bit-clk1
|
||||
- items: #for HDMI
|
||||
- const: pcnoc-sway-clk
|
||||
- const: audio-core
|
||||
- const: pcnoc-mport-clk
|
||||
items:
|
||||
- const: pcnoc-sway-clk
|
||||
- const: audio-core
|
||||
- const: mclk0
|
||||
- const: pcnoc-mport-clk
|
||||
- const: mi2s-bit-clk0
|
||||
- const: mi2s-bit-clk1
|
||||
reg:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
reg-names:
|
||||
anyOf:
|
||||
- items: #for I2S
|
||||
- const: lpass-lpaif
|
||||
- items: #for I2S and HDMI
|
||||
- const: lpass-hdmiif
|
||||
- const: lpass-lpaif
|
||||
items:
|
||||
- const: lpass-hdmiif
|
||||
- const: lpass-lpaif
|
||||
interrupts:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
interrupt-names:
|
||||
anyOf:
|
||||
- items: #for I2S
|
||||
- const: lpass-irq-lpaif
|
||||
- items: #for I2S and HDMI
|
||||
- const: lpass-irq-lpaif
|
||||
- const: lpass-irq-hdmi
|
||||
items:
|
||||
- const: lpass-irq-lpaif
|
||||
- const: lpass-irq-hdmi
|
||||
required:
|
||||
- iommus
|
||||
- power-domains
|
||||
@ -192,54 +198,44 @@ allOf:
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 10
|
||||
maxItems: 10
|
||||
clock-names:
|
||||
oneOf:
|
||||
- items: #for I2S
|
||||
- const: aon_cc_audio_hm_h
|
||||
- const: audio_cc_ext_mclk0
|
||||
- const: core_cc_sysnoc_mport_core
|
||||
- const: core_cc_ext_if0_ibit
|
||||
- const: core_cc_ext_if1_ibit
|
||||
- items: #for Soundwire
|
||||
- const: aon_cc_audio_hm_h
|
||||
- const: audio_cc_codec_mem
|
||||
- const: audio_cc_codec_mem0
|
||||
- const: audio_cc_codec_mem1
|
||||
- const: audio_cc_codec_mem2
|
||||
- const: aon_cc_va_mem0
|
||||
- items: #for HDMI
|
||||
- const: core_cc_sysnoc_mport_core
|
||||
|
||||
items:
|
||||
- const: aon_cc_audio_hm_h
|
||||
- const: audio_cc_ext_mclk0
|
||||
- const: core_cc_sysnoc_mport_core
|
||||
- const: core_cc_ext_if0_ibit
|
||||
- const: core_cc_ext_if1_ibit
|
||||
- const: audio_cc_codec_mem
|
||||
- const: audio_cc_codec_mem0
|
||||
- const: audio_cc_codec_mem1
|
||||
- const: audio_cc_codec_mem2
|
||||
- const: aon_cc_va_mem0
|
||||
reg:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
reg-names:
|
||||
anyOf:
|
||||
- items: #for I2S
|
||||
- const: lpass-lpaif
|
||||
- items: #for I2S and HDMI
|
||||
- const: lpass-hdmiif
|
||||
- const: lpass-lpaif
|
||||
- items: #for I2S, soundwire and HDMI
|
||||
- const: lpass-hdmiif
|
||||
- const: lpass-lpaif
|
||||
- const: lpass-rxtx-cdc-dma-lpm
|
||||
- const: lpass-rxtx-lpaif
|
||||
- const: lpass-va-lpaif
|
||||
- const: lpass-va-cdc-dma-lpm
|
||||
items:
|
||||
- const: lpass-hdmiif
|
||||
- const: lpass-lpaif
|
||||
- const: lpass-rxtx-cdc-dma-lpm
|
||||
- const: lpass-rxtx-lpaif
|
||||
- const: lpass-va-lpaif
|
||||
- const: lpass-va-cdc-dma-lpm
|
||||
interrupts:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
interrupt-names:
|
||||
anyOf:
|
||||
- items: #for I2S
|
||||
- const: lpass-irq-lpaif
|
||||
- items: #for I2S and HDMI
|
||||
- const: lpass-irq-lpaif
|
||||
- const: lpass-irq-hdmi
|
||||
- items: #for I2S, soundwire and HDMI
|
||||
- const: lpass-irq-lpaif
|
||||
- const: lpass-irq-hdmi
|
||||
- const: lpass-irq-vaif
|
||||
- const: lpass-irq-rxtxif
|
||||
items:
|
||||
- const: lpass-irq-lpaif
|
||||
- const: lpass-irq-hdmi
|
||||
- const: lpass-irq-vaif
|
||||
- const: lpass-irq-rxtxif
|
||||
power-domain-names:
|
||||
allOf:
|
||||
- items:
|
||||
- const: lcx
|
||||
items:
|
||||
- const: lcx
|
||||
|
||||
required:
|
||||
- iommus
|
||||
|
@ -36,7 +36,7 @@ properties:
|
||||
oneOf:
|
||||
- items: #for ADSP based platforms
|
||||
- const: mclk
|
||||
- const: core
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- items: #for ADSP bypass based platforms
|
||||
- const: mclk
|
||||
@ -77,7 +77,7 @@ examples:
|
||||
clocks = <&aoncc 0>,
|
||||
<&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
|
||||
clock-names = "mclk", "core", "dcodec";
|
||||
clock-names = "mclk", "macro", "dcodec";
|
||||
clock-output-names = "fsgen";
|
||||
qcom,dmic-sample-rate = <600000>;
|
||||
vdd-micb-supply = <&vreg_s4a_1p8>;
|
||||
|
@ -17,7 +17,8 @@ properties:
|
||||
const: qcom,q6apm-dais
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -15,16 +15,20 @@ description:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- lenovo,yoga-c630-sndcard
|
||||
- qcom,apq8016-sbc-sndcard
|
||||
- qcom,db845c-sndcard
|
||||
- qcom,msm8916-qdsp6-sndcard
|
||||
- qcom,qrb5165-rb5-sndcard
|
||||
- qcom,sc8280xp-sndcard
|
||||
- qcom,sdm845-sndcard
|
||||
- qcom,sm8250-sndcard
|
||||
- qcom,sm8450-sndcard
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- lenovo,yoga-c630-sndcard
|
||||
- qcom,db845c-sndcard
|
||||
- const: qcom,sdm845-sndcard
|
||||
- enum:
|
||||
- qcom,apq8016-sbc-sndcard
|
||||
- qcom,msm8916-qdsp6-sndcard
|
||||
- qcom,qrb5165-rb5-sndcard
|
||||
- qcom,sc8280xp-sndcard
|
||||
- qcom,sdm845-sndcard
|
||||
- qcom,sm8250-sndcard
|
||||
- qcom,sm8450-sndcard
|
||||
|
||||
audio-routing:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
|
@ -28,7 +28,9 @@ properties:
|
||||
description: GPIO spec for reset line to use
|
||||
maxItems: 1
|
||||
|
||||
slim-ifc-dev: true
|
||||
slim-ifc-dev:
|
||||
description: IFC device interface
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
@ -147,21 +149,49 @@ patternProperties:
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reset-gpios
|
||||
- slim-ifc-dev
|
||||
- interrupts
|
||||
- interrupt-controller
|
||||
- clock-frequency
|
||||
- clock-output-names
|
||||
- qcom,micbias1-microvolt
|
||||
- qcom,micbias2-microvolt
|
||||
- qcom,micbias3-microvolt
|
||||
- qcom,micbias4-microvolt
|
||||
- "#interrupt-cells"
|
||||
- "#clock-cells"
|
||||
- "#sound-dai-cells"
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
required:
|
||||
- slim-ifc-dev
|
||||
then:
|
||||
required:
|
||||
- reset-gpios
|
||||
- slim-ifc-dev
|
||||
- interrupt-controller
|
||||
- clock-frequency
|
||||
- clock-output-names
|
||||
- qcom,micbias1-microvolt
|
||||
- qcom,micbias2-microvolt
|
||||
- qcom,micbias3-microvolt
|
||||
- qcom,micbias4-microvolt
|
||||
- "#interrupt-cells"
|
||||
- "#clock-cells"
|
||||
- "#sound-dai-cells"
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
oneOf:
|
||||
- required:
|
||||
- interrupts-extended
|
||||
- required:
|
||||
- interrupts
|
||||
else:
|
||||
properties:
|
||||
reset-gpios: false
|
||||
slim-ifc-dev: false
|
||||
interrupts: false
|
||||
interrupt-controller: false
|
||||
clock-frequency: false
|
||||
clock-output-names: false
|
||||
qcom,micbias1-microvolt: false
|
||||
qcom,micbias2-microvolt: false
|
||||
qcom,micbias3-microvolt: false
|
||||
qcom,micbias4-microvolt: false
|
||||
"#interrupt-cells": false
|
||||
"#clock-cells": false
|
||||
"#sound-dai-cells": false
|
||||
"#address-cells": false
|
||||
"#size-cells": false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
@ -15,6 +15,9 @@ description: |
|
||||
Their primary operating mode uses a SoundWire digital audio
|
||||
interface. This binding is for SoundWire interface.
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sdw10217201000
|
||||
@ -39,7 +42,7 @@ required:
|
||||
- "#thermal-sensor-cells"
|
||||
- "#sound-dai-cells"
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -0,0 +1,75 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/renesas,idt821034.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas IDT821034 codec device
|
||||
|
||||
maintainers:
|
||||
- Herve Codina <herve.codina@bootlin.com>
|
||||
|
||||
description: |
|
||||
The IDT821034 codec is a four channel PCM codec with onchip filters and
|
||||
programmable gain setting.
|
||||
|
||||
The time-slots used by the codec must be set and so, the properties
|
||||
'dai-tdm-slot-num', 'dai-tdm-slot-width', 'dai-tdm-slot-tx-mask' and
|
||||
'dai-tdm-slot-rx-mask' must be present in the ALSA sound card node for
|
||||
sub-nodes that involve the codec. The codec uses one 8bit time-slot per
|
||||
channel.
|
||||
'dai-tdm-tdm-slot-with' must be set to 8.
|
||||
|
||||
The IDT821034 codec also supports 5 gpios (SLIC signals) per channel.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,idt821034
|
||||
|
||||
reg:
|
||||
description:
|
||||
SPI device address.
|
||||
maxItems: 1
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 8192000
|
||||
|
||||
spi-cpha: true
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
'#gpio-cells':
|
||||
const: 2
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- spi-cpha
|
||||
- '#sound-dai-cells'
|
||||
- gpio-controller
|
||||
- '#gpio-cells'
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
audio-codec@0 {
|
||||
compatible = "renesas,idt821034";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <8192000>;
|
||||
spi-cpha;
|
||||
#sound-dai-cells = <0>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
@ -18,8 +18,7 @@ properties:
|
||||
- enum:
|
||||
- renesas,rcar_sound-r8a7778 # R-Car M1A
|
||||
- renesas,rcar_sound-r8a7779 # R-Car H1
|
||||
- enum:
|
||||
- renesas,rcar_sound-gen1
|
||||
- const: renesas,rcar_sound-gen1
|
||||
# for Gen2 SoC
|
||||
- items:
|
||||
- enum:
|
||||
@ -32,8 +31,7 @@ properties:
|
||||
- renesas,rcar_sound-r8a7791 # R-Car M2-W
|
||||
- renesas,rcar_sound-r8a7793 # R-Car M2-N
|
||||
- renesas,rcar_sound-r8a7794 # R-Car E2
|
||||
- enum:
|
||||
- renesas,rcar_sound-gen2
|
||||
- const: renesas,rcar_sound-gen2
|
||||
# for Gen3 SoC
|
||||
- items:
|
||||
- enum:
|
||||
@ -47,14 +45,16 @@ properties:
|
||||
- renesas,rcar_sound-r8a77965 # R-Car M3-N
|
||||
- renesas,rcar_sound-r8a77990 # R-Car E3
|
||||
- renesas,rcar_sound-r8a77995 # R-Car D3
|
||||
- enum:
|
||||
- renesas,rcar_sound-gen3
|
||||
# for Generic
|
||||
- const: renesas,rcar_sound-gen3
|
||||
# for Gen4 SoC
|
||||
- items:
|
||||
- enum:
|
||||
- renesas,rcar_sound-gen1
|
||||
- renesas,rcar_sound-gen2
|
||||
- renesas,rcar_sound-gen3
|
||||
- const: renesas,rcar_sound-r8a779g0 # R-Car V4H
|
||||
- const: renesas,rcar_sound-gen4
|
||||
# for Generic
|
||||
- enum:
|
||||
- renesas,rcar_sound-gen1
|
||||
- renesas,rcar_sound-gen2
|
||||
- renesas,rcar_sound-gen3
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
@ -68,6 +68,7 @@ properties:
|
||||
description: |
|
||||
it must be 0 if your system is using single DAI
|
||||
it must be 1 if your system is using multi DAIs
|
||||
This is used on simple-audio-card
|
||||
enum: [0, 1]
|
||||
|
||||
"#clock-cells":
|
||||
@ -113,15 +114,34 @@ properties:
|
||||
- pattern: '^clk_(a|b|c|i)$'
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
$ref: audio-graph-port.yaml#/definitions/port-base
|
||||
unevaluatedProperties: false
|
||||
patternProperties:
|
||||
'^port(@[0-9a-f]+)?$':
|
||||
$ref: audio-graph-port.yaml#
|
||||
$ref: audio-graph-port.yaml#/definitions/port-base
|
||||
unevaluatedProperties: false
|
||||
patternProperties:
|
||||
"^endpoint(@[0-9a-f]+)?":
|
||||
$ref: audio-graph-port.yaml#/definitions/endpoint-base
|
||||
properties:
|
||||
playback:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
capture:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
unevaluatedProperties: false
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
$ref: audio-graph-port.yaml#/definitions/port-base
|
||||
unevaluatedProperties: false
|
||||
patternProperties:
|
||||
"^endpoint(@[0-9a-f]+)?":
|
||||
$ref: audio-graph-port.yaml#/definitions/endpoint-base
|
||||
properties:
|
||||
playback:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
capture:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
unevaluatedProperties: false
|
||||
|
||||
rcar_sound,dvc:
|
||||
description: DVC subnode.
|
||||
@ -178,10 +198,6 @@ properties:
|
||||
enum:
|
||||
- tx
|
||||
- rx
|
||||
required:
|
||||
- interrupts
|
||||
- dmas
|
||||
- dma-names
|
||||
additionalProperties: false
|
||||
|
||||
rcar_sound,ssiu:
|
||||
@ -240,8 +256,6 @@ properties:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
required:
|
||||
- interrupts
|
||||
- dmas
|
||||
- dma-names
|
||||
additionalProperties: false
|
||||
|
||||
# For DAI base
|
||||
@ -271,7 +285,6 @@ required:
|
||||
- reg-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- "#sound-dai-cells"
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
@ -285,7 +298,6 @@ allOf:
|
||||
reg:
|
||||
maxItems: 3
|
||||
reg-names:
|
||||
maxItems: 3
|
||||
items:
|
||||
enum:
|
||||
- scu
|
||||
@ -294,9 +306,8 @@ allOf:
|
||||
else:
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 5
|
||||
minItems: 5
|
||||
reg-names:
|
||||
maxItems: 5
|
||||
items:
|
||||
enum:
|
||||
- scu
|
||||
|
@ -20,6 +20,9 @@ Optional properties:
|
||||
- realtek,in3-differential
|
||||
Boolean. Indicate MIC1/2/3 input are differential, rather than single-ended.
|
||||
|
||||
- realtek,lout-differential
|
||||
Boolean. Indicate LOUT output is differential, rather than stereo.
|
||||
|
||||
- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
|
||||
|
||||
- realtek,dmic1-data-pin
|
||||
|
@ -43,9 +43,10 @@ properties:
|
||||
type: object
|
||||
properties:
|
||||
sound-dai:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: phandle of the MAX98090 CODEC
|
||||
- description: phandle of the HDMI IP block node
|
||||
- description: phandle of the MAX98090 CODEC
|
||||
|
||||
samsung,audio-routing:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
|
@ -37,12 +37,20 @@ properties:
|
||||
samsung,exynos7-i2s1: I2S1 on previous samsung platforms supports
|
||||
stereo channels. Exynos7 I2S1 upgraded to 5.1 multichannel with
|
||||
slightly modified bit offsets.
|
||||
|
||||
tesla,fsd-i2s: for 8/16/24bit stereo channel I2S for playback and
|
||||
capture, secondary FIFO using external DMA, s/w reset control,
|
||||
internal mux for root clock source with all root clock sampling
|
||||
frequencies supported by Exynos7 I2S and 7.1 channel TDM support
|
||||
for playback and capture TDM (Time division multiplexing) to allow
|
||||
transfer of multiple channel audio data on single data line.
|
||||
enum:
|
||||
- samsung,s3c6410-i2s
|
||||
- samsung,s5pv210-i2s
|
||||
- samsung,exynos5420-i2s
|
||||
- samsung,exynos7-i2s
|
||||
- samsung,exynos7-i2s1
|
||||
- tesla,fsd-i2s
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
@ -67,9 +75,6 @@ properties:
|
||||
- const: rx
|
||||
- const: tx-sec
|
||||
|
||||
assigned-clock-parents: true
|
||||
assigned-clocks: true
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
@ -205,6 +205,8 @@ patternProperties:
|
||||
$ref: "#/definitions/dai"
|
||||
"^simple-audio-card,codec(@[0-9a-f]+)?$":
|
||||
$ref: "#/definitions/dai"
|
||||
"^simple-audio-card,plat(@[0-9a-f]+)?$":
|
||||
$ref: "#/definitions/dai"
|
||||
|
||||
"^simple-audio-card,dai-link(@[0-9a-f]+)?$":
|
||||
description: |
|
||||
@ -215,6 +217,10 @@ patternProperties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
"#size-cells":
|
||||
const: 0
|
||||
# common properties
|
||||
frame-master:
|
||||
$ref: "#/definitions/frame-master"
|
||||
@ -244,9 +250,9 @@ patternProperties:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
"^cpu(@[0-9a-f]+)?":
|
||||
"^cpu(-[0-9]+)?$":
|
||||
$ref: "#/definitions/dai"
|
||||
"^codec(@[0-9a-f]+)?":
|
||||
"^codec(-[0-9]+)?$":
|
||||
$ref: "#/definitions/dai"
|
||||
additionalProperties: false
|
||||
|
||||
@ -462,16 +468,16 @@ examples:
|
||||
|
||||
convert-channels = <8>; /* TDM Split */
|
||||
|
||||
sndcpu1: cpu0 {
|
||||
sndcpu1: cpu-0 {
|
||||
sound-dai = <&rcar_sound 1>;
|
||||
};
|
||||
cpu1 {
|
||||
cpu-1 {
|
||||
sound-dai = <&rcar_sound 2>;
|
||||
};
|
||||
cpu2 {
|
||||
cpu-2 {
|
||||
sound-dai = <&rcar_sound 3>;
|
||||
};
|
||||
cpu3 {
|
||||
cpu-3 {
|
||||
sound-dai = <&rcar_sound 4>;
|
||||
};
|
||||
codec {
|
||||
|
@ -6,11 +6,13 @@ audio playback. For more product information please see the links below:
|
||||
|
||||
https://www.ti.com/product/TAS5720L
|
||||
https://www.ti.com/product/TAS5720M
|
||||
https://www.ti.com/product/TAS5720A-Q1
|
||||
https://www.ti.com/product/TAS5722L
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "ti,tas5720",
|
||||
"ti,tas5720a-q1",
|
||||
"ti,tas5722"
|
||||
- reg : I2C slave address
|
||||
- dvdd-supply : phandle to a 3.3-V supply for the digital circuitry
|
||||
|
@ -1,56 +0,0 @@
|
||||
Texas Instruments pcm3168a DT bindings
|
||||
|
||||
This driver supports both SPI and I2C bus access for this codec
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: "ti,pcm3168a"
|
||||
|
||||
- clocks : Contains an entry for each entry in clock-names
|
||||
|
||||
- clock-names : Includes the following entries:
|
||||
"scki" The system clock
|
||||
|
||||
- VDD1-supply : Digital power supply regulator 1 (+3.3V)
|
||||
|
||||
- VDD2-supply : Digital power supply regulator 2 (+3.3V)
|
||||
|
||||
- VCCAD1-supply : ADC power supply regulator 1 (+5V)
|
||||
|
||||
- VCCAD2-supply : ADC power supply regulator 2 (+5V)
|
||||
|
||||
- VCCDA1-supply : DAC power supply regulator 1 (+5V)
|
||||
|
||||
- VCCDA2-supply : DAC power supply regulator 2 (+5V)
|
||||
|
||||
For required properties on SPI/I2C, consult SPI/I2C device tree documentation
|
||||
|
||||
Optional properties:
|
||||
|
||||
- reset-gpios : Optional reset gpio line connected to RST pin of the codec.
|
||||
The RST line is low active:
|
||||
RST = low: device power-down
|
||||
RST = high: device is enabled
|
||||
|
||||
Examples:
|
||||
|
||||
i2c0: i2c0@0 {
|
||||
|
||||
...
|
||||
|
||||
pcm3168a: audio-codec@44 {
|
||||
compatible = "ti,pcm3168a";
|
||||
reg = <0x44>;
|
||||
reset-gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
|
||||
clocks = <&clk_core CLK_AUDIO>;
|
||||
clock-names = "scki";
|
||||
VDD1-supply = <&supply3v3>;
|
||||
VDD2-supply = <&supply3v3>;
|
||||
VCCAD1-supply = <&supply5v0>;
|
||||
VCCAD2-supply = <&supply5v0>;
|
||||
VCCDA1-supply = <&supply5v0>;
|
||||
VCCDA2-supply = <&supply5v0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&dac_clk_pin>;
|
||||
};
|
||||
};
|
107
Documentation/devicetree/bindings/sound/ti,pcm3168a.yaml
Normal file
107
Documentation/devicetree/bindings/sound/ti,pcm3168a.yaml
Normal file
@ -0,0 +1,107 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/ti,pcm3168a.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments PCM3168A Audio Codec
|
||||
|
||||
maintainers:
|
||||
- Damien Horsley <Damien.Horsley@imgtec.com>
|
||||
- Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
- Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
|
||||
description:
|
||||
The Texas Instruments PCM3168A is a 24-bit Multi-channel Audio CODEC with
|
||||
96/192kHz sampling rate, supporting both SPI and I2C bus access.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,pcm3168a
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: System clock input
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: scki
|
||||
|
||||
reset-gpios:
|
||||
items:
|
||||
- description: |
|
||||
GPIO line connected to the active-low RST pin of the codec.
|
||||
RST = low: device power-down
|
||||
RST = high: device is enabled
|
||||
|
||||
"#sound-dai-cells":
|
||||
enum: [0, 1]
|
||||
|
||||
VDD1-supply:
|
||||
description: Digital power supply regulator 1 (+3.3V)
|
||||
|
||||
VDD2-supply:
|
||||
description: Digital power supply regulator 2 (+3.3V)
|
||||
|
||||
VCCAD1-supply:
|
||||
description: ADC power supply regulator 1 (+5V)
|
||||
|
||||
VCCAD2-supply:
|
||||
description: ADC power supply regulator 2 (+5V)
|
||||
|
||||
VCCDA1-supply:
|
||||
description: DAC power supply regulator 1 (+5V)
|
||||
|
||||
VCCDA2-supply:
|
||||
description: DAC power supply regulator 2 (+5V)
|
||||
|
||||
ports:
|
||||
$ref: audio-graph-port.yaml#/definitions/port-base
|
||||
properties:
|
||||
port@0:
|
||||
$ref: audio-graph-port.yaml#
|
||||
description: Audio input port.
|
||||
|
||||
port@1:
|
||||
$ref: audio-graph-port.yaml#
|
||||
description: Audio output port.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- VDD1-supply
|
||||
- VDD2-supply
|
||||
- VCCAD1-supply
|
||||
- VCCAD2-supply
|
||||
- VCCDA1-supply
|
||||
- VCCDA2-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pcm3168a: audio-codec@44 {
|
||||
compatible = "ti,pcm3168a";
|
||||
reg = <0x44>;
|
||||
reset-gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
|
||||
clocks = <&clk_core 42>;
|
||||
clock-names = "scki";
|
||||
VDD1-supply = <&supply3v3>;
|
||||
VDD2-supply = <&supply3v3>;
|
||||
VCCAD1-supply = <&supply5v0>;
|
||||
VCCAD2-supply = <&supply5v0>;
|
||||
VCCDA1-supply = <&supply5v0>;
|
||||
VCCDA2-supply = <&supply5v0>;
|
||||
};
|
||||
};
|
165
Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml
Normal file
165
Documentation/devicetree/bindings/sound/ti,tlv320aic3x.yaml
Normal file
@ -0,0 +1,165 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
# Copyright (C) 2022 Texas Instruments Incorporated
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/ti,tlv320aic3x.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments TLV320AIC3x Codec
|
||||
|
||||
description: |
|
||||
TLV320AIC3x are a series of low-power stereo audio codecs with stereo
|
||||
headphone amplifier, as well as multiple inputs and outputs programmable in
|
||||
single-ended or fully differential configurations.
|
||||
|
||||
The serial control bus supports SPI or I2C protocols, while the serial audio
|
||||
data bus is programmable for I2S, left/right-justified, DSP, or TDM modes.
|
||||
|
||||
The following pins can be referred in the sound node's audio routing property:
|
||||
|
||||
CODEC output pins:
|
||||
LLOUT
|
||||
RLOUT
|
||||
MONO_LOUT
|
||||
HPLOUT
|
||||
HPROUT
|
||||
HPLCOM
|
||||
HPRCOM
|
||||
|
||||
CODEC input pins for TLV320AIC3104:
|
||||
MIC2L
|
||||
MIC2R
|
||||
LINE1L
|
||||
LINE1R
|
||||
|
||||
CODEC input pins for other compatible codecs:
|
||||
MIC3L
|
||||
MIC3R
|
||||
LINE1L
|
||||
LINE2L
|
||||
LINE1R
|
||||
LINE2R
|
||||
|
||||
maintainers:
|
||||
- Jai Luthra <j-luthra@ti.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,tlv320aic3x
|
||||
- ti,tlv320aic33
|
||||
- ti,tlv320aic3007
|
||||
- ti,tlv320aic3106
|
||||
- ti,tlv320aic3104
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
GPIO specification for the active low RESET input.
|
||||
|
||||
gpio-reset:
|
||||
maxItems: 1
|
||||
description:
|
||||
Deprecated, please use reset-gpios instead.
|
||||
deprecated: true
|
||||
|
||||
ai3x-gpio-func:
|
||||
description: AIC3X_GPIO1 & AIC3X_GPIO2 Functionality
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
maxItems: 2
|
||||
|
||||
ai3x-micbias-vg:
|
||||
description: MicBias required voltage. If node is omitted then MicBias is powered down.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
oneOf:
|
||||
- const: 1
|
||||
description: MICBIAS output is powered to 2.0V.
|
||||
- const: 2
|
||||
description: MICBIAS output is powered to 2.5V.
|
||||
- const: 3
|
||||
description: MICBIAS output is connected to AVDD.
|
||||
|
||||
ai3x-ocmv:
|
||||
description: Output Common-Mode Voltage selection.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
oneOf:
|
||||
- const: 0
|
||||
description: 1.35V
|
||||
- const: 1
|
||||
description: 1.5V
|
||||
- const: 2
|
||||
description: 1.65V
|
||||
- const: 3
|
||||
description: 1.8V
|
||||
|
||||
AVDD-supply:
|
||||
description: Analog DAC voltage.
|
||||
|
||||
IOVDD-supply:
|
||||
description: I/O voltage.
|
||||
|
||||
DRVDD-supply:
|
||||
description: ADC analog and output driver voltage.
|
||||
|
||||
DVDD-supply:
|
||||
description: Digital core voltage.
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
tlv320aic3x_i2c: audio-codec@1b {
|
||||
compatible = "ti,tlv320aic3x";
|
||||
reg = <0x1b>;
|
||||
|
||||
reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
|
||||
|
||||
AVDD-supply = <®ulator>;
|
||||
IOVDD-supply = <®ulator>;
|
||||
DRVDD-supply = <®ulator>;
|
||||
DVDD-supply = <®ulator>;
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
tlv320aic3x_spi: audio-codec@0 {
|
||||
compatible = "ti,tlv320aic3x";
|
||||
reg = <0>; /* CS number */
|
||||
#sound-dai-cells = <0>;
|
||||
|
||||
AVDD-supply = <®ulator>;
|
||||
IOVDD-supply = <®ulator>;
|
||||
DRVDD-supply = <®ulator>;
|
||||
DVDD-supply = <®ulator>;
|
||||
ai3x-ocmv = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -1,97 +0,0 @@
|
||||
Texas Instruments - tlv320aic3x Codec module
|
||||
|
||||
The tlv320aic3x serial control bus communicates through both I2C and SPI bus protocols
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible - "string" - One of:
|
||||
"ti,tlv320aic3x" - Generic TLV320AIC3x device
|
||||
"ti,tlv320aic33" - TLV320AIC33
|
||||
"ti,tlv320aic3007" - TLV320AIC3007
|
||||
"ti,tlv320aic3106" - TLV320AIC3106
|
||||
"ti,tlv320aic3104" - TLV320AIC3104
|
||||
|
||||
|
||||
- reg - <int> - I2C slave address
|
||||
|
||||
|
||||
Optional properties:
|
||||
|
||||
- reset-gpios - GPIO specification for the active low RESET input.
|
||||
- ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality
|
||||
- Not supported on tlv320aic3104
|
||||
- ai3x-micbias-vg - MicBias Voltage required.
|
||||
1 - MICBIAS output is powered to 2.0V,
|
||||
2 - MICBIAS output is powered to 2.5V,
|
||||
3 - MICBIAS output is connected to AVDD,
|
||||
If this node is not mentioned or if the value is incorrect, then MicBias
|
||||
is powered down.
|
||||
- ai3x-ocmv - Output Common-Mode Voltage selection:
|
||||
0 - 1.35V,
|
||||
1 - 1.5V,
|
||||
2 - 1.65V,
|
||||
3 - 1.8V
|
||||
- AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the
|
||||
device as covered in Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
|
||||
Deprecated properties:
|
||||
|
||||
- gpio-reset - gpio pin number used for codec reset
|
||||
|
||||
CODEC output pins:
|
||||
* LLOUT
|
||||
* RLOUT
|
||||
* MONO_LOUT
|
||||
* HPLOUT
|
||||
* HPROUT
|
||||
* HPLCOM
|
||||
* HPRCOM
|
||||
|
||||
CODEC input pins for TLV320AIC3104:
|
||||
* MIC2L
|
||||
* MIC2R
|
||||
* LINE1L
|
||||
* LINE1R
|
||||
|
||||
CODEC input pins for other compatible codecs:
|
||||
* MIC3L
|
||||
* MIC3R
|
||||
* LINE1L
|
||||
* LINE2L
|
||||
* LINE1R
|
||||
* LINE2R
|
||||
|
||||
The pins can be used in referring sound node's audio-routing property.
|
||||
|
||||
I2C example:
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
tlv320aic3x: tlv320aic3x@1b {
|
||||
compatible = "ti,tlv320aic3x";
|
||||
reg = <0x1b>;
|
||||
|
||||
reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>;
|
||||
|
||||
AVDD-supply = <®ulator>;
|
||||
IOVDD-supply = <®ulator>;
|
||||
DRVDD-supply = <®ulator>;
|
||||
DVDD-supply = <®ulator>;
|
||||
};
|
||||
|
||||
SPI example:
|
||||
|
||||
spi0: spi@f0000000 {
|
||||
tlv320aic3x: codec@0 {
|
||||
compatible = "ti,tlv320aic3x";
|
||||
reg = <0>; /* CS number */
|
||||
#sound-dai-cells = <0>;
|
||||
spi-max-frequency = <1000000>;
|
||||
|
||||
AVDD-supply = <®ulator>;
|
||||
IOVDD-supply = <®ulator>;
|
||||
DRVDD-supply = <®ulator>;
|
||||
DVDD-supply = <®ulator>;
|
||||
ai3x-ocmv = <0>;
|
||||
};
|
||||
};
|
@ -635,6 +635,8 @@ patternProperties:
|
||||
description: Inverse Path
|
||||
"^iom,.*":
|
||||
description: Iomega Corporation
|
||||
"^irondevice,.*":
|
||||
description: Iron Device Corporation
|
||||
"^isee,.*":
|
||||
description: ISEE 2007 S.L.
|
||||
"^isil,.*":
|
||||
|
21
MAINTAINERS
21
MAINTAINERS
@ -10166,6 +10166,13 @@ L: linux-iio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/iio/pressure/dps310.c
|
||||
|
||||
INFINEON PEB2466 ASoC CODEC
|
||||
M: Herve Codina <herve.codina@bootlin.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/infineon,peb2466.yaml
|
||||
F: sound/soc/codecs/peb2466.c
|
||||
|
||||
INFINIBAND SUBSYSTEM
|
||||
M: Jason Gunthorpe <jgg@nvidia.com>
|
||||
M: Leon Romanovsky <leonro@nvidia.com>
|
||||
@ -10927,6 +10934,13 @@ M: David Sterba <dsterba@suse.com>
|
||||
S: Odd Fixes
|
||||
F: drivers/tty/ipwireless/
|
||||
|
||||
IRON DEVICE AUDIO CODEC DRIVERS
|
||||
M: Kiseok Jo <kiseok.jo@irondevice.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/irondevice,*
|
||||
F: sound/soc/codecs/sma*
|
||||
|
||||
IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
|
||||
M: Marc Zyngier <maz@kernel.org>
|
||||
S: Maintained
|
||||
@ -17803,6 +17817,13 @@ F: Documentation/devicetree/bindings/net/renesas,*.yaml
|
||||
F: drivers/net/ethernet/renesas/
|
||||
F: include/linux/sh_eth.h
|
||||
|
||||
RENESAS IDT821034 ASoC CODEC
|
||||
M: Herve Codina <herve.codina@bootlin.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/renesas,idt821034.yaml
|
||||
F: sound/soc/codecs/idt821034.c
|
||||
|
||||
RENESAS R-CAR GYROADC DRIVER
|
||||
M: Marek Vasut <marek.vasut@gmail.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
|
@ -469,7 +469,7 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
|
||||
}
|
||||
|
||||
/* Inform slave about the impending port prepare */
|
||||
sdw_do_port_prep(s_rt, prep_ch, SDW_OPS_PORT_PRE_PREP);
|
||||
sdw_do_port_prep(s_rt, prep_ch, prep ? SDW_OPS_PORT_PRE_PREP : SDW_OPS_PORT_PRE_DEPREP);
|
||||
|
||||
/* Prepare Slave port implementing CP_SM */
|
||||
if (!dpn_prop->simple_ch_prep_sm) {
|
||||
@ -501,7 +501,7 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
|
||||
}
|
||||
|
||||
/* Inform slaves about ports prepared */
|
||||
sdw_do_port_prep(s_rt, prep_ch, SDW_OPS_PORT_POST_PREP);
|
||||
sdw_do_port_prep(s_rt, prep_ch, prep ? SDW_OPS_PORT_POST_PREP : SDW_OPS_PORT_POST_DEPREP);
|
||||
|
||||
/* Disable interrupt after Port de-prepare */
|
||||
if (!prep && intr)
|
||||
|
@ -1,20 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
|
||||
*/
|
||||
|
||||
#ifndef __MSP_H
|
||||
#define __MSP_H
|
||||
|
||||
#include <linux/platform_data/dma-ste-dma40.h>
|
||||
|
||||
/* Platform data structure for a MSP I2S-device */
|
||||
struct msp_i2s_platform_data {
|
||||
int id;
|
||||
struct stedma40_chan_cfg *msp_i2s_dma_rx;
|
||||
struct stedma40_chan_cfg *msp_i2s_dma_tx;
|
||||
};
|
||||
|
||||
#endif
|
@ -566,13 +566,15 @@ struct sdw_prepare_ch {
|
||||
* enum sdw_port_prep_ops: Prepare operations for Data Port
|
||||
*
|
||||
* @SDW_OPS_PORT_PRE_PREP: Pre prepare operation for the Port
|
||||
* @SDW_OPS_PORT_PREP: Prepare operation for the Port
|
||||
* @SDW_OPS_PORT_PRE_DEPREP: Pre deprepare operation for the Port
|
||||
* @SDW_OPS_PORT_POST_PREP: Post prepare operation for the Port
|
||||
* @SDW_OPS_PORT_POST_DEPREP: Post deprepare operation for the Port
|
||||
*/
|
||||
enum sdw_port_prep_ops {
|
||||
SDW_OPS_PORT_PRE_PREP = 0,
|
||||
SDW_OPS_PORT_PREP = 1,
|
||||
SDW_OPS_PORT_POST_PREP = 2,
|
||||
SDW_OPS_PORT_PRE_DEPREP,
|
||||
SDW_OPS_PORT_POST_PREP,
|
||||
SDW_OPS_PORT_POST_DEPREP,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -126,24 +126,24 @@
|
||||
#define ACP_PAD_PULLDOWN_CTRL 0x0001448
|
||||
#define ACP_PAD_DRIVE_STRENGTH_CTRL 0x000144C
|
||||
#define ACP_PAD_SCHMEN_CTRL 0x0001450
|
||||
#define ACP_SW_PAD_KEEPER_EN 0x0001454
|
||||
#define ACP_SW_WAKE_EN 0x0001458
|
||||
#define ACP_SW0_PAD_KEEPER_EN 0x0001454
|
||||
#define ACP_SW0_WAKE_EN 0x0001458
|
||||
#define ACP_I2S_WAKE_EN 0x000145C
|
||||
#define ACP_SW1_WAKE_EN 0x0001460
|
||||
|
||||
#define ACP_SW_I2S_ERROR_REASON 0x00018B4
|
||||
#define ACP_SW_POS_TRACK_I2S_TX_CTRL 0x00018B8
|
||||
#define ACP_SW_I2S_TX_DMA_POS 0x00018BC
|
||||
#define ACP_SW_POS_TRACK_BT_TX_CTRL 0x00018C0
|
||||
#define ACP_SW_BT_TX_DMA_POS 0x00018C4
|
||||
#define ACP_SW_POS_TRACK_HS_TX_CTRL 0x00018C8
|
||||
#define ACP_SW_HS_TX_DMA_POS 0x00018CC
|
||||
#define ACP_SW_POS_TRACK_I2S_RX_CTRL 0x00018D0
|
||||
#define ACP_SW_I2S_RX_DMA_POS 0x00018D4
|
||||
#define ACP_SW_POS_TRACK_BT_RX_CTRL 0x00018D8
|
||||
#define ACP_SW_BT_RX_DMA_POS 0x00018DC
|
||||
#define ACP_SW_POS_TRACK_HS_RX_CTRL 0x00018E0
|
||||
#define ACP_SW_HS_RX_DMA_POS 0x00018E4
|
||||
#define ACP_SW0_I2S_ERROR_REASON 0x00018B4
|
||||
#define ACP_SW0_POS_TRACK_AUDIO0_TX_CTRL 0x00018B8
|
||||
#define ACP_SW0_AUDIO0_TX_DMA_POS 0x00018BC
|
||||
#define ACP_SW0_POS_TRACK_AUDIO1_TX_CTRL 0x00018C0
|
||||
#define ACP_SW0_AUDIO1_TX_DMA_POS 0x00018C4
|
||||
#define ACP_SW0_POS_TRACK_AUDIO2_TX_CTRL 0x00018C8
|
||||
#define ACP_SW0_AUDIO2_TX_DMA_POS 0x00018CC
|
||||
#define ACP_SW0_POS_TRACK_AUDIO0_RX_CTRL 0x00018D0
|
||||
#define ACP_SW0_AUDIO0_DMA_POS 0x00018D4
|
||||
#define ACP_SW0_POS_TRACK_AUDIO1_RX_CTRL 0x00018D8
|
||||
#define ACP_SW0_AUDIO1_RX_DMA_POS 0x00018DC
|
||||
#define ACP_SW0_POS_TRACK_AUDIO2_RX_CTRL 0x00018E0
|
||||
#define ACP_SW0_AUDIO2_RX_DMA_POS 0x00018E4
|
||||
#define ACP_ERROR_INTR_MASK1 0X0001974
|
||||
#define ACP_ERROR_INTR_MASK2 0X0001978
|
||||
#define ACP_ERROR_INTR_MASK3 0X000197C
|
||||
@ -155,98 +155,80 @@
|
||||
#define ACP_EXTERNAL_INTR_STAT 0x0001A0C
|
||||
#define ACP_EXTERNAL_INTR_STAT1 0x0001A10
|
||||
#define ACP_ERROR_STATUS 0x0001A4C
|
||||
#define ACP_P1_SW_I2S_ERROR_REASON 0x0001A50
|
||||
#define ACP_P1_SW_POS_TRACK_I2S_TX_CTRL 0x0001A6C
|
||||
#define ACP_P1_SW_I2S_TX_DMA_POS 0x0001A70
|
||||
#define ACP_P1_SW_POS_TRACK_I2S_RX_CTRL 0x0001A74
|
||||
#define ACP_P1_SW_I2S_RX_DMA_POS 0x0001A78
|
||||
#define ACP_SW1_I2S_ERROR_REASON 0x0001A50
|
||||
#define ACP_SW1_POS_TRACK_AUDIO0_TX_CTRL 0x0001A6C
|
||||
#define ACP_SW1_AUDIO0_TX_DMA_POS 0x0001A70
|
||||
#define ACP_SW1_POS_TRACK_AUDIO0_RX_CTRL 0x0001A74
|
||||
#define ACP_SW1_AUDIO0_RX_DMA_POS 0x0001A78
|
||||
#define ACP_P1_DMIC_I2S_GPIO_INTR_CTRL 0x0001A7C
|
||||
#define ACP_P1_DMIC_I2S_GPIO_INTR_STATUS 0x0001A80
|
||||
#define ACP_SCRATCH_REG_BASE_ADDR 0x0001A84
|
||||
#define ACP_P1_SW_POS_TRACK_BT_TX_CTRL 0x0001A88
|
||||
#define ACP_P1_SW_BT_TX_DMA_POS 0x0001A8C
|
||||
#define ACP_P1_SW_POS_TRACK_HS_TX_CTRL 0x0001A90
|
||||
#define ACP_P1_SW_HS_TX_DMA_POS 0x0001A94
|
||||
#define ACP_P1_SW_POS_TRACK_BT_RX_CTRL 0x0001A98
|
||||
#define ACP_P1_SW_BT_RX_DMA_POS 0x0001A9C
|
||||
#define ACP_P1_SW_POS_TRACK_HS_RX_CTRL 0x0001AA0
|
||||
#define ACP_P1_SW_HS_RX_DMA_POS 0x0001AA4
|
||||
#define ACP_SW1_POS_TRACK_AUDIO1_TX_CTRL 0x0001A88
|
||||
#define ACP_SW1_AUDIO1_TX_DMA_POS 0x0001A8C
|
||||
#define ACP_SW1_POS_TRACK_AUDIO2_TX_CTRL 0x0001A90
|
||||
#define ACP_SW1_AUDIO2_TX_DMA_POS 0x0001A94
|
||||
#define ACP_SW1_POS_TRACK_AUDIO1_RX_CTRL 0x0001A98
|
||||
#define ACP_SW1_AUDIO1_RX_DMA_POS 0x0001A9C
|
||||
#define ACP_SW1_POS_TRACK_AUDIO2_RX_CTRL 0x0001AA0
|
||||
#define ACP_SW1_AUDIO2_RX_DMA_POS 0x0001AA4
|
||||
#define ACP_ERROR_INTR_MASK4 0X0001AEC
|
||||
#define ACP_ERROR_INTR_MASK5 0X0001AF0
|
||||
|
||||
/* Registers from ACP_AUDIO_BUFFERS block */
|
||||
#define ACP_I2S_RX_RINGBUFADDR 0x0002000
|
||||
#define ACP_I2S_RX_RINGBUFSIZE 0x0002004
|
||||
#define ACP_I2S_RX_LINKPOSITIONCNTR 0x0002008
|
||||
#define ACP_I2S_RX_FIFOADDR 0x000200C
|
||||
#define ACP_I2S_RX_FIFOSIZE 0x0002010
|
||||
#define ACP_I2S_RX_DMA_SIZE 0x0002014
|
||||
#define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x0002018
|
||||
#define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW 0x000201C
|
||||
#define ACP_I2S_RX_INTR_WATERMARK_SIZE 0x0002020
|
||||
#define ACP_I2S_TX_RINGBUFADDR 0x0002024
|
||||
#define ACP_I2S_TX_RINGBUFSIZE 0x0002028
|
||||
#define ACP_I2S_TX_LINKPOSITIONCNTR 0x000202C
|
||||
#define ACP_I2S_TX_FIFOADDR 0x0002030
|
||||
#define ACP_I2S_TX_FIFOSIZE 0x0002034
|
||||
#define ACP_I2S_TX_DMA_SIZE 0x0002038
|
||||
#define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x000203C
|
||||
#define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW 0x0002040
|
||||
#define ACP_I2S_TX_INTR_WATERMARK_SIZE 0x0002044
|
||||
#define ACP_BT_RX_RINGBUFADDR 0x0002048
|
||||
#define ACP_BT_RX_RINGBUFSIZE 0x000204C
|
||||
#define ACP_BT_RX_LINKPOSITIONCNTR 0x0002050
|
||||
#define ACP_BT_RX_FIFOADDR 0x0002054
|
||||
#define ACP_BT_RX_FIFOSIZE 0x0002058
|
||||
#define ACP_BT_RX_DMA_SIZE 0x000205C
|
||||
#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH 0x0002060
|
||||
#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW 0x0002064
|
||||
#define ACP_BT_RX_INTR_WATERMARK_SIZE 0x0002068
|
||||
#define ACP_BT_TX_RINGBUFADDR 0x000206C
|
||||
#define ACP_BT_TX_RINGBUFSIZE 0x0002070
|
||||
#define ACP_BT_TX_LINKPOSITIONCNTR 0x0002074
|
||||
#define ACP_BT_TX_FIFOADDR 0x0002078
|
||||
#define ACP_BT_TX_FIFOSIZE 0x000207C
|
||||
#define ACP_BT_TX_DMA_SIZE 0x0002080
|
||||
#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x0002084
|
||||
#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x0002088
|
||||
#define ACP_BT_TX_INTR_WATERMARK_SIZE 0x000208C
|
||||
#define ACP_HS_RX_RINGBUFADDR 0x0002090
|
||||
#define ACP_HS_RX_RINGBUFSIZE 0x0002094
|
||||
#define ACP_HS_RX_LINKPOSITIONCNTR 0x0002098
|
||||
#define ACP_HS_RX_FIFOADDR 0x000209C
|
||||
#define ACP_HS_RX_FIFOSIZE 0x00020A0
|
||||
#define ACP_HS_RX_DMA_SIZE 0x00020A4
|
||||
#define ACP_HS_RX_LINEARPOSITIONCNTR_HIGH 0x00020A8
|
||||
#define ACP_HS_RX_LINEARPOSITIONCNTR_LOW 0x00020AC
|
||||
#define ACP_HS_RX_INTR_WATERMARK_SIZE 0x00020B0
|
||||
#define ACP_HS_TX_RINGBUFADDR 0x00020B4
|
||||
#define ACP_HS_TX_RINGBUFSIZE 0x00020B8
|
||||
#define ACP_HS_TX_LINKPOSITIONCNTR 0x00020BC
|
||||
#define ACP_HS_TX_FIFOADDR 0x00020C0
|
||||
#define ACP_HS_TX_FIFOSIZE 0x00020C4
|
||||
#define ACP_HS_TX_DMA_SIZE 0x00020C8
|
||||
#define ACP_HS_TX_LINEARPOSITIONCNTR_HIGH 0x00020CC
|
||||
#define ACP_HS_TX_LINEARPOSITIONCNTR_LOW 0x00020D0
|
||||
#define ACP_HS_TX_INTR_WATERMARK_SIZE 0x00020D4
|
||||
#define ACP_AUDIO_RX_RINGBUFADDR ACP_I2S_RX_RINGBUFADDR
|
||||
#define ACP_AUDIO_RX_RINGBUFSIZE ACP_I2S_RX_RINGBUFSIZE
|
||||
#define ACP_AUDIO_RX_LINKPOSITIONCNTR ACP_I2S_RX_LINKPOSITIONCNTR
|
||||
#define ACP_AUDIO_RX_FIFOADDR ACP_I2S_RX_FIFOADDR
|
||||
#define ACP_AUDIO_RX_FIFOSIZE ACP_I2S_RX_FIFOSIZE
|
||||
#define ACP_AUDIO_RX_DMA_SIZE ACP_I2S_RX_DMA_SIZE
|
||||
#define ACP_AUDIO_RX_LINEARPOSITIONCNTR_HIGH ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH
|
||||
#define ACP_AUDIO_RX_LINEARPOSITIONCNTR_LOW ACP_I2S_RX_LINEARPOSITIONCNTR_LOW
|
||||
#define ACP_AUDIO_RX_INTR_WATERMARK_SIZE ACP_I2S_RX_INTR_WATERMARK_SIZE
|
||||
#define ACP_AUDIO_TX_RINGBUFADDR ACP_I2S_TX_RINGBUFADDR
|
||||
#define ACP_AUDIO_TX_RINGBUFSIZE ACP_I2S_TX_RINGBUFSIZE
|
||||
#define ACP_AUDIO_TX_LINKPOSITIONCNTR ACP_I2S_TX_LINKPOSITIONCNTR
|
||||
#define ACP_AUDIO_TX_FIFOADDR ACP_I2S_TX_FIFOADDR
|
||||
#define ACP_AUDIO_TX_FIFOSIZE ACP_I2S_TX_FIFOSIZE
|
||||
#define ACP_AUDIO_TX_DMA_SIZE ACP_I2S_TX_DMA_SIZE
|
||||
#define ACP_AUDIO_TX_LINEARPOSITIONCNTR_HIGH ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH
|
||||
#define ACP_AUDIO_TX_LINEARPOSITIONCNTR_LOW ACP_I2S_TX_LINEARPOSITIONCNTR_LOW
|
||||
#define ACP_AUDIO_TX_INTR_WATERMARK_SIZE ACP_I2S_TX_INTR_WATERMARK_SIZE
|
||||
#define ACP_AUDIO0_RX_RINGBUFADDR 0x0002000
|
||||
#define ACP_AUDIO0_RX_RINGBUFSIZE 0x0002004
|
||||
#define ACP_AUDIO0_RX_LINKPOSITIONCNTR 0x0002008
|
||||
#define ACP_AUDIO0_RX_FIFOADDR 0x000200C
|
||||
#define ACP_AUDIO0_RX_FIFOSIZE 0x0002010
|
||||
#define ACP_AUDIO0_RX_DMA_SIZE 0x0002014
|
||||
#define ACP_AUDIO0_RX_LINEARPOSITIONCNTR_HIGH 0x0002018
|
||||
#define ACP_AUDIO0_RX_LINEARPOSITIONCNTR_LOW 0x000201C
|
||||
#define ACP_AUDIO0_RX_INTR_WATERMARK_SIZE 0x0002020
|
||||
#define ACP_AUDIO0_TX_RINGBUFADDR 0x0002024
|
||||
#define ACP_AUDIO0_TX_RINGBUFSIZE 0x0002028
|
||||
#define ACP_AUDIO0_TX_LINKPOSITIONCNTR 0x000202C
|
||||
#define ACP_AUDIO0_TX_FIFOADDR 0x0002030
|
||||
#define ACP_AUDIO0_TX_FIFOSIZE 0x0002034
|
||||
#define ACP_AUDIO0_TX_DMA_SIZE 0x0002038
|
||||
#define ACP_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH 0x000203C
|
||||
#define ACP_AUDIO0_TX_LINEARPOSITIONCNTR_LOW 0x0002040
|
||||
#define ACP_AUDIO0_TX_INTR_WATERMARK_SIZE 0x0002044
|
||||
#define ACP_AUDIO1_RX_RINGBUFADDR 0x0002048
|
||||
#define ACP_AUDIO1_RX_RINGBUFSIZE 0x000204C
|
||||
#define ACP_AUDIO1_RX_LINKPOSITIONCNTR 0x0002050
|
||||
#define ACP_AUDIO1_RX_FIFOADDR 0x0002054
|
||||
#define ACP_AUDIO1_RX_FIFOSIZE 0x0002058
|
||||
#define ACP_AUDIO1_RX_DMA_SIZE 0x000205C
|
||||
#define ACP_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH 0x0002060
|
||||
#define ACP_AUDIO1_RX_LINEARPOSITIONCNTR_LOW 0x0002064
|
||||
#define ACP_AUDIO1_RX_INTR_WATERMARK_SIZE 0x0002068
|
||||
#define ACP_AUDIO1_TX_RINGBUFADDR 0x000206C
|
||||
#define ACP_AUDIO1_TX_RINGBUFSIZE 0x0002070
|
||||
#define ACP_AUDIO1_TX_LINKPOSITIONCNTR 0x0002074
|
||||
#define ACP_AUDIO1_TX_FIFOADDR 0x0002078
|
||||
#define ACP_AUDIO1_TX_FIFOSIZE 0x000207C
|
||||
#define ACP_AUDIO1_TX_DMA_SIZE 0x0002080
|
||||
#define ACP_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH 0x0002084
|
||||
#define ACP_AUDIO1_TX_LINEARPOSITIONCNTR_LOW 0x0002088
|
||||
#define ACP_AUDIO1_TX_INTR_WATERMARK_SIZE 0x000208C
|
||||
#define ACP_AUDIO2_RX_RINGBUFADDR 0x0002090
|
||||
#define ACP_AUDIO2_RX_RINGBUFSIZE 0x0002094
|
||||
#define ACP_AUDIO2_RX_LINKPOSITIONCNTR 0x0002098
|
||||
#define ACP_AUDIO2_RX_FIFOADDR 0x000209C
|
||||
#define ACP_AUDIO2_RX_FIFOSIZE 0x00020A0
|
||||
#define ACP_AUDIO2_RX_DMA_SIZE 0x00020A4
|
||||
#define ACP_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH 0x00020A8
|
||||
#define ACP_AUDIO2_RX_LINEARPOSITIONCNTR_LOW 0x00020AC
|
||||
#define ACP_AUDIO2_RX_INTR_WATERMARK_SIZE 0x00020B0
|
||||
#define ACP_AUDIO2_TX_RINGBUFADDR 0x00020B4
|
||||
#define ACP_AUDIO2_TX_RINGBUFSIZE 0x00020B8
|
||||
#define ACP_AUDIO2_TX_LINKPOSITIONCNTR 0x00020BC
|
||||
#define ACP_AUDIO2_TX_FIFOADDR 0x00020C0
|
||||
#define ACP_AUDIO2_TX_FIFOSIZE 0x00020C4
|
||||
#define ACP_AUDIO2_TX_DMA_SIZE 0x00020C8
|
||||
#define ACP_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH 0x00020CC
|
||||
#define ACP_AUDIO2_TX_LINEARPOSITIONCNTR_LOW 0x00020D0
|
||||
#define ACP_AUDIO2_TX_INTR_WATERMARK_SIZE 0x00020D4
|
||||
|
||||
/* Registers from ACP_I2S_TDM block */
|
||||
#define ACP_I2STDM_IER 0x0002400
|
||||
@ -292,367 +274,222 @@
|
||||
#define ACP_WOV_ERROR_STATUS_REGISTER 0x0002C68
|
||||
#define ACP_PDM_CLKDIV 0x0002C6C
|
||||
|
||||
/* Registers from ACP_SW_SWCLK block */
|
||||
#define ACP_SW_EN 0x0003000
|
||||
#define ACP_SW_EN_STATUS 0x0003004
|
||||
#define ACP_SW_FRAMESIZE 0x0003008
|
||||
#define ACP_SW_SSP_COUNTER 0x000300C
|
||||
#define ACP_SW_AUDIO_TX_EN 0x0003010
|
||||
#define ACP_SW_AUDIO_TX_EN_STATUS 0x0003014
|
||||
#define ACP_SW_AUDIO_TX_FRAME_FORMAT 0x0003018
|
||||
#define ACP_SW_AUDIO_TX_SAMPLEINTERVAL 0x000301C
|
||||
#define ACP_SW_AUDIO_TX_HCTRL_DP0 0x0003020
|
||||
#define ACP_SW_AUDIO_TX_HCTRL_DP1 0x0003024
|
||||
#define ACP_SW_AUDIO_TX_HCTRL_DP2 0x0003028
|
||||
#define ACP_SW_AUDIO_TX_HCTRL_DP3 0x000302C
|
||||
#define ACP_SW_AUDIO_TX_OFFSET_DP0 0x0003030
|
||||
#define ACP_SW_AUDIO_TX_OFFSET_DP1 0x0003034
|
||||
#define ACP_SW_AUDIO_TX_OFFSET_DP2 0x0003038
|
||||
#define ACP_SW_AUDIO_TX_OFFSET_DP3 0x000303C
|
||||
#define ACP_SW_AUDIO_TX_CHANNEL_ENABLE_DP0 0x0003040
|
||||
#define ACP_SW_AUDIO_TX_CHANNEL_ENABLE_DP1 0x0003044
|
||||
#define ACP_SW_AUDIO_TX_CHANNEL_ENABLE_DP2 0x0003048
|
||||
#define ACP_SW_AUDIO_TX_CHANNEL_ENABLE_DP3 0x000304C
|
||||
#define ACP_SW_BT_TX_EN 0x0003050
|
||||
#define ACP_SW_BT_TX_EN_STATUS 0x0003054
|
||||
#define ACP_SW_BT_TX_FRAME_FORMAT 0x0003058
|
||||
#define ACP_SW_BT_TX_SAMPLEINTERVAL 0x000305C
|
||||
#define ACP_SW_BT_TX_HCTRL 0x0003060
|
||||
#define ACP_SW_BT_TX_OFFSET 0x0003064
|
||||
#define ACP_SW_BT_TX_CHANNEL_ENABLE_DP0 0x0003068
|
||||
#define ACP_SW_HEADSET_TX_EN 0x000306C
|
||||
#define ACP_SW_HEADSET_TX_EN_STATUS 0x0003070
|
||||
#define ACP_SW_HEADSET_TX_FRAME_FORMAT 0x0003074
|
||||
#define ACP_SW_HEADSET_TX_SAMPLEINTERVAL 0x0003078
|
||||
#define ACP_SW_HEADSET_TX_HCTRL 0x000307C
|
||||
#define ACP_SW_HEADSET_TX_OFFSET 0x0003080
|
||||
#define ACP_SW_HEADSET_TX_CHANNEL_ENABLE_DP0 0x0003084
|
||||
#define ACP_SW_AUDIO_RX_EN 0x0003088
|
||||
#define ACP_SW_AUDIO_RX_EN_STATUS 0x000308C
|
||||
#define ACP_SW_AUDIO_RX_FRAME_FORMAT 0x0003090
|
||||
#define ACP_SW_AUDIO_RX_SAMPLEINTERVAL 0x0003094
|
||||
#define ACP_SW_AUDIO_RX_HCTRL_DP0 0x0003098
|
||||
#define ACP_SW_AUDIO_RX_HCTRL_DP1 0x000309C
|
||||
#define ACP_SW_AUDIO_RX_HCTRL_DP2 0x0003100
|
||||
#define ACP_SW_AUDIO_RX_HCTRL_DP3 0x0003104
|
||||
#define ACP_SW_AUDIO_RX_OFFSET_DP0 0x0003108
|
||||
#define ACP_SW_AUDIO_RX_OFFSET_DP1 0x000310C
|
||||
#define ACP_SW_AUDIO_RX_OFFSET_DP2 0x0003110
|
||||
#define ACP_SW_AUDIO_RX_OFFSET_DP3 0x0003114
|
||||
#define ACP_SW_AUDIO_RX_CHANNEL_ENABLE_DP0 0x0003118
|
||||
#define ACP_SW_AUDIO_RX_CHANNEL_ENABLE_DP1 0x000311C
|
||||
#define ACP_SW_AUDIO_RX_CHANNEL_ENABLE_DP2 0x0003120
|
||||
#define ACP_SW_AUDIO_RX_CHANNEL_ENABLE_DP3 0x0003124
|
||||
#define ACP_SW_BT_RX_EN 0x0003128
|
||||
#define ACP_SW_BT_RX_EN_STATUS 0x000312C
|
||||
#define ACP_SW_BT_RX_FRAME_FORMAT 0x0003130
|
||||
#define ACP_SW_BT_RX_SAMPLEINTERVAL 0x0003134
|
||||
#define ACP_SW_BT_RX_HCTRL 0x0003138
|
||||
#define ACP_SW_BT_RX_OFFSET 0x000313C
|
||||
#define ACP_SW_BT_RX_CHANNEL_ENABLE_DP0 0x0003140
|
||||
#define ACP_SW_HEADSET_RX_EN 0x0003144
|
||||
#define ACP_SW_HEADSET_RX_EN_STATUS 0x0003148
|
||||
#define ACP_SW_HEADSET_RX_FRAME_FORMAT 0x000314C
|
||||
#define ACP_SW_HEADSET_RX_SAMPLEINTERVAL 0x0003150
|
||||
#define ACP_SW_HEADSET_RX_HCTRL 0x0003154
|
||||
#define ACP_SW_HEADSET_RX_OFFSET 0x0003158
|
||||
#define ACP_SW_HEADSET_RX_CHANNEL_ENABLE_DP0 0x000315C
|
||||
#define ACP_SW_BPT_PORT_EN 0x0003160
|
||||
#define ACP_SW_BPT_PORT_EN_STATUS 0x0003164
|
||||
#define ACP_SW_BPT_PORT_FRAME_FORMAT 0x0003168
|
||||
#define ACP_SW_BPT_PORT_SAMPLEINTERVAL 0x000316C
|
||||
#define ACP_SW_BPT_PORT_HCTRL 0x0003170
|
||||
#define ACP_SW_BPT_PORT_OFFSET 0x0003174
|
||||
#define ACP_SW_BPT_PORT_CHANNEL_ENABLE 0x0003178
|
||||
#define ACP_SW_BPT_PORT_FIRST_BYTE_ADDR 0x000317C
|
||||
#define ACP_SW_CLK_RESUME_CTRL 0x0003180
|
||||
#define ACP_SW_CLK_RESUME_DELAY_CNTR 0x0003184
|
||||
#define ACP_SW_BUS_RESET_CTRL 0x0003188
|
||||
#define ACP_SW_PRBS_ERR_STATUS 0x000318C
|
||||
#define SW_IMM_CMD_UPPER_WORD 0x0003230
|
||||
#define SW_IMM_CMD_LOWER_QWORD 0x0003234
|
||||
#define SW_IMM_RESP_UPPER_WORD 0x0003238
|
||||
#define SW_IMM_RESP_LOWER_QWORD 0x000323C
|
||||
#define SW_IMM_CMD_STS 0x0003240
|
||||
#define SW_BRA_BASE_ADDRESS 0x0003244
|
||||
#define SW_BRA_TRANSFER_SIZE 0x0003248
|
||||
#define SW_BRA_DMA_BUSY 0x000324C
|
||||
#define SW_BRA_RESP 0x0003250
|
||||
#define SW_BRA_RESP_FRAME_ADDR 0x0003254
|
||||
#define SW_BRA_CURRENT_TRANSFER_SIZE 0x0003258
|
||||
#define SW_STATE_CHANGE_STATUS_0TO7 0x000325C
|
||||
#define SW_STATE_CHANGE_STATUS_8TO11 0x0003260
|
||||
#define SW_STATE_CHANGE_STATUS_MASK_0TO7 0x0003264
|
||||
#define SW_STATE_CHANGE_STATUS_MASK_8TO11 0x0003268
|
||||
#define SW_CLK_FREQUENCY_CTRL 0x000326C
|
||||
#define SW_ERROR_INTR_MASK 0x0003270
|
||||
#define SW_PHY_TEST_MODE_DATA_OFF 0x0003274
|
||||
/* Registers from ACP_SW0_SWCLK block */
|
||||
#define ACP_SW0_EN 0x0003000
|
||||
#define ACP_SW0_EN_STATUS 0x0003004
|
||||
#define ACP_SW0_FRAMESIZE 0x0003008
|
||||
#define ACP_SW0_SSP_COUNTER 0x000300C
|
||||
#define ACP_SW0_AUDIO0_TX_EN 0x0003010
|
||||
#define ACP_SW0_AUDIO0_TX_EN_STATUS 0x0003014
|
||||
#define ACP_SW0_AUDIO0_TX_FRAME_FORMAT 0x0003018
|
||||
#define ACP_SW0_AUDIO0_TX_SAMPLEINTERVAL 0x000301C
|
||||
#define ACP_SW0_AUDIO0_TX_HCTRL_DP0 0x0003020
|
||||
#define ACP_SW0_AUDIO0_TX_HCTRL_DP1 0x0003024
|
||||
#define ACP_SW0_AUDIO0_TX_HCTRL_DP2 0x0003028
|
||||
#define ACP_SW0_AUDIO0_TX_HCTRL_DP3 0x000302C
|
||||
#define ACP_SW0_AUDIO0_TX_OFFSET_DP0 0x0003030
|
||||
#define ACP_SW0_AUDIO0_TX_OFFSET_DP1 0x0003034
|
||||
#define ACP_SW0_AUDIO0_TX_OFFSET_DP2 0x0003038
|
||||
#define ACP_SW0_AUDIO0_TX_OFFSET_DP3 0x000303C
|
||||
#define ACP_SW0_AUDIO0_TX_CHANNEL_ENABLE_DP0 0x0003040
|
||||
#define ACP_SW0_AUDIO0_TX_CHANNEL_ENABLE_DP1 0x0003044
|
||||
#define ACP_SW0_AUDIO0_TX_CHANNEL_ENABLE_DP2 0x0003048
|
||||
#define ACP_SW0_AUDIO0_TX_CHANNEL_ENABLE_DP3 0x000304C
|
||||
#define ACP_SW0_AUDIO1_TX_EN 0x0003050
|
||||
#define ACP_SW0_AUDIO1_TX_EN_STATUS 0x0003054
|
||||
#define ACP_SW0_AUDIO1_TX_FRAME_FORMAT 0x0003058
|
||||
#define ACP_SW0_AUDIO1_TX_SAMPLEINTERVAL 0x000305C
|
||||
#define ACP_SW0_AUDIO1_TX_HCTRL 0x0003060
|
||||
#define ACP_SW0_AUDIO1_TX_OFFSET 0x0003064
|
||||
#define ACP_SW0_AUDIO1_TX_CHANNEL_ENABLE_DP0 0x0003068
|
||||
#define ACP_SW0_AUDIO2_TX_EN 0x000306C
|
||||
#define ACP_SW0_AUDIO2_TX_EN_STATUS 0x0003070
|
||||
#define ACP_SW0_AUDIO2_TX_FRAME_FORMAT 0x0003074
|
||||
#define ACP_SW0_AUDIO2_TX_SAMPLEINTERVAL 0x0003078
|
||||
#define ACP_SW0_AUDIO2_TX_HCTRL 0x000307C
|
||||
#define ACP_SW0_AUDIO2_TX_OFFSET 0x0003080
|
||||
#define ACP_SW0_AUDIO2_TX_CHANNEL_ENABLE_DP0 0x0003084
|
||||
#define ACP_SW0_AUDIO0_RX_EN 0x0003088
|
||||
#define ACP_SW0_AUDIO0_RX_EN_STATUS 0x000308C
|
||||
#define ACP_SW0_AUDIO0_RX_FRAME_FORMAT 0x0003090
|
||||
#define ACP_SW0_AUDIO0_RX_SAMPLEINTERVAL 0x0003094
|
||||
#define ACP_SW0_AUDIO0_RX_HCTRL_DP0 0x0003098
|
||||
#define ACP_SW0_AUDIO0_RX_HCTRL_DP1 0x000309C
|
||||
#define ACP_SW0_AUDIO0_RX_HCTRL_DP2 0x0003100
|
||||
#define ACP_SW0_AUDIO0_RX_HCTRL_DP3 0x0003104
|
||||
#define ACP_SW0_AUDIO0_RX_OFFSET_DP0 0x0003108
|
||||
#define ACP_SW0_AUDIO0_RX_OFFSET_DP1 0x000310C
|
||||
#define ACP_SW0_AUDIO0_RX_OFFSET_DP2 0x0003110
|
||||
#define ACP_SW0_AUDIO0_RX_OFFSET_DP3 0x0003114
|
||||
#define ACP_SW0_AUDIO0_RX_CHANNEL_ENABLE_DP0 0x0003118
|
||||
#define ACP_SW0_AUDIO0_RX_CHANNEL_ENABLE_DP1 0x000311C
|
||||
#define ACP_SW0_AUDIO0_RX_CHANNEL_ENABLE_DP2 0x0003120
|
||||
#define ACP_SW0_AUDIO0_RX_CHANNEL_ENABLE_DP3 0x0003124
|
||||
#define ACP_SW0_AUDIO1_RX_EN 0x0003128
|
||||
#define ACP_SW0_AUDIO1_RX_EN_STATUS 0x000312C
|
||||
#define ACP_SW0_AUDIO1_RX_FRAME_FORMAT 0x0003130
|
||||
#define ACP_SW0_AUDIO1_RX_SAMPLEINTERVAL 0x0003134
|
||||
#define ACP_SW0_AUDIO1_RX_HCTRL 0x0003138
|
||||
#define ACP_SW0_AUDIO1_RX_OFFSET 0x000313C
|
||||
#define ACP_SW0_AUDIO1_RX_CHANNEL_ENABLE_DP0 0x0003140
|
||||
#define ACP_SW0_AUDIO2_RX_EN 0x0003144
|
||||
#define ACP_SW0_AUDIO2_RX_EN_STATUS 0x0003148
|
||||
#define ACP_SW0_AUDIO2_RX_FRAME_FORMAT 0x000314C
|
||||
#define ACP_SW0_AUDIO2_RX_SAMPLEINTERVAL 0x0003150
|
||||
#define ACP_SW0_AUDIO2_RX_HCTRL 0x0003154
|
||||
#define ACP_SW0_AUDIO2_RX_OFFSET 0x0003158
|
||||
#define ACP_SW0_AUDIO2_RX_CHANNEL_ENABLE_DP0 0x000315C
|
||||
#define ACP_SW0_BPT_PORT_EN 0x0003160
|
||||
#define ACP_SW0_BPT_PORT_EN_STATUS 0x0003164
|
||||
#define ACP_SW0_BPT_PORT_FRAME_FORMAT 0x0003168
|
||||
#define ACP_SW0_BPT_PORT_SAMPLEINTERVAL 0x000316C
|
||||
#define ACP_SW0_BPT_PORT_HCTRL 0x0003170
|
||||
#define ACP_SW0_BPT_PORT_OFFSET 0x0003174
|
||||
#define ACP_SW0_BPT_PORT_CHANNEL_ENABLE 0x0003178
|
||||
#define ACP_SW0_BPT_PORT_FIRST_BYTE_ADDR 0x000317C
|
||||
#define ACP_SW0_CLK_RESUME_CTRL 0x0003180
|
||||
#define ACP_SW0_CLK_RESUME_DELAY_CNTR 0x0003184
|
||||
#define ACP_SW0_BUS_RESET_CTRL 0x0003188
|
||||
#define ACP_SW0_PRBS_ERR_STATUS 0x000318C
|
||||
#define ACP_SW0_IMM_CMD_UPPER_WORD 0x0003230
|
||||
#define ACP_SW0_IMM_CMD_LOWER_QWORD 0x0003234
|
||||
#define ACP_SW0_IMM_RESP_UPPER_WORD 0x0003238
|
||||
#define ACP_SW0_IMM_RESP_LOWER_QWORD 0x000323C
|
||||
#define ACP_SW0_IMM_CMD_STS 0x0003240
|
||||
#define ACP_SW0_BRA_BASE_ADDRESS 0x0003244
|
||||
#define ACP_SW0_BRA_TRANSFER_SIZE 0x0003248
|
||||
#define ACP_SW0_BRA_DMA_BUSY 0x000324C
|
||||
#define ACP_SW0_BRA_RESP 0x0003250
|
||||
#define ACP_SW0_BRA_RESP_FRAME_ADDR 0x0003254
|
||||
#define ACP_SW0_BRA_CURRENT_TRANSFER_SIZE 0x0003258
|
||||
#define ACP_SW0_STATECHANGE_STATUS_0TO7 0x000325C
|
||||
#define ACP_SW0_STATECHANGE_STATUS_8TO11 0x0003260
|
||||
#define ACP_SW0_STATECHANGE_STATUS_MASK_0TO7 0x0003264
|
||||
#define ACP_SW0_STATECHANGE_STATUS_MASK_8TO11 0x0003268
|
||||
#define ACP_SW0_CLK_FREQUENCY_CTRL 0x000326C
|
||||
#define ACP_SW0_ERROR_INTR_MASK 0x0003270
|
||||
#define ACP_SW0_PHY_TEST_MODE_DATA_OFF 0x0003274
|
||||
|
||||
/* Registers from ACP_P1_AUDIO_BUFFERS block */
|
||||
#define ACP_P1_I2S_RX_RINGBUFADDR 0x0003A00
|
||||
#define ACP_P1_I2S_RX_RINGBUFSIZE 0x0003A04
|
||||
#define ACP_P1_I2S_RX_LINKPOSITIONCNTR 0x0003A08
|
||||
#define ACP_P1_I2S_RX_FIFOADDR 0x0003A0C
|
||||
#define ACP_P1_I2S_RX_FIFOSIZE 0x0003A10
|
||||
#define ACP_P1_I2S_RX_DMA_SIZE 0x0003A14
|
||||
#define ACP_P1_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x0003A18
|
||||
#define ACP_P1_I2S_RX_LINEARPOSITIONCNTR_LOW 0x0003A1C
|
||||
#define ACP_P1_I2S_RX_INTR_WATERMARK_SIZE 0x0003A20
|
||||
#define ACP_P1_I2S_TX_RINGBUFADDR 0x0003A24
|
||||
#define ACP_P1_I2S_TX_RINGBUFSIZE 0x0003A28
|
||||
#define ACP_P1_I2S_TX_LINKPOSITIONCNTR 0x0003A2C
|
||||
#define ACP_P1_I2S_TX_FIFOADDR 0x0003A30
|
||||
#define ACP_P1_I2S_TX_FIFOSIZE 0x0003A34
|
||||
#define ACP_P1_I2S_TX_DMA_SIZE 0x0003A38
|
||||
#define ACP_P1_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x0003A3C
|
||||
#define ACP_P1_I2S_TX_LINEARPOSITIONCNTR_LOW 0x0003A40
|
||||
#define ACP_P1_I2S_TX_INTR_WATERMARK_SIZE 0x0003A44
|
||||
#define ACP_P1_BT_RX_RINGBUFADDR 0x0003A48
|
||||
#define ACP_P1_BT_RX_RINGBUFSIZE 0x0003A4C
|
||||
#define ACP_P1_BT_RX_LINKPOSITIONCNTR 0x0003A50
|
||||
#define ACP_P1_BT_RX_FIFOADDR 0x0003A54
|
||||
#define ACP_P1_BT_RX_FIFOSIZE 0x0003A58
|
||||
#define ACP_P1_BT_RX_DMA_SIZE 0x0003A5C
|
||||
#define ACP_P1_BT_RX_LINEARPOSITIONCNTR_HIGH 0x0003A60
|
||||
#define ACP_P1_BT_RX_LINEARPOSITIONCNTR_LOW 0x0003A64
|
||||
#define ACP_P1_BT_RX_INTR_WATERMARK_SIZE 0x0003A68
|
||||
#define ACP_P1_BT_TX_RINGBUFADDR 0x0003A6C
|
||||
#define ACP_P1_BT_TX_RINGBUFSIZE 0x0003A70
|
||||
#define ACP_P1_BT_TX_LINKPOSITIONCNTR 0x0003A74
|
||||
#define ACP_P1_BT_TX_FIFOADDR 0x0003A78
|
||||
#define ACP_P1_BT_TX_FIFOSIZE 0x0003A7C
|
||||
#define ACP_P1_BT_TX_DMA_SIZE 0x0003A80
|
||||
#define ACP_P1_BT_TX_LINEARPOSITIONCNTR_HIGH 0x0003A84
|
||||
#define ACP_P1_BT_TX_LINEARPOSITIONCNTR_LOW 0x0003A88
|
||||
#define ACP_P1_BT_TX_INTR_WATERMARK_SIZE 0x0003A8C
|
||||
#define ACP_P1_HS_RX_RINGBUFADDR 0x0003A90
|
||||
#define ACP_P1_HS_RX_RINGBUFSIZE 0x0003A94
|
||||
#define ACP_P1_HS_RX_LINKPOSITIONCNTR 0x0003A98
|
||||
#define ACP_P1_HS_RX_FIFOADDR 0x0003A9C
|
||||
#define ACP_P1_HS_RX_FIFOSIZE 0x0003AA0
|
||||
#define ACP_P1_HS_RX_DMA_SIZE 0x0003AA4
|
||||
#define ACP_P1_HS_RX_LINEARPOSITIONCNTR_HIGH 0x0003AA8
|
||||
#define ACP_P1_HS_RX_LINEARPOSITIONCNTR_LOW 0x0003AAC
|
||||
#define ACP_P1_HS_RX_INTR_WATERMARK_SIZE 0x0003AB0
|
||||
#define ACP_P1_HS_TX_RINGBUFADDR 0x0003AB4
|
||||
#define ACP_P1_HS_TX_RINGBUFSIZE 0x0003AB8
|
||||
#define ACP_P1_HS_TX_LINKPOSITIONCNTR 0x0003ABC
|
||||
#define ACP_P1_HS_TX_FIFOADDR 0x0003AC0
|
||||
#define ACP_P1_HS_TX_FIFOSIZE 0x0003AC4
|
||||
#define ACP_P1_HS_TX_DMA_SIZE 0x0003AC8
|
||||
#define ACP_P1_HS_TX_LINEARPOSITIONCNTR_HIGH 0x0003ACC
|
||||
#define ACP_P1_HS_TX_LINEARPOSITIONCNTR_LOW 0x0003AD0
|
||||
#define ACP_P1_HS_TX_INTR_WATERMARK_SIZE 0x0003AD4
|
||||
#define ACP_P1_AUDIO_RX_RINGBUFADDR ACP_P1_I2S_RX_RINGBUFADDR
|
||||
#define ACP_P1_AUDIO_RX_RINGBUFSIZE ACP_P1_I2S_RX_RINGBUFSIZE
|
||||
#define ACP_P1_AUDIO_RX_LINKPOSITIONCNTR ACP_P1_I2S_RX_LINKPOSITIONCNTR
|
||||
#define ACP_P1_AUDIO_RX_FIFOADDR ACP_P1_I2S_RX_FIFOADDR
|
||||
#define ACP_P1_AUDIO_RX_FIFOSIZE ACP_P1_I2S_RX_FIFOSIZE
|
||||
#define ACP_P1_AUDIO_RX_DMA_SIZE ACP_P1_I2S_RX_DMA_SIZE
|
||||
#define ACP_P1_AUDIO_RX_LINEARPOSITIONCNTR_HIGH ACP_P1_I2S_RX_LINEARPOSITIONCNTR_HIGH
|
||||
#define ACP_P1_AUDIO_RX_LINEARPOSITIONCNTR_LOW ACP_P1_I2S_RX_LINEARPOSITIONCNTR_LOW
|
||||
#define ACP_P1_AUDIO_RX_INTR_WATERMARK_SIZE ACP_P1_I2S_RX_INTR_WATERMARK_SIZE
|
||||
#define ACP_P1_AUDIO_TX_RINGBUFADDR ACP_P1_I2S_TX_RINGBUFADDR
|
||||
#define ACP_P1_AUDIO_TX_RINGBUFSIZE ACP_P1_I2S_TX_RINGBUFSIZE
|
||||
#define ACP_P1_AUDIO_TX_LINKPOSITIONCNTR ACP_P1_I2S_TX_LINKPOSITIONCNTR
|
||||
#define ACP_P1_AUDIO_TX_FIFOADDR ACP_P1_I2S_TX_FIFOADDR
|
||||
#define ACP_P1_AUDIO_TX_FIFOSIZE ACP_P1_I2S_TX_FIFOSIZE
|
||||
#define ACP_P1_AUDIO_TX_DMA_SIZE ACP_P1_I2S_TX_DMA_SIZE
|
||||
#define ACP_P1_AUDIO_TX_LINEARPOSITIONCNTR_HIGH ACP_P1_I2S_TX_LINEARPOSITIONCNTR_HIGH
|
||||
#define ACP_P1_AUDIO_TX_LINEARPOSITIONCNTR_LOW ACP_P1_I2S_TX_LINEARPOSITIONCNTR_LOW
|
||||
#define ACP_P1_AUDIO_TX_INTR_WATERMARK_SIZE ACP_P1_I2S_TX_INTR_WATERMARK_SIZE
|
||||
#define ACP_P1_AUDIO0_RX_RINGBUFADDR 0x0003A00
|
||||
#define ACP_P1_AUDIO0_RX_RINGBUFSIZE 0x0003A04
|
||||
#define ACP_P1_AUDIO0_RX_LINKPOSITIONCNTR 0x0003A08
|
||||
#define ACP_P1_AUDIO0_RX_FIFOADDR 0x0003A0C
|
||||
#define ACP_P1_AUDIO0_RX_FIFOSIZE 0x0003A10
|
||||
#define ACP_P1_AUDIO0_RX_DMA_SIZE 0x0003A14
|
||||
#define ACP_P1_AUDIO0_RX_LINEARPOSITIONCNTR_HIGH 0x0003A18
|
||||
#define ACP_P1_AUDIO0_RX_LINEARPOSITIONCNTR_LOW 0x0003A1C
|
||||
#define ACP_P1_AUDIO0_RX_INTR_WATERMARK_SIZE 0x0003A20
|
||||
#define ACP_P1_AUDIO0_TX_RINGBUFADDR 0x0003A24
|
||||
#define ACP_P1_AUDIO0_TX_RINGBUFSIZE 0x0003A28
|
||||
#define ACP_P1_AUDIO0_TX_LINKPOSITIONCNTR 0x0003A2C
|
||||
#define ACP_P1_AUDIO0_TX_FIFOADDR 0x0003A30
|
||||
#define ACP_P1_AUDIO0_TX_FIFOSIZE 0x0003A34
|
||||
#define ACP_P1_AUDIO0_TX_DMA_SIZE 0x0003A38
|
||||
#define ACP_P1_AUDIO0_TX_LINEARPOSITIONCNTR_HIGH 0x0003A3C
|
||||
#define ACP_P1_AUDIO0_TX_LINEARPOSITIONCNTR_LOW 0x0003A40
|
||||
#define ACP_P1_AUDIO0_TX_INTR_WATERMARK_SIZE 0x0003A44
|
||||
#define ACP_P1_AUDIO1_RX_RINGBUFADDR 0x0003A48
|
||||
#define ACP_P1_AUDIO1_RX_RINGBUFSIZE 0x0003A4C
|
||||
#define ACP_P1_AUDIO1_RX_LINKPOSITIONCNTR 0x0003A50
|
||||
#define ACP_P1_AUDIO1_RX_FIFOADDR 0x0003A54
|
||||
#define ACP_P1_AUDIO1_RX_FIFOSIZE 0x0003A58
|
||||
#define ACP_P1_AUDIO1_RX_DMA_SIZE 0x0003A5C
|
||||
#define ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_HIGH 0x0003A60
|
||||
#define ACP_P1_AUDIO1_RX_LINEARPOSITIONCNTR_LOW 0x0003A64
|
||||
#define ACP_P1_AUDIO1_RX_INTR_WATERMARK_SIZE 0x0003A68
|
||||
#define ACP_P1_AUDIO1_TX_RINGBUFADDR 0x0003A6C
|
||||
#define ACP_P1_AUDIO1_TX_RINGBUFSIZE 0x0003A70
|
||||
#define ACP_P1_AUDIO1_TX_LINKPOSITIONCNTR 0x0003A74
|
||||
#define ACP_P1_AUDIO1_TX_FIFOADDR 0x0003A78
|
||||
#define ACP_P1_AUDIO1_TX_FIFOSIZE 0x0003A7C
|
||||
#define ACP_P1_AUDIO1_TX_DMA_SIZE 0x0003A80
|
||||
#define ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_HIGH 0x0003A84
|
||||
#define ACP_P1_AUDIO1_TX_LINEARPOSITIONCNTR_LOW 0x0003A88
|
||||
#define ACP_P1_AUDIO1_TX_INTR_WATERMARK_SIZE 0x0003A8C
|
||||
#define ACP_P1_AUDIO2_RX_RINGBUFADDR 0x0003A90
|
||||
#define ACP_P1_AUDIO2_RX_RINGBUFSIZE 0x0003A94
|
||||
#define ACP_P1_AUDIO2_RX_LINKPOSITIONCNTR 0x0003A98
|
||||
#define ACP_P1_AUDIO2_RX_FIFOADDR 0x0003A9C
|
||||
#define ACP_P1_AUDIO2_RX_FIFOSIZE 0x0003AA0
|
||||
#define ACP_P1_AUDIO2_RX_DMA_SIZE 0x0003AA4
|
||||
#define ACP_P1_AUDIO2_RX_LINEARPOSITIONCNTR_HIGH 0x0003AA8
|
||||
#define ACP_P1_AUDIO2_RX_LINEARPOSITIONCNTR_LOW 0x0003AAC
|
||||
#define ACP_P1_AUDIO2_RX_INTR_WATERMARK_SIZE 0x0003AB0
|
||||
#define ACP_P1_AUDIO2_TX_RINGBUFADDR 0x0003AB4
|
||||
#define ACP_P1_AUDIO2_TX_RINGBUFSIZE 0x0003AB8
|
||||
#define ACP_P1_AUDIO2_TX_LINKPOSITIONCNTR 0x0003ABC
|
||||
#define ACP_P1_AUDIO2_TX_FIFOADDR 0x0003AC0
|
||||
#define ACP_P1_AUDIO2_TX_FIFOSIZE 0x0003AC4
|
||||
#define ACP_P1_AUDIO2_TX_DMA_SIZE 0x0003AC8
|
||||
#define ACP_P1_AUDIO2_TX_LINEARPOSITIONCNTR_HIGH 0x0003ACC
|
||||
#define ACP_P1_AUDIO2_TX_LINEARPOSITIONCNTR_LOW 0x0003AD0
|
||||
#define ACP_P1_AUDIO2_TX_INTR_WATERMARK_SIZE 0x0003AD4
|
||||
|
||||
/* Registers from ACP_P1_SW_SWCLK block */
|
||||
#define ACP_P1_SW_EN 0x0003C00
|
||||
#define ACP_P1_SW_EN_STATUS 0x0003C04
|
||||
#define ACP_P1_SW_FRAMESIZE 0x0003C08
|
||||
#define ACP_P1_SW_SSP_COUNTER 0x0003C0C
|
||||
#define ACP_P1_SW_BT_TX_EN 0x0003C50
|
||||
#define ACP_P1_SW_BT_TX_EN_STATUS 0x0003C54
|
||||
#define ACP_P1_SW_BT_TX_FRAME_FORMAT 0x0003C58
|
||||
#define ACP_P1_SW_BT_TX_SAMPLEINTERVAL 0x0003C5C
|
||||
#define ACP_P1_SW_BT_TX_HCTRL 0x0003C60
|
||||
#define ACP_P1_SW_BT_TX_OFFSET 0x0003C64
|
||||
#define ACP_P1_SW_BT_TX_CHANNEL_ENABLE_DP0 0x0003C68
|
||||
#define ACP_P1_SW_BT_RX_EN 0x0003D28
|
||||
#define ACP_P1_SW_BT_RX_EN_STATUS 0x0003D2C
|
||||
#define ACP_P1_SW_BT_RX_FRAME_FORMAT 0x0003D30
|
||||
#define ACP_P1_SW_BT_RX_SAMPLEINTERVAL 0x0003D34
|
||||
#define ACP_P1_SW_BT_RX_HCTRL 0x0003D38
|
||||
#define ACP_P1_SW_BT_RX_OFFSET 0x0003D3C
|
||||
#define ACP_P1_SW_BT_RX_CHANNEL_ENABLE_DP0 0x0003D40
|
||||
#define ACP_P1_SW_BPT_PORT_EN 0x0003D60
|
||||
#define ACP_P1_SW_BPT_PORT_EN_STATUS 0x0003D64
|
||||
#define ACP_P1_SW_BPT_PORT_FRAME_FORMAT 0x0003D68
|
||||
#define ACP_P1_SW_BPT_PORT_SAMPLEINTERVAL 0x0003D6C
|
||||
#define ACP_P1_SW_BPT_PORT_HCTRL 0x0003D70
|
||||
#define ACP_P1_SW_BPT_PORT_OFFSET 0x0003D74
|
||||
#define ACP_P1_SW_BPT_PORT_CHANNEL_ENABLE 0x0003D78
|
||||
#define ACP_P1_SW_BPT_PORT_FIRST_BYTE_ADDR 0x0003D7C
|
||||
#define ACP_P1_SW_CLK_RESUME_CTRL 0x0003D80
|
||||
#define ACP_P1_SW_CLK_RESUME_DELAY_CNTR 0x0003D84
|
||||
#define ACP_P1_SW_BUS_RESET_CTRL 0x0003D88
|
||||
#define ACP_P1_SW_PRBS_ERR_STATUS 0x0003D8C
|
||||
/* Registers from ACP_SW1_SWCLK block */
|
||||
#define ACP_SW1_EN 0x0003C00
|
||||
#define ACP_SW1_EN_STATUS 0x0003C04
|
||||
#define ACP_SW1_FRAMESIZE 0x0003C08
|
||||
#define ACP_SW1_SSP_COUNTER 0x0003C0C
|
||||
#define ACP_SW1_AUDIO1_TX_EN 0x0003C50
|
||||
#define ACP_SW1_AUDIO1_TX_EN_STATUS 0x0003C54
|
||||
#define ACP_SW1_AUDIO1_TX_FRAME_FORMAT 0x0003C58
|
||||
#define ACP_SW1_AUDIO1_TX_SAMPLEINTERVAL 0x0003C5C
|
||||
#define ACP_SW1_AUDIO1_TX_HCTRL 0x0003C60
|
||||
#define ACP_SW1_AUDIO1_TX_OFFSET 0x0003C64
|
||||
#define ACP_SW1_AUDIO1_TX_CHANNEL_ENABLE_DP0 0x0003C68
|
||||
#define ACP_SW1_AUDIO1_RX_EN 0x0003D28
|
||||
#define ACP_SW1_AUDIO1_RX_EN_STATUS 0x0003D2C
|
||||
#define ACP_SW1_AUDIO1_RX_FRAME_FORMAT 0x0003D30
|
||||
#define ACP_SW1_AUDIO1_RX_SAMPLEINTERVAL 0x0003D34
|
||||
#define ACP_SW1_AUDIO1_RX_HCTRL 0x0003D38
|
||||
#define ACP_SW1_AUDIO1_RX_OFFSET 0x0003D3C
|
||||
#define ACP_SW1_AUDIO1_RX_CHANNEL_ENABLE_DP0 0x0003D40
|
||||
#define ACP_SW1_BPT_PORT_EN 0x0003D60
|
||||
#define ACP_SW1_BPT_PORT_EN_STATUS 0x0003D64
|
||||
#define ACP_SW1_BPT_PORT_FRAME_FORMAT 0x0003D68
|
||||
#define ACP_SW1_BPT_PORT_SAMPLEINTERVAL 0x0003D6C
|
||||
#define ACP_SW1_BPT_PORT_HCTRL 0x0003D70
|
||||
#define ACP_SW1_BPT_PORT_OFFSET 0x0003D74
|
||||
#define ACP_SW1_BPT_PORT_CHANNEL_ENABLE 0x0003D78
|
||||
#define ACP_SW1_BPT_PORT_FIRST_BYTE_ADDR 0x0003D7C
|
||||
#define ACP_SW1_CLK_RESUME_CTRL 0x0003D80
|
||||
#define ACP_SW1_CLK_RESUME_DELAY_CNTR 0x0003D84
|
||||
#define ACP_SW1_BUS_RESET_CTRL 0x0003D88
|
||||
#define ACP_SW1_PRBS_ERR_STATUS 0x0003D8C
|
||||
|
||||
/* Registers from ACP_P1_SW_ACLK block */
|
||||
#define P1_SW_CORB_BASE_ADDRESS 0x0003E00
|
||||
#define P1_SW_CORB_WRITE_POINTER 0x0003E04
|
||||
#define P1_SW_CORB_READ_POINTER 0x0003E08
|
||||
#define P1_SW_CORB_CONTROL 0x0003E0C
|
||||
#define P1_SW_CORB_SIZE 0x0003E14
|
||||
#define P1_SW_RIRB_BASE_ADDRESS 0x0003E18
|
||||
#define P1_SW_RIRB_WRITE_POINTER 0x0003E1C
|
||||
#define P1_SW_RIRB_RESPONSE_INTERRUPT_COUNT 0x0003E20
|
||||
#define P1_SW_RIRB_CONTROL 0x0003E24
|
||||
#define P1_SW_RIRB_SIZE 0x0003E28
|
||||
#define P1_SW_RIRB_FIFO_MIN_THDL 0x0003E2C
|
||||
#define P1_SW_IMM_CMD_UPPER_WORD 0x0003E30
|
||||
#define P1_SW_IMM_CMD_LOWER_QWORD 0x0003E34
|
||||
#define P1_SW_IMM_RESP_UPPER_WORD 0x0003E38
|
||||
#define P1_SW_IMM_RESP_LOWER_QWORD 0x0003E3C
|
||||
#define P1_SW_IMM_CMD_STS 0x0003E40
|
||||
#define P1_SW_BRA_BASE_ADDRESS 0x0003E44
|
||||
#define P1_SW_BRA_TRANSFER_SIZE 0x0003E48
|
||||
#define P1_SW_BRA_DMA_BUSY 0x0003E4C
|
||||
#define P1_SW_BRA_RESP 0x0003E50
|
||||
#define P1_SW_BRA_RESP_FRAME_ADDR 0x0003E54
|
||||
#define P1_SW_BRA_CURRENT_TRANSFER_SIZE 0x0003E58
|
||||
#define P1_SW_STATE_CHANGE_STATUS_0TO7 0x0003E5C
|
||||
#define P1_SW_STATE_CHANGE_STATUS_8TO11 0x0003E60
|
||||
#define P1_SW_STATE_CHANGE_STATUS_MASK_0TO7 0x0003E64
|
||||
#define P1_SW_STATE_CHANGE_STATUS_MASK_8TO11 0x0003E68
|
||||
#define P1_SW_CLK_FREQUENCY_CTRL 0x0003E6C
|
||||
#define P1_SW_ERROR_INTR_MASK 0x0003E70
|
||||
#define P1_SW_PHY_TEST_MODE_DATA_OFF 0x0003E74
|
||||
/* Registers from ACP_SW1_ACLK block */
|
||||
#define ACP_SW1_CORB_BASE_ADDRESS 0x0003E00
|
||||
#define ACP_SW1_CORB_WRITE_POINTER 0x0003E04
|
||||
#define ACP_SW1_CORB_READ_POINTER 0x0003E08
|
||||
#define ACP_SW1_CORB_CONTROL 0x0003E0C
|
||||
#define ACP_SW1_CORB_SIZE 0x0003E14
|
||||
#define ACP_SW1_RIRB_BASE_ADDRESS 0x0003E18
|
||||
#define ACP_SW1_RIRB_WRITE_POINTER 0x0003E1C
|
||||
#define ACP_SW1_RIRB_RESPONSE_INTERRUPT_COUNT 0x0003E20
|
||||
#define ACP_SW1_RIRB_CONTROL 0x0003E24
|
||||
#define ACP_SW1_RIRB_SIZE 0x0003E28
|
||||
#define ACP_SW1_RIRB_FIFO_MIN_THDL 0x0003E2C
|
||||
#define ACP_SW1_IMM_CMD_UPPER_WORD 0x0003E30
|
||||
#define ACP_SW1_IMM_CMD_LOWER_QWORD 0x0003E34
|
||||
#define ACP_SW1_IMM_RESP_UPPER_WORD 0x0003E38
|
||||
#define ACP_SW1_IMM_RESP_LOWER_QWORD 0x0003E3C
|
||||
#define ACP_SW1_IMM_CMD_STS 0x0003E40
|
||||
#define ACP_SW1_BRA_BASE_ADDRESS 0x0003E44
|
||||
#define ACP_SW1_BRA_TRANSFER_SIZE 0x0003E48
|
||||
#define ACP_SW1_BRA_DMA_BUSY 0x0003E4C
|
||||
#define ACP_SW1_BRA_RESP 0x0003E50
|
||||
#define ACP_SW1_BRA_RESP_FRAME_ADDR 0x0003E54
|
||||
#define ACP_SW1_BRA_CURRENT_TRANSFER_SIZE 0x0003E58
|
||||
#define ACP_SW1_STATECHANGE_STATUS_0TO7 0x0003E5C
|
||||
#define ACP_SW1_STATECHANGE_STATUS_8TO11 0x0003E60
|
||||
#define ACP_SW1_STATECHANGE_STATUS_MASK_0TO7 0x0003E64
|
||||
#define ACP_SW1_STATECHANGE_STATUS_MASK_8TO11 0x0003E68
|
||||
#define ACP_SW1_CLK_FREQUENCY_CTRL 0x0003E6C
|
||||
#define ACP_SW1_ERROR_INTR_MASK 0x0003E70
|
||||
#define ACP_SW1_PHY_TEST_MODE_DATA_OFF 0x0003E74
|
||||
|
||||
/* Registers from ACP_SCRATCH block */
|
||||
#define ACP_SCRATCH_REG_0 0x0010000
|
||||
#define ACP_SCRATCH_REG_1 0x0010004
|
||||
#define ACP_SCRATCH_REG_2 0x0010008
|
||||
#define ACP_SCRATCH_REG_3 0x001000C
|
||||
#define ACP_SCRATCH_REG_4 0x0010010
|
||||
#define ACP_SCRATCH_REG_5 0x0010014
|
||||
#define ACP_SCRATCH_REG_6 0x0010018
|
||||
#define ACP_SCRATCH_REG_7 0x001001C
|
||||
#define ACP_SCRATCH_REG_8 0x0010020
|
||||
#define ACP_SCRATCH_REG_9 0x0010024
|
||||
#define ACP_SCRATCH_REG_10 0x0010028
|
||||
#define ACP_SCRATCH_REG_11 0x001002C
|
||||
#define ACP_SCRATCH_REG_12 0x0010030
|
||||
#define ACP_SCRATCH_REG_13 0x0010034
|
||||
#define ACP_SCRATCH_REG_14 0x0010038
|
||||
#define ACP_SCRATCH_REG_15 0x001003C
|
||||
#define ACP_SCRATCH_REG_16 0x0010040
|
||||
#define ACP_SCRATCH_REG_17 0x0010044
|
||||
#define ACP_SCRATCH_REG_18 0x0010048
|
||||
#define ACP_SCRATCH_REG_19 0x001004C
|
||||
#define ACP_SCRATCH_REG_20 0x0010050
|
||||
#define ACP_SCRATCH_REG_21 0x0010054
|
||||
#define ACP_SCRATCH_REG_22 0x0010058
|
||||
#define ACP_SCRATCH_REG_23 0x001005C
|
||||
#define ACP_SCRATCH_REG_24 0x0010060
|
||||
#define ACP_SCRATCH_REG_25 0x0010064
|
||||
#define ACP_SCRATCH_REG_26 0x0010068
|
||||
#define ACP_SCRATCH_REG_27 0x001006C
|
||||
#define ACP_SCRATCH_REG_28 0x0010070
|
||||
#define ACP_SCRATCH_REG_29 0x0010074
|
||||
#define ACP_SCRATCH_REG_30 0x0010078
|
||||
#define ACP_SCRATCH_REG_31 0x001007C
|
||||
#define ACP_SCRATCH_REG_32 0x0010080
|
||||
#define ACP_SCRATCH_REG_33 0x0010084
|
||||
#define ACP_SCRATCH_REG_34 0x0010088
|
||||
#define ACP_SCRATCH_REG_35 0x001008C
|
||||
#define ACP_SCRATCH_REG_36 0x0010090
|
||||
#define ACP_SCRATCH_REG_37 0x0010094
|
||||
#define ACP_SCRATCH_REG_38 0x0010098
|
||||
#define ACP_SCRATCH_REG_39 0x001009C
|
||||
#define ACP_SCRATCH_REG_40 0x00100A0
|
||||
#define ACP_SCRATCH_REG_41 0x00100A4
|
||||
#define ACP_SCRATCH_REG_42 0x00100A8
|
||||
#define ACP_SCRATCH_REG_43 0x00100AC
|
||||
#define ACP_SCRATCH_REG_44 0x00100B0
|
||||
#define ACP_SCRATCH_REG_45 0x00100B4
|
||||
#define ACP_SCRATCH_REG_46 0x00100B8
|
||||
#define ACP_SCRATCH_REG_47 0x00100BC
|
||||
#define ACP_SCRATCH_REG_48 0x00100C0
|
||||
#define ACP_SCRATCH_REG_49 0x00100C4
|
||||
#define ACP_SCRATCH_REG_50 0x00100C8
|
||||
#define ACP_SCRATCH_REG_51 0x00100CC
|
||||
#define ACP_SCRATCH_REG_52 0x00100D0
|
||||
#define ACP_SCRATCH_REG_53 0x00100D4
|
||||
#define ACP_SCRATCH_REG_54 0x00100D8
|
||||
#define ACP_SCRATCH_REG_55 0x00100DC
|
||||
#define ACP_SCRATCH_REG_56 0x00100E0
|
||||
#define ACP_SCRATCH_REG_57 0x00100E4
|
||||
#define ACP_SCRATCH_REG_58 0x00100E8
|
||||
#define ACP_SCRATCH_REG_59 0x00100EC
|
||||
#define ACP_SCRATCH_REG_60 0x00100F0
|
||||
#define ACP_SCRATCH_REG_61 0x00100F4
|
||||
#define ACP_SCRATCH_REG_62 0x00100F8
|
||||
#define ACP_SCRATCH_REG_63 0x00100FC
|
||||
#define ACP_SCRATCH_REG_64 0x0010100
|
||||
#define ACP_SCRATCH_REG_65 0x0010104
|
||||
#define ACP_SCRATCH_REG_66 0x0010108
|
||||
#define ACP_SCRATCH_REG_67 0x001010C
|
||||
#define ACP_SCRATCH_REG_68 0x0010110
|
||||
#define ACP_SCRATCH_REG_69 0x0010114
|
||||
#define ACP_SCRATCH_REG_70 0x0010118
|
||||
#define ACP_SCRATCH_REG_71 0x001011C
|
||||
#define ACP_SCRATCH_REG_72 0x0010120
|
||||
#define ACP_SCRATCH_REG_73 0x0010124
|
||||
#define ACP_SCRATCH_REG_74 0x0010128
|
||||
#define ACP_SCRATCH_REG_75 0x001012C
|
||||
#define ACP_SCRATCH_REG_76 0x0010130
|
||||
#define ACP_SCRATCH_REG_77 0x0010134
|
||||
#define ACP_SCRATCH_REG_78 0x0010138
|
||||
#define ACP_SCRATCH_REG_79 0x001013C
|
||||
#define ACP_SCRATCH_REG_80 0x0010140
|
||||
#define ACP_SCRATCH_REG_81 0x0010144
|
||||
#define ACP_SCRATCH_REG_82 0x0010148
|
||||
#define ACP_SCRATCH_REG_83 0x001014C
|
||||
#define ACP_SCRATCH_REG_84 0x0010150
|
||||
#define ACP_SCRATCH_REG_85 0x0010154
|
||||
#define ACP_SCRATCH_REG_86 0x0010158
|
||||
#define ACP_SCRATCH_REG_87 0x001015C
|
||||
#define ACP_SCRATCH_REG_88 0x0010160
|
||||
#define ACP_SCRATCH_REG_89 0x0010164
|
||||
#define ACP_SCRATCH_REG_90 0x0010168
|
||||
#define ACP_SCRATCH_REG_91 0x001016C
|
||||
#define ACP_SCRATCH_REG_92 0x0010170
|
||||
#define ACP_SCRATCH_REG_93 0x0010174
|
||||
#define ACP_SCRATCH_REG_94 0x0010178
|
||||
#define ACP_SCRATCH_REG_95 0x001017C
|
||||
#define ACP_SCRATCH_REG_96 0x0010180
|
||||
#define ACP_SCRATCH_REG_97 0x0010184
|
||||
#define ACP_SCRATCH_REG_98 0x0010188
|
||||
#define ACP_SCRATCH_REG_99 0x001018C
|
||||
#define ACP_SCRATCH_REG_100 0x0010190
|
||||
#define ACP_SCRATCH_REG_101 0x0010194
|
||||
#define ACP_SCRATCH_REG_102 0x0010198
|
||||
#define ACP_SCRATCH_REG_103 0x001019C
|
||||
#define ACP_SCRATCH_REG_104 0x00101A0
|
||||
#define ACP_SCRATCH_REG_105 0x00101A4
|
||||
#define ACP_SCRATCH_REG_106 0x00101A8
|
||||
#define ACP_SCRATCH_REG_107 0x00101AC
|
||||
#define ACP_SCRATCH_REG_108 0x00101B0
|
||||
#define ACP_SCRATCH_REG_109 0x00101B4
|
||||
#define ACP_SCRATCH_REG_110 0x00101B8
|
||||
#define ACP_SCRATCH_REG_111 0x00101BC
|
||||
#define ACP_SCRATCH_REG_112 0x00101C0
|
||||
#define ACP_SCRATCH_REG_113 0x00101C4
|
||||
#define ACP_SCRATCH_REG_114 0x00101C8
|
||||
#define ACP_SCRATCH_REG_115 0x00101CC
|
||||
#define ACP_SCRATCH_REG_116 0x00101D0
|
||||
#define ACP_SCRATCH_REG_117 0x00101D4
|
||||
#define ACP_SCRATCH_REG_118 0x00101D8
|
||||
#define ACP_SCRATCH_REG_119 0x00101DC
|
||||
#define ACP_SCRATCH_REG_120 0x00101E0
|
||||
#define ACP_SCRATCH_REG_121 0x00101E4
|
||||
#define ACP_SCRATCH_REG_122 0x00101E8
|
||||
#define ACP_SCRATCH_REG_123 0x00101EC
|
||||
#define ACP_SCRATCH_REG_124 0x00101F0
|
||||
#define ACP_SCRATCH_REG_125 0x00101F4
|
||||
#define ACP_SCRATCH_REG_126 0x00101F8
|
||||
#define ACP_SCRATCH_REG_127 0x00101FC
|
||||
#define ACP_SCRATCH_REG_128 0x0010200
|
||||
#define ACP_SCRATCH_REG_0 0x0010000
|
||||
|
||||
#endif
|
||||
|
@ -34,6 +34,7 @@
|
||||
#define CS42L42_PAGE_24 0x2400
|
||||
#define CS42L42_PAGE_25 0x2500
|
||||
#define CS42L42_PAGE_26 0x2600
|
||||
#define CS42L42_PAGE_27 0x2700
|
||||
#define CS42L42_PAGE_28 0x2800
|
||||
#define CS42L42_PAGE_29 0x2900
|
||||
#define CS42L42_PAGE_2A 0x2A00
|
||||
@ -720,6 +721,10 @@
|
||||
|
||||
#define CS42L42_SRC_SDOUT_FS (CS42L42_PAGE_26 + 0x09)
|
||||
|
||||
/* Page 0x27 DMA */
|
||||
#define CS42L42_SOFT_RESET_REBOOT (CS42L42_PAGE_27 + 0x01)
|
||||
#define CS42L42_SFT_RST_REBOOT_MASK BIT(1)
|
||||
|
||||
/* Page 0x28 S/PDIF Registers */
|
||||
#define CS42L42_SPDIF_CTL1 (CS42L42_PAGE_28 + 0x01)
|
||||
#define CS42L42_SPDIF_CTL2 (CS42L42_PAGE_28 + 0x02)
|
||||
|
@ -69,6 +69,7 @@ struct asoc_simple_priv {
|
||||
} *dai_props;
|
||||
struct asoc_simple_jack hp_jack;
|
||||
struct asoc_simple_jack mic_jack;
|
||||
struct snd_soc_jack *aux_jacks;
|
||||
struct snd_soc_dai_link *dai_link;
|
||||
struct asoc_simple_dai *dais;
|
||||
struct snd_soc_dai_link_component *dlcs;
|
||||
@ -187,6 +188,8 @@ int asoc_simple_parse_pin_switches(struct snd_soc_card *card,
|
||||
int asoc_simple_init_jack(struct snd_soc_card *card,
|
||||
struct asoc_simple_jack *sjack,
|
||||
int is_hp, char *prefix, char *pin);
|
||||
int asoc_simple_init_aux_jacks(struct asoc_simple_priv *priv,
|
||||
char *prefix);
|
||||
int asoc_simple_init_priv(struct asoc_simple_priv *priv,
|
||||
struct link_info *li);
|
||||
int asoc_simple_remove(struct platform_device *pdev);
|
||||
|
@ -98,6 +98,7 @@ struct snd_soc_component_driver {
|
||||
int source, unsigned int freq_in, unsigned int freq_out);
|
||||
int (*set_jack)(struct snd_soc_component *component,
|
||||
struct snd_soc_jack *jack, void *data);
|
||||
int (*get_jack_type)(struct snd_soc_component *component);
|
||||
|
||||
/* DT */
|
||||
int (*of_xlate_dai_name)(struct snd_soc_component *component,
|
||||
@ -384,6 +385,7 @@ int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
|
||||
unsigned int freq_out);
|
||||
int snd_soc_component_set_jack(struct snd_soc_component *component,
|
||||
struct snd_soc_jack *jack, void *data);
|
||||
int snd_soc_component_get_jack_type(struct snd_soc_component *component);
|
||||
|
||||
void snd_soc_component_seq_notifier(struct snd_soc_component *component,
|
||||
enum snd_soc_dapm_type type, int subseq);
|
||||
|
@ -423,6 +423,16 @@ struct snd_soc_dai_driver {
|
||||
int remove_order;
|
||||
};
|
||||
|
||||
/* for Playback/Capture */
|
||||
struct snd_soc_dai_stream {
|
||||
struct snd_soc_dapm_widget *widget;
|
||||
|
||||
unsigned int active; /* usage count */
|
||||
unsigned int tdm_mask; /* CODEC TDM slot masks and params (for fixup) */
|
||||
|
||||
void *dma_data; /* DAI DMA data */
|
||||
};
|
||||
|
||||
/*
|
||||
* Digital Audio Interface runtime data.
|
||||
*
|
||||
@ -437,14 +447,7 @@ struct snd_soc_dai {
|
||||
struct snd_soc_dai_driver *driver;
|
||||
|
||||
/* DAI runtime info */
|
||||
unsigned int stream_active[SNDRV_PCM_STREAM_LAST + 1]; /* usage count */
|
||||
|
||||
struct snd_soc_dapm_widget *playback_widget;
|
||||
struct snd_soc_dapm_widget *capture_widget;
|
||||
|
||||
/* DAI DMA data */
|
||||
void *playback_dma_data;
|
||||
void *capture_dma_data;
|
||||
struct snd_soc_dai_stream stream[SNDRV_PCM_STREAM_LAST + 1];
|
||||
|
||||
/* Symmetry data - only valid if symmetry is being enforced */
|
||||
unsigned int rate;
|
||||
@ -454,10 +457,6 @@ struct snd_soc_dai {
|
||||
/* parent platform/codec */
|
||||
struct snd_soc_component *component;
|
||||
|
||||
/* CODEC TDM slot masks and params (for fixup) */
|
||||
unsigned int tx_mask;
|
||||
unsigned int rx_mask;
|
||||
|
||||
struct list_head list;
|
||||
|
||||
/* function mark */
|
||||
@ -477,36 +476,59 @@ snd_soc_dai_get_pcm_stream(const struct snd_soc_dai *dai, int stream)
|
||||
&dai->driver->playback : &dai->driver->capture;
|
||||
}
|
||||
|
||||
#define snd_soc_dai_get_widget_playback(dai) snd_soc_dai_get_widget(dai, SNDRV_PCM_STREAM_PLAYBACK)
|
||||
#define snd_soc_dai_get_widget_capture(dai) snd_soc_dai_get_widget(dai, SNDRV_PCM_STREAM_CAPTURE)
|
||||
static inline
|
||||
struct snd_soc_dapm_widget *snd_soc_dai_get_widget(
|
||||
struct snd_soc_dai *dai, int stream)
|
||||
struct snd_soc_dapm_widget *snd_soc_dai_get_widget(struct snd_soc_dai *dai, int stream)
|
||||
{
|
||||
return (stream == SNDRV_PCM_STREAM_PLAYBACK) ?
|
||||
dai->playback_widget : dai->capture_widget;
|
||||
return dai->stream[stream].widget;
|
||||
}
|
||||
|
||||
static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai,
|
||||
const struct snd_pcm_substream *ss)
|
||||
#define snd_soc_dai_set_widget_playback(dai, widget) snd_soc_dai_set_widget(dai, SNDRV_PCM_STREAM_PLAYBACK, widget)
|
||||
#define snd_soc_dai_set_widget_capture(dai, widget) snd_soc_dai_set_widget(dai, SNDRV_PCM_STREAM_CAPTURE, widget)
|
||||
static inline
|
||||
void snd_soc_dai_set_widget(struct snd_soc_dai *dai, int stream, struct snd_soc_dapm_widget *widget)
|
||||
{
|
||||
return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
|
||||
dai->playback_dma_data : dai->capture_dma_data;
|
||||
dai->stream[stream].widget = widget;
|
||||
}
|
||||
|
||||
static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
|
||||
const struct snd_pcm_substream *ss,
|
||||
void *data)
|
||||
#define snd_soc_dai_dma_data_get_playback(dai) snd_soc_dai_dma_data_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
|
||||
#define snd_soc_dai_dma_data_get_capture(dai) snd_soc_dai_dma_data_get(dai, SNDRV_PCM_STREAM_CAPTURE)
|
||||
#define snd_soc_dai_get_dma_data(dai, ss) snd_soc_dai_dma_data_get(dai, ss->stream)
|
||||
static inline void *snd_soc_dai_dma_data_get(const struct snd_soc_dai *dai, int stream)
|
||||
{
|
||||
if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
dai->playback_dma_data = data;
|
||||
else
|
||||
dai->capture_dma_data = data;
|
||||
return dai->stream[stream].dma_data;
|
||||
}
|
||||
|
||||
static inline void snd_soc_dai_init_dma_data(struct snd_soc_dai *dai,
|
||||
void *playback, void *capture)
|
||||
#define snd_soc_dai_dma_data_set_playback(dai, data) snd_soc_dai_dma_data_set(dai, SNDRV_PCM_STREAM_PLAYBACK, data)
|
||||
#define snd_soc_dai_dma_data_set_capture(dai, data) snd_soc_dai_dma_data_set(dai, SNDRV_PCM_STREAM_CAPTURE, data)
|
||||
#define snd_soc_dai_set_dma_data(dai, ss, data) snd_soc_dai_dma_data_set(dai, ss->stream, data)
|
||||
static inline void snd_soc_dai_dma_data_set(struct snd_soc_dai *dai, int stream, void *data)
|
||||
{
|
||||
dai->playback_dma_data = playback;
|
||||
dai->capture_dma_data = capture;
|
||||
dai->stream[stream].dma_data = data;
|
||||
}
|
||||
|
||||
static inline void snd_soc_dai_init_dma_data(struct snd_soc_dai *dai, void *playback, void *capture)
|
||||
{
|
||||
snd_soc_dai_dma_data_set_playback(dai, playback);
|
||||
snd_soc_dai_dma_data_set_capture(dai, capture);
|
||||
}
|
||||
|
||||
static inline unsigned int snd_soc_dai_tdm_mask_get(struct snd_soc_dai *dai, int stream)
|
||||
{
|
||||
return dai->stream[stream].tdm_mask;
|
||||
}
|
||||
|
||||
static inline void snd_soc_dai_tdm_mask_set(struct snd_soc_dai *dai, int stream,
|
||||
unsigned int tdm_mask)
|
||||
{
|
||||
dai->stream[stream].tdm_mask = tdm_mask;
|
||||
}
|
||||
|
||||
static inline unsigned int snd_soc_dai_stream_active(struct snd_soc_dai *dai, int stream)
|
||||
{
|
||||
/* see snd_soc_dai_action() for setup */
|
||||
return dai->stream[stream].active;
|
||||
}
|
||||
|
||||
static inline void snd_soc_dai_set_drvdata(struct snd_soc_dai *dai,
|
||||
@ -561,10 +583,4 @@ static inline void *snd_soc_dai_get_stream(struct snd_soc_dai *dai,
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
snd_soc_dai_stream_active(struct snd_soc_dai *dai, int stream)
|
||||
{
|
||||
return dai->stream_active[stream];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <sound/asoc.h>
|
||||
|
||||
struct device;
|
||||
struct snd_pcm_substream;
|
||||
struct snd_soc_pcm_runtime;
|
||||
struct soc_enum;
|
||||
|
||||
|
@ -162,6 +162,8 @@ int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream);
|
||||
int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
|
||||
int event);
|
||||
bool dpcm_end_walk_at_be(struct snd_soc_dapm_widget *widget, enum snd_soc_dapm_direction dir);
|
||||
int widget_in_list(struct snd_soc_dapm_widget_list *list,
|
||||
struct snd_soc_dapm_widget *widget);
|
||||
|
||||
#define dpcm_be_dai_startup_rollback(fe, stream, last) \
|
||||
dpcm_be_dai_stop(fe, stream, 0, last)
|
||||
|
@ -62,7 +62,7 @@ struct snd_soc_dobj {
|
||||
enum snd_soc_dobj_type type;
|
||||
unsigned int index; /* objects can belong in different groups */
|
||||
struct list_head list;
|
||||
struct snd_soc_tplg_ops *ops;
|
||||
int (*unload)(struct snd_soc_component *comp, struct snd_soc_dobj *dobj);
|
||||
union {
|
||||
struct snd_soc_dobj_control control;
|
||||
struct snd_soc_dobj_widget widget;
|
||||
|
@ -1052,6 +1052,12 @@ struct snd_soc_card {
|
||||
#define for_each_card_widgets_safe(card, w, _w) \
|
||||
list_for_each_entry_safe(w, _w, &card->widgets, list)
|
||||
|
||||
|
||||
static inline int snd_soc_card_is_instantiated(struct snd_soc_card *card)
|
||||
{
|
||||
return card && card->instantiated;
|
||||
}
|
||||
|
||||
/* SoC machine DAI configuration, glues a codec and cpu DAI together */
|
||||
struct snd_soc_pcm_runtime {
|
||||
struct device *dev;
|
||||
|
@ -185,6 +185,9 @@ enum sof_ipc4_pipeline_state {
|
||||
#define SOF_IPC4_GLB_PIPE_STATE_MASK GENMASK(15, 0)
|
||||
#define SOF_IPC4_GLB_PIPE_STATE(x) ((x) << SOF_IPC4_GLB_PIPE_STATE_SHIFT)
|
||||
|
||||
/* pipeline set state IPC msg extension */
|
||||
#define SOF_IPC4_GLB_PIPE_STATE_EXT_MULTI BIT(0)
|
||||
|
||||
/* load library ipc msg */
|
||||
#define SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID_SHIFT 16
|
||||
#define SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID(x) ((x) << SOF_IPC4_GLB_LOAD_LIBRARY_LIB_ID_SHIFT)
|
||||
|
@ -108,6 +108,7 @@ enum avs_tplg_token {
|
||||
AVS_TKN_MOD_CORE_ID_U8 = 1704,
|
||||
AVS_TKN_MOD_PROC_DOMAIN_U8 = 1705,
|
||||
AVS_TKN_MOD_MODCFG_EXT_ID_U32 = 1706,
|
||||
AVS_TKN_MOD_KCONTROL_ID_U32 = 1707,
|
||||
|
||||
/* struct avs_tplg_path_template */
|
||||
AVS_TKN_PATH_TMPL_ID_U32 = 1801,
|
||||
@ -121,6 +122,9 @@ enum avs_tplg_token {
|
||||
AVS_TKN_PIN_FMT_INDEX_U32 = 2201,
|
||||
AVS_TKN_PIN_FMT_IOBS_U32 = 2202,
|
||||
AVS_TKN_PIN_FMT_AFMT_ID_U32 = 2203,
|
||||
|
||||
/* struct avs_tplg_kcontrol */
|
||||
AVS_TKN_KCONTROL_ID_U32 = 2301,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc-acpi.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "acp-mach.h"
|
||||
@ -27,6 +28,7 @@ static struct acp_card_drvdata rt5682_rt1019_data = {
|
||||
.hs_codec_id = RT5682,
|
||||
.amp_codec_id = RT1019,
|
||||
.dmic_codec_id = DMIC,
|
||||
.tdm_mode = false,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata rt5682s_max_data = {
|
||||
@ -36,6 +38,7 @@ static struct acp_card_drvdata rt5682s_max_data = {
|
||||
.hs_codec_id = RT5682S,
|
||||
.amp_codec_id = MAX98360A,
|
||||
.dmic_codec_id = DMIC,
|
||||
.tdm_mode = false,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata rt5682s_rt1019_data = {
|
||||
@ -45,6 +48,7 @@ static struct acp_card_drvdata rt5682s_rt1019_data = {
|
||||
.hs_codec_id = RT5682S,
|
||||
.amp_codec_id = RT1019,
|
||||
.dmic_codec_id = DMIC,
|
||||
.tdm_mode = false,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata max_nau8825_data = {
|
||||
@ -56,6 +60,7 @@ static struct acp_card_drvdata max_nau8825_data = {
|
||||
.dmic_codec_id = DMIC,
|
||||
.soc_mclk = true,
|
||||
.platform = REMBRANDT,
|
||||
.tdm_mode = false,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata rt5682s_rt1019_rmb_data = {
|
||||
@ -67,6 +72,7 @@ static struct acp_card_drvdata rt5682s_rt1019_rmb_data = {
|
||||
.dmic_codec_id = DMIC,
|
||||
.soc_mclk = true,
|
||||
.platform = REMBRANDT,
|
||||
.tdm_mode = false,
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new acp_controls[] = {
|
||||
@ -90,6 +96,8 @@ static int acp_asoc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = NULL;
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct dmi_system_id *dmi_id;
|
||||
struct acp_card_drvdata *acp_card_drvdata;
|
||||
int ret;
|
||||
|
||||
if (!pdev->id_entry)
|
||||
@ -108,6 +116,11 @@ static int acp_asoc_probe(struct platform_device *pdev)
|
||||
card->num_controls = ARRAY_SIZE(acp_controls);
|
||||
card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
|
||||
|
||||
acp_card_drvdata = card->drvdata;
|
||||
dmi_id = dmi_first_match(acp_quirk_table);
|
||||
if (dmi_id && dmi_id->driver_data)
|
||||
acp_card_drvdata->tdm_mode = dmi_id->driver_data;
|
||||
|
||||
acp_legacy_dai_links_create(card);
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
|
@ -32,6 +32,20 @@
|
||||
#define DUAL_CHANNEL 2
|
||||
#define FOUR_CHANNEL 4
|
||||
|
||||
#define TDM_MODE_ENABLE 1
|
||||
|
||||
const struct dmi_system_id acp_quirk_table[] = {
|
||||
{
|
||||
/* Google skyrim proto-0 */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_FAMILY, "Google_Skyrim"),
|
||||
},
|
||||
.driver_data = (void *)TDM_MODE_ENABLE,
|
||||
},
|
||||
{}
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(acp_quirk_table);
|
||||
|
||||
static struct snd_soc_jack pco_jack;
|
||||
|
||||
static const unsigned int channels[] = {
|
||||
@ -54,10 +68,11 @@ static const struct snd_pcm_hw_constraint_list constraints_channels = {
|
||||
.mask = 0,
|
||||
};
|
||||
|
||||
static int acp_clk_enable(struct acp_card_drvdata *drvdata)
|
||||
static int acp_clk_enable(struct acp_card_drvdata *drvdata,
|
||||
unsigned int srate, unsigned int bclk_ratio)
|
||||
{
|
||||
clk_set_rate(drvdata->wclk, 48000);
|
||||
clk_set_rate(drvdata->bclk, 48000 * 64);
|
||||
clk_set_rate(drvdata->wclk, srate);
|
||||
clk_set_rate(drvdata->bclk, srate * bclk_ratio);
|
||||
|
||||
return clk_prepare_enable(drvdata->wclk);
|
||||
}
|
||||
@ -86,34 +101,6 @@ static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
|
||||
if (drvdata->hs_codec_id != RT5682)
|
||||
return -EINVAL;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
|
||||
| SND_SOC_DAIFMT_CBP_CFP);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,
|
||||
PCO_PLAT_CLK, RT5682_PLL_FREQ);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,
|
||||
RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set tdm/i2s1 master bclk ratio */
|
||||
ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
|
||||
drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
|
||||
|
||||
@ -151,10 +138,15 @@ static int acp_card_hs_startup(struct snd_pcm_substream *substream)
|
||||
int ret;
|
||||
unsigned int fmt;
|
||||
|
||||
if (drvdata->soc_mclk)
|
||||
fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
|
||||
if (drvdata->tdm_mode)
|
||||
fmt = SND_SOC_DAIFMT_DSP_A;
|
||||
else
|
||||
fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
|
||||
fmt = SND_SOC_DAIFMT_I2S;
|
||||
|
||||
if (drvdata->soc_mclk)
|
||||
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
|
||||
else
|
||||
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, fmt);
|
||||
if (ret < 0) {
|
||||
@ -168,16 +160,6 @@ static int acp_card_hs_startup(struct snd_pcm_substream *substream)
|
||||
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
|
||||
&constraints_rates);
|
||||
|
||||
if (strcmp(codec_dai->name, "rt5682s-aif1") && strcmp(codec_dai->name, "rt5682s-aif2")) {
|
||||
if (!drvdata->soc_mclk) {
|
||||
ret = acp_clk_enable(drvdata);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -191,9 +173,96 @@ static void acp_card_shutdown(struct snd_pcm_substream *substream)
|
||||
clk_disable_unprepare(drvdata->wclk);
|
||||
}
|
||||
|
||||
static int acp_card_rt5682_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct acp_card_drvdata *drvdata = card->drvdata;
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
int ret;
|
||||
unsigned int fmt, srate, ch, format;
|
||||
|
||||
srate = params_rate(params);
|
||||
ch = params_channels(params);
|
||||
format = params_physical_width(params);
|
||||
|
||||
if (drvdata->tdm_mode)
|
||||
fmt = SND_SOC_DAIFMT_DSP_A;
|
||||
else
|
||||
fmt = SND_SOC_DAIFMT_I2S;
|
||||
|
||||
if (drvdata->soc_mclk)
|
||||
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
|
||||
else
|
||||
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, fmt);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (drvdata->tdm_mode) {
|
||||
/**
|
||||
* As codec supports slot 0 and slot 1 for playback and capture.
|
||||
*/
|
||||
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 8, 16);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 8, 16);
|
||||
if (ret < 0) {
|
||||
dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,
|
||||
PCO_PLAT_CLK, RT5682_PLL_FREQ);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,
|
||||
RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set tdm/i2s1 master bclk ratio */
|
||||
ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!drvdata->soc_mclk) {
|
||||
ret = acp_clk_enable(drvdata, srate, ch * format);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops acp_card_rt5682_ops = {
|
||||
.startup = acp_card_hs_startup,
|
||||
.shutdown = acp_card_shutdown,
|
||||
.hw_params = acp_card_rt5682_hw_params,
|
||||
};
|
||||
|
||||
/* Define RT5682S CODEC component*/
|
||||
@ -212,7 +281,6 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
|
||||
struct acp_card_drvdata *drvdata = card->drvdata;
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_component *component = codec_dai->component;
|
||||
unsigned int fmt;
|
||||
int ret;
|
||||
|
||||
dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
|
||||
@ -220,38 +288,6 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
|
||||
if (drvdata->hs_codec_id != RT5682S)
|
||||
return -EINVAL;
|
||||
|
||||
if (drvdata->soc_mclk)
|
||||
fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
|
||||
else
|
||||
fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, fmt);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL2, RT5682S_PLL_S_MCLK,
|
||||
PCO_PLAT_CLK, RT5682_PLL_FREQ);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL2,
|
||||
RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set tdm/i2s1 master bclk ratio */
|
||||
ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!drvdata->soc_mclk) {
|
||||
drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
|
||||
drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
|
||||
@ -281,8 +317,90 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
|
||||
return snd_soc_dapm_add_routes(&rtd->card->dapm, rt5682s_map, ARRAY_SIZE(rt5682s_map));
|
||||
}
|
||||
|
||||
static int acp_card_rt5682s_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct acp_card_drvdata *drvdata = card->drvdata;
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
int ret;
|
||||
unsigned int fmt, srate, ch, format;
|
||||
|
||||
srate = params_rate(params);
|
||||
ch = params_channels(params);
|
||||
format = params_physical_width(params);
|
||||
|
||||
if (drvdata->tdm_mode)
|
||||
fmt = SND_SOC_DAIFMT_DSP_A;
|
||||
else
|
||||
fmt = SND_SOC_DAIFMT_I2S;
|
||||
|
||||
if (drvdata->soc_mclk)
|
||||
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
|
||||
else
|
||||
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, fmt);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (drvdata->tdm_mode) {
|
||||
/**
|
||||
* As codec supports slot 0 and slot 1 for playback and capture.
|
||||
*/
|
||||
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 8, 16);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 8, 16);
|
||||
if (ret < 0) {
|
||||
dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL2, RT5682S_PLL_S_MCLK,
|
||||
PCO_PLAT_CLK, RT5682_PLL_FREQ);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL2,
|
||||
RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set tdm/i2s1 master bclk ratio */
|
||||
ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
clk_set_rate(drvdata->wclk, srate);
|
||||
clk_set_rate(drvdata->bclk, srate * ch * format);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops acp_card_rt5682s_ops = {
|
||||
.startup = acp_card_hs_startup,
|
||||
.hw_params = acp_card_rt5682s_hw_params,
|
||||
};
|
||||
|
||||
static const unsigned int dmic_channels[] = {
|
||||
@ -351,19 +469,55 @@ static int acp_card_rt1019_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct acp_card_drvdata *drvdata = card->drvdata;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
int srate, i, ret = 0;
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
int i, ret = 0;
|
||||
unsigned int fmt, srate, ch, format;
|
||||
|
||||
srate = params_rate(params);
|
||||
ch = params_channels(params);
|
||||
format = params_physical_width(params);
|
||||
|
||||
if (drvdata->amp_codec_id != RT1019)
|
||||
return -EINVAL;
|
||||
|
||||
if (drvdata->tdm_mode)
|
||||
fmt = SND_SOC_DAIFMT_DSP_A;
|
||||
else
|
||||
fmt = SND_SOC_DAIFMT_I2S;
|
||||
|
||||
if (drvdata->soc_mclk)
|
||||
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
|
||||
else
|
||||
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (drvdata->tdm_mode) {
|
||||
/**
|
||||
* As codec supports slot 2 and slot 3 for playback.
|
||||
*/
|
||||
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xC, 0, 8, 16);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
for_each_rtd_codec_dais(rtd, i, codec_dai) {
|
||||
if (strcmp(codec_dai->name, "rt1019-aif"))
|
||||
continue;
|
||||
|
||||
ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,
|
||||
64 * srate, 256 * srate);
|
||||
if (drvdata->tdm_mode)
|
||||
ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,
|
||||
TDM_CHANNELS * format * srate, 256 * srate);
|
||||
else
|
||||
ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,
|
||||
ch * format * srate, 256 * srate);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -371,6 +525,41 @@ static int acp_card_rt1019_hw_params(struct snd_pcm_substream *substream,
|
||||
256 * srate, SND_SOC_CLOCK_IN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (drvdata->tdm_mode) {
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A
|
||||
| SND_SOC_DAIFMT_NB_NF);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* As codec supports slot 2 for left channel playback.
|
||||
*/
|
||||
if (!strcmp(codec_dai->component->name, "i2c-10EC1019:00")) {
|
||||
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x4, 0x4, 8, 16);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* As codec supports slot 3 for right channel playback.
|
||||
*/
|
||||
if (!strcmp(codec_dai->component->name, "i2c-10EC1019:01")) {
|
||||
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x8, 0x8, 8, 16);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!drvdata->soc_mclk) {
|
||||
ret = acp_clk_enable(drvdata, srate, ch * format);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -379,10 +568,6 @@ static int acp_card_rt1019_hw_params(struct snd_pcm_substream *substream,
|
||||
static int acp_card_amp_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct acp_card_drvdata *drvdata = card->drvdata;
|
||||
int ret = 0;
|
||||
|
||||
runtime->hw.channels_max = DUAL_CHANNEL;
|
||||
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
|
||||
@ -390,14 +575,7 @@ static int acp_card_amp_startup(struct snd_pcm_substream *substream)
|
||||
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
|
||||
&constraints_rates);
|
||||
|
||||
if (!drvdata->soc_mclk) {
|
||||
ret = acp_clk_enable(drvdata);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops acp_card_rt1019_ops = {
|
||||
@ -426,9 +604,61 @@ static int acp_card_maxim_init(struct snd_soc_pcm_runtime *rtd)
|
||||
ARRAY_SIZE(max98360a_map));
|
||||
}
|
||||
|
||||
static int acp_card_maxim_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct acp_card_drvdata *drvdata = card->drvdata;
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
unsigned int fmt, srate, ch, format;
|
||||
int ret;
|
||||
|
||||
srate = params_rate(params);
|
||||
ch = params_channels(params);
|
||||
format = params_physical_width(params);
|
||||
|
||||
if (drvdata->tdm_mode)
|
||||
fmt = SND_SOC_DAIFMT_DSP_A;
|
||||
else
|
||||
fmt = SND_SOC_DAIFMT_I2S;
|
||||
|
||||
if (drvdata->soc_mclk)
|
||||
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
|
||||
else
|
||||
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (drvdata->tdm_mode) {
|
||||
/**
|
||||
* As codec supports slot 2 and slot 3 for playback.
|
||||
*/
|
||||
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xC, 0, 8, 16);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!drvdata->soc_mclk) {
|
||||
ret = acp_clk_enable(drvdata, srate, ch * format);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_ops acp_card_maxim_ops = {
|
||||
.startup = acp_card_amp_startup,
|
||||
.shutdown = acp_card_shutdown,
|
||||
.hw_params = acp_card_maxim_hw_params,
|
||||
};
|
||||
|
||||
/* Declare nau8825 codec components */
|
||||
@ -446,7 +676,6 @@ static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd)
|
||||
struct acp_card_drvdata *drvdata = card->drvdata;
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_component *component = codec_dai->component;
|
||||
unsigned int fmt;
|
||||
int ret;
|
||||
|
||||
dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
|
||||
@ -454,16 +683,6 @@ static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd)
|
||||
if (drvdata->hs_codec_id != NAU8825)
|
||||
return -EINVAL;
|
||||
|
||||
if (drvdata->soc_mclk)
|
||||
fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
|
||||
else
|
||||
fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, fmt);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = snd_soc_card_jack_new(card, "Headset Jack",
|
||||
SND_JACK_HEADSET | SND_JACK_LINEOUT |
|
||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
@ -492,8 +711,12 @@ static int acp_nau8825_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct acp_card_drvdata *drvdata = card->drvdata;
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
|
||||
int ret;
|
||||
unsigned int fmt;
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_FS,
|
||||
(48000 * 256), SND_SOC_CLOCK_IN);
|
||||
@ -507,6 +730,44 @@ static int acp_nau8825_hw_params(struct snd_pcm_substream *substream,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (drvdata->tdm_mode)
|
||||
fmt = SND_SOC_DAIFMT_DSP_A;
|
||||
else
|
||||
fmt = SND_SOC_DAIFMT_I2S;
|
||||
|
||||
if (drvdata->soc_mclk)
|
||||
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
|
||||
else
|
||||
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, fmt);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (drvdata->tdm_mode) {
|
||||
/**
|
||||
* As codec supports slot 4 and slot 5 for playback and slot 6 for capture.
|
||||
*/
|
||||
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x30, 0xC0, 8, 16);
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x40, 0x30, 8, 16);
|
||||
if (ret < 0) {
|
||||
dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -565,8 +826,12 @@ SND_SOC_DAILINK_DEF(i2s_hs,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-hs")));
|
||||
SND_SOC_DAILINK_DEF(sof_sp,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp")));
|
||||
SND_SOC_DAILINK_DEF(sof_sp_virtual,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp-virtual")));
|
||||
SND_SOC_DAILINK_DEF(sof_hs,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs")));
|
||||
SND_SOC_DAILINK_DEF(sof_hs_virtual,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs-virtual")));
|
||||
SND_SOC_DAILINK_DEF(sof_dmic,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic")));
|
||||
SND_SOC_DAILINK_DEF(pdm_dmic,
|
||||
@ -596,8 +861,6 @@ static int acp_rtk_set_bias_level(struct snd_soc_card *card,
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) {
|
||||
clk_set_rate(drvdata->wclk, 48000);
|
||||
clk_set_rate(drvdata->bclk, 48000 * 64);
|
||||
|
||||
/* Increase bclk's enable_count */
|
||||
ret = clk_prepare_enable(drvdata->bclk);
|
||||
@ -701,8 +964,8 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
|
||||
if (drv_data->amp_cpu_id == I2S_SP) {
|
||||
links[i].name = "acp-amp-codec";
|
||||
links[i].id = AMP_BE_ID;
|
||||
links[i].cpus = sof_sp;
|
||||
links[i].num_cpus = ARRAY_SIZE(sof_sp);
|
||||
links[i].cpus = sof_sp_virtual;
|
||||
links[i].num_cpus = ARRAY_SIZE(sof_sp_virtual);
|
||||
links[i].platforms = sof_component;
|
||||
links[i].num_platforms = ARRAY_SIZE(sof_component);
|
||||
links[i].dpcm_playback = 1;
|
||||
@ -733,8 +996,8 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
|
||||
if (drv_data->amp_cpu_id == I2S_HS) {
|
||||
links[i].name = "acp-amp-codec";
|
||||
links[i].id = AMP_BE_ID;
|
||||
links[i].cpus = sof_hs;
|
||||
links[i].num_cpus = ARRAY_SIZE(sof_hs);
|
||||
links[i].cpus = sof_hs_virtual;
|
||||
links[i].num_cpus = ARRAY_SIZE(sof_hs_virtual);
|
||||
links[i].platforms = sof_component;
|
||||
links[i].num_platforms = ARRAY_SIZE(sof_component);
|
||||
links[i].dpcm_playback = 1;
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include <linux/module.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#define TDM_CHANNELS 8
|
||||
|
||||
enum be_id {
|
||||
HEADSET_BE_ID = 0,
|
||||
AMP_BE_ID,
|
||||
@ -58,9 +60,11 @@ struct acp_card_drvdata {
|
||||
struct clk *wclk;
|
||||
struct clk *bclk;
|
||||
bool soc_mclk;
|
||||
bool tdm_mode;
|
||||
};
|
||||
|
||||
int acp_sofdsp_dai_links_create(struct snd_soc_card *card);
|
||||
int acp_legacy_dai_links_create(struct snd_soc_card *card);
|
||||
extern const struct dmi_system_id acp_quirk_table[];
|
||||
|
||||
#endif
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc-acpi.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "acp-mach.h"
|
||||
@ -27,6 +28,7 @@ static struct acp_card_drvdata sof_rt5682_rt1019_data = {
|
||||
.hs_codec_id = RT5682,
|
||||
.amp_codec_id = RT1019,
|
||||
.dmic_codec_id = DMIC,
|
||||
.tdm_mode = false,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata sof_rt5682_max_data = {
|
||||
@ -36,6 +38,7 @@ static struct acp_card_drvdata sof_rt5682_max_data = {
|
||||
.hs_codec_id = RT5682,
|
||||
.amp_codec_id = MAX98360A,
|
||||
.dmic_codec_id = DMIC,
|
||||
.tdm_mode = false,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata sof_rt5682s_rt1019_data = {
|
||||
@ -45,6 +48,7 @@ static struct acp_card_drvdata sof_rt5682s_rt1019_data = {
|
||||
.hs_codec_id = RT5682S,
|
||||
.amp_codec_id = RT1019,
|
||||
.dmic_codec_id = DMIC,
|
||||
.tdm_mode = false,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata sof_rt5682s_max_data = {
|
||||
@ -54,6 +58,7 @@ static struct acp_card_drvdata sof_rt5682s_max_data = {
|
||||
.hs_codec_id = RT5682S,
|
||||
.amp_codec_id = MAX98360A,
|
||||
.dmic_codec_id = DMIC,
|
||||
.tdm_mode = false,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata sof_nau8825_data = {
|
||||
@ -64,6 +69,7 @@ static struct acp_card_drvdata sof_nau8825_data = {
|
||||
.amp_codec_id = MAX98360A,
|
||||
.dmic_codec_id = DMIC,
|
||||
.soc_mclk = true,
|
||||
.tdm_mode = false,
|
||||
};
|
||||
|
||||
static struct acp_card_drvdata sof_rt5682s_hs_rt1019_data = {
|
||||
@ -74,6 +80,7 @@ static struct acp_card_drvdata sof_rt5682s_hs_rt1019_data = {
|
||||
.amp_codec_id = RT1019,
|
||||
.dmic_codec_id = DMIC,
|
||||
.soc_mclk = true,
|
||||
.tdm_mode = false,
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new acp_controls[] = {
|
||||
@ -96,6 +103,8 @@ static int acp_sof_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_card *card = NULL;
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct dmi_system_id *dmi_id;
|
||||
struct acp_card_drvdata *acp_card_drvdata;
|
||||
int ret;
|
||||
|
||||
if (!pdev->id_entry)
|
||||
@ -114,6 +123,11 @@ static int acp_sof_probe(struct platform_device *pdev)
|
||||
card->num_controls = ARRAY_SIZE(acp_controls);
|
||||
card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
|
||||
|
||||
acp_card_drvdata = card->drvdata;
|
||||
dmi_id = dmi_first_match(acp_quirk_table);
|
||||
if (dmi_id && dmi_id->driver_data)
|
||||
acp_card_drvdata->tdm_mode = dmi_id->driver_data;
|
||||
|
||||
acp_sofdsp_dai_links_create(card);
|
||||
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define ACP63_REG_START 0x1240000
|
||||
#define ACP63_REG_END 0x1250200
|
||||
#define ACP63_DEVS 3
|
||||
#define ACP63_PDM_MODE 1
|
||||
|
||||
#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001
|
||||
#define ACP_PGFSM_CNTL_POWER_ON_MASK 1
|
||||
@ -30,7 +29,7 @@
|
||||
#define ACP_ERROR_STAT 29
|
||||
#define PDM_DECIMATION_FACTOR 2
|
||||
#define ACP_PDM_CLK_FREQ_MASK 7
|
||||
#define ACP_WOV_MISC_CTRL_MASK 0x10
|
||||
#define ACP_WOV_GAIN_CONTROL GENMASK(4, 3)
|
||||
#define ACP_PDM_ENABLE 1
|
||||
#define ACP_PDM_DISABLE 0
|
||||
#define ACP_PDM_DMA_EN_STATUS 2
|
||||
@ -54,6 +53,11 @@
|
||||
/* time in ms for runtime suspend delay */
|
||||
#define ACP_SUSPEND_DELAY_MS 2000
|
||||
|
||||
#define ACP63_DMIC_ADDR 2
|
||||
#define ACP63_PDM_MODE_DEVS 3
|
||||
#define ACP63_PDM_DEV_MASK 1
|
||||
#define ACP_DMIC_DEV 2
|
||||
|
||||
enum acp_config {
|
||||
ACP_CONFIG_0 = 0,
|
||||
ACP_CONFIG_1,
|
||||
@ -84,6 +88,7 @@ struct pdm_stream_instance {
|
||||
struct pdm_dev_data {
|
||||
u32 pdm_irq;
|
||||
void __iomem *acp63_base;
|
||||
struct mutex *acp_lock;
|
||||
struct snd_pcm_substream *capture_stream;
|
||||
};
|
||||
|
||||
@ -100,6 +105,9 @@ static inline void acp63_writel(u32 val, void __iomem *base_addr)
|
||||
struct acp63_dev_data {
|
||||
void __iomem *acp63_base;
|
||||
struct resource *res;
|
||||
bool acp63_audio_mode;
|
||||
struct platform_device *pdev[ACP63_DEVS];
|
||||
struct mutex acp_lock; /* protect shared registers */
|
||||
u16 pdev_mask;
|
||||
u16 pdev_count;
|
||||
u16 pdm_dev_index;
|
||||
};
|
||||
|
@ -116,6 +116,7 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
|
||||
struct acp63_dev_data *adata;
|
||||
struct pdm_dev_data *ps_pdm_data;
|
||||
u32 val;
|
||||
u16 pdev_index;
|
||||
|
||||
adata = dev_id;
|
||||
if (!adata)
|
||||
@ -123,7 +124,8 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
|
||||
|
||||
val = acp63_readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
|
||||
if (val & BIT(PDM_DMA_STAT)) {
|
||||
ps_pdm_data = dev_get_drvdata(&adata->pdev[0]->dev);
|
||||
pdev_index = adata->pdm_dev_index;
|
||||
ps_pdm_data = dev_get_drvdata(&adata->pdev[pdev_index]->dev);
|
||||
acp63_writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT);
|
||||
if (ps_pdm_data->capture_stream)
|
||||
snd_pcm_period_elapsed(ps_pdm_data->capture_stream);
|
||||
@ -132,17 +134,124 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static void get_acp63_device_config(u32 config, struct pci_dev *pci,
|
||||
struct acp63_dev_data *acp_data)
|
||||
{
|
||||
struct acpi_device *dmic_dev;
|
||||
const union acpi_object *obj;
|
||||
bool is_dmic_dev = false;
|
||||
|
||||
dmic_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0);
|
||||
if (dmic_dev) {
|
||||
if (!acpi_dev_get_property(dmic_dev, "acp-audio-device-type",
|
||||
ACPI_TYPE_INTEGER, &obj) &&
|
||||
obj->integer.value == ACP_DMIC_DEV)
|
||||
is_dmic_dev = true;
|
||||
}
|
||||
|
||||
switch (config) {
|
||||
case ACP_CONFIG_0:
|
||||
case ACP_CONFIG_1:
|
||||
case ACP_CONFIG_2:
|
||||
case ACP_CONFIG_3:
|
||||
case ACP_CONFIG_9:
|
||||
case ACP_CONFIG_15:
|
||||
dev_dbg(&pci->dev, "Audio Mode %d\n", config);
|
||||
break;
|
||||
default:
|
||||
if (is_dmic_dev) {
|
||||
acp_data->pdev_mask = ACP63_PDM_DEV_MASK;
|
||||
acp_data->pdev_count = ACP63_PDM_MODE_DEVS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void acp63_fill_platform_dev_info(struct platform_device_info *pdevinfo,
|
||||
struct device *parent,
|
||||
struct fwnode_handle *fw_node,
|
||||
char *name, unsigned int id,
|
||||
const struct resource *res,
|
||||
unsigned int num_res,
|
||||
const void *data,
|
||||
size_t size_data)
|
||||
{
|
||||
pdevinfo->name = name;
|
||||
pdevinfo->id = id;
|
||||
pdevinfo->parent = parent;
|
||||
pdevinfo->num_res = num_res;
|
||||
pdevinfo->res = res;
|
||||
pdevinfo->data = data;
|
||||
pdevinfo->size_data = size_data;
|
||||
pdevinfo->fwnode = fw_node;
|
||||
}
|
||||
|
||||
static int create_acp63_platform_devs(struct pci_dev *pci, struct acp63_dev_data *adata, u32 addr)
|
||||
{
|
||||
struct platform_device_info pdevinfo[ACP63_DEVS];
|
||||
struct device *parent;
|
||||
int index;
|
||||
int ret;
|
||||
|
||||
parent = &pci->dev;
|
||||
dev_dbg(&pci->dev,
|
||||
"%s pdev_mask:0x%x pdev_count:0x%x\n", __func__, adata->pdev_mask,
|
||||
adata->pdev_count);
|
||||
if (adata->pdev_mask) {
|
||||
adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL);
|
||||
if (!adata->res) {
|
||||
ret = -ENOMEM;
|
||||
goto de_init;
|
||||
}
|
||||
adata->res->flags = IORESOURCE_MEM;
|
||||
adata->res->start = addr;
|
||||
adata->res->end = addr + (ACP63_REG_END - ACP63_REG_START);
|
||||
memset(&pdevinfo, 0, sizeof(pdevinfo));
|
||||
}
|
||||
|
||||
switch (adata->pdev_mask) {
|
||||
case ACP63_PDM_DEV_MASK:
|
||||
adata->pdm_dev_index = 0;
|
||||
acp63_fill_platform_dev_info(&pdevinfo[0], parent, NULL, "acp_ps_pdm_dma",
|
||||
0, adata->res, 1, &adata->acp_lock,
|
||||
sizeof(adata->acp_lock));
|
||||
acp63_fill_platform_dev_info(&pdevinfo[1], parent, NULL, "dmic-codec",
|
||||
0, NULL, 0, NULL, 0);
|
||||
acp63_fill_platform_dev_info(&pdevinfo[2], parent, NULL, "acp_ps_mach",
|
||||
0, NULL, 0, NULL, 0);
|
||||
break;
|
||||
default:
|
||||
dev_dbg(&pci->dev, "No PDM devices found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (index = 0; index < adata->pdev_count; index++) {
|
||||
adata->pdev[index] = platform_device_register_full(&pdevinfo[index]);
|
||||
if (IS_ERR(adata->pdev[index])) {
|
||||
dev_err(&pci->dev,
|
||||
"cannot register %s device\n", pdevinfo[index].name);
|
||||
ret = PTR_ERR(adata->pdev[index]);
|
||||
goto unregister_devs;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
unregister_devs:
|
||||
for (--index; index >= 0; index--)
|
||||
platform_device_unregister(adata->pdev[index]);
|
||||
de_init:
|
||||
if (acp63_deinit(adata->acp63_base, &pci->dev))
|
||||
dev_err(&pci->dev, "ACP de-init failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int snd_acp63_probe(struct pci_dev *pci,
|
||||
const struct pci_device_id *pci_id)
|
||||
{
|
||||
struct acp63_dev_data *adata;
|
||||
struct platform_device_info pdevinfo[ACP63_DEVS];
|
||||
int index, ret;
|
||||
int val = 0x00;
|
||||
struct acpi_device *adev;
|
||||
const union acpi_object *obj;
|
||||
u32 addr;
|
||||
unsigned int irqflags;
|
||||
u32 irqflags;
|
||||
int val;
|
||||
int ret;
|
||||
|
||||
irqflags = IRQF_SHARED;
|
||||
/* Pink Sardine device check */
|
||||
@ -179,86 +288,28 @@ static int snd_acp63_probe(struct pci_dev *pci,
|
||||
}
|
||||
pci_set_master(pci);
|
||||
pci_set_drvdata(pci, adata);
|
||||
mutex_init(&adata->acp_lock);
|
||||
ret = acp63_init(adata->acp63_base, &pci->dev);
|
||||
if (ret)
|
||||
goto release_regions;
|
||||
ret = devm_request_irq(&pci->dev, pci->irq, acp63_irq_handler,
|
||||
irqflags, "ACP_PCI_IRQ", adata);
|
||||
if (ret) {
|
||||
dev_err(&pci->dev, "ACP PCI IRQ request failed\n");
|
||||
goto de_init;
|
||||
}
|
||||
val = acp63_readl(adata->acp63_base + ACP_PIN_CONFIG);
|
||||
switch (val) {
|
||||
case ACP_CONFIG_0:
|
||||
case ACP_CONFIG_1:
|
||||
case ACP_CONFIG_2:
|
||||
case ACP_CONFIG_3:
|
||||
case ACP_CONFIG_9:
|
||||
case ACP_CONFIG_15:
|
||||
dev_info(&pci->dev, "Audio Mode %d\n", val);
|
||||
break;
|
||||
default:
|
||||
|
||||
/* Checking DMIC hardware*/
|
||||
adev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), 0x02, 0);
|
||||
|
||||
if (!adev)
|
||||
break;
|
||||
|
||||
if (!acpi_dev_get_property(adev, "acp-audio-device-type",
|
||||
ACPI_TYPE_INTEGER, &obj) &&
|
||||
obj->integer.value == 2) {
|
||||
adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL);
|
||||
if (!adata->res) {
|
||||
ret = -ENOMEM;
|
||||
goto de_init;
|
||||
}
|
||||
|
||||
adata->res->name = "acp_iomem";
|
||||
adata->res->flags = IORESOURCE_MEM;
|
||||
adata->res->start = addr;
|
||||
adata->res->end = addr + (ACP63_REG_END - ACP63_REG_START);
|
||||
adata->acp63_audio_mode = ACP63_PDM_MODE;
|
||||
|
||||
memset(&pdevinfo, 0, sizeof(pdevinfo));
|
||||
pdevinfo[0].name = "acp_ps_pdm_dma";
|
||||
pdevinfo[0].id = 0;
|
||||
pdevinfo[0].parent = &pci->dev;
|
||||
pdevinfo[0].num_res = 1;
|
||||
pdevinfo[0].res = adata->res;
|
||||
|
||||
pdevinfo[1].name = "dmic-codec";
|
||||
pdevinfo[1].id = 0;
|
||||
pdevinfo[1].parent = &pci->dev;
|
||||
|
||||
pdevinfo[2].name = "acp_ps_mach";
|
||||
pdevinfo[2].id = 0;
|
||||
pdevinfo[2].parent = &pci->dev;
|
||||
|
||||
for (index = 0; index < ACP63_DEVS; index++) {
|
||||
adata->pdev[index] =
|
||||
platform_device_register_full(&pdevinfo[index]);
|
||||
|
||||
if (IS_ERR(adata->pdev[index])) {
|
||||
dev_err(&pci->dev,
|
||||
"cannot register %s device\n",
|
||||
pdevinfo[index].name);
|
||||
ret = PTR_ERR(adata->pdev[index]);
|
||||
goto unregister_devs;
|
||||
}
|
||||
ret = devm_request_irq(&pci->dev, pci->irq, acp63_irq_handler,
|
||||
irqflags, "ACP_PCI_IRQ", adata);
|
||||
if (ret) {
|
||||
dev_err(&pci->dev, "ACP PCI IRQ request failed\n");
|
||||
goto unregister_devs;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
get_acp63_device_config(val, pci, adata);
|
||||
ret = create_acp63_platform_devs(pci, adata, addr);
|
||||
if (ret < 0) {
|
||||
dev_err(&pci->dev, "ACP platform devices creation failed\n");
|
||||
goto de_init;
|
||||
}
|
||||
pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
|
||||
pm_runtime_use_autosuspend(&pci->dev);
|
||||
pm_runtime_put_noidle(&pci->dev);
|
||||
pm_runtime_allow(&pci->dev);
|
||||
return 0;
|
||||
unregister_devs:
|
||||
for (--index; index >= 0; index--)
|
||||
platform_device_unregister(adata->pdev[index]);
|
||||
de_init:
|
||||
if (acp63_deinit(adata->acp63_base, &pci->dev))
|
||||
dev_err(&pci->dev, "ACP de-init failed\n");
|
||||
@ -305,10 +356,8 @@ static void snd_acp63_remove(struct pci_dev *pci)
|
||||
int ret, index;
|
||||
|
||||
adata = pci_get_drvdata(pci);
|
||||
if (adata->acp63_audio_mode == ACP63_PDM_MODE) {
|
||||
for (index = 0; index < ACP63_DEVS; index++)
|
||||
platform_device_unregister(adata->pdev[index]);
|
||||
}
|
||||
for (index = 0; index < adata->pdev_count; index++)
|
||||
platform_device_unregister(adata->pdev[index]);
|
||||
ret = acp63_deinit(adata->acp63_base, &pci->dev);
|
||||
if (ret)
|
||||
dev_err(&pci->dev, "ACP de-init failed\n");
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <sound/pcm_params.h>
|
||||
@ -18,6 +19,10 @@
|
||||
|
||||
#define DRV_NAME "acp_ps_pdm_dma"
|
||||
|
||||
static int pdm_gain = 3;
|
||||
module_param(pdm_gain, int, 0644);
|
||||
MODULE_PARM_DESC(pdm_gain, "Gain control (0-3)");
|
||||
|
||||
static const struct snd_pcm_hardware acp63_pdm_hardware_capture = {
|
||||
.info = SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
@ -55,26 +60,31 @@ static void acp63_enable_pdm_clock(void __iomem *acp_base)
|
||||
|
||||
acp63_writel(pdm_clk_enable, acp_base + ACP_WOV_CLK_CTRL);
|
||||
pdm_ctrl = acp63_readl(acp_base + ACP_WOV_MISC_CTRL);
|
||||
pdm_ctrl |= ACP_WOV_MISC_CTRL_MASK;
|
||||
pdm_ctrl &= ~ACP_WOV_GAIN_CONTROL;
|
||||
pdm_ctrl |= FIELD_PREP(ACP_WOV_GAIN_CONTROL, clamp(pdm_gain, 0, 3));
|
||||
acp63_writel(pdm_ctrl, acp_base + ACP_WOV_MISC_CTRL);
|
||||
}
|
||||
|
||||
static void acp63_enable_pdm_interrupts(void __iomem *acp_base)
|
||||
static void acp63_enable_pdm_interrupts(struct pdm_dev_data *adata)
|
||||
{
|
||||
u32 ext_int_ctrl;
|
||||
|
||||
ext_int_ctrl = acp63_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
|
||||
mutex_lock(adata->acp_lock);
|
||||
ext_int_ctrl = acp63_readl(adata->acp63_base + ACP_EXTERNAL_INTR_CNTL);
|
||||
ext_int_ctrl |= PDM_DMA_INTR_MASK;
|
||||
acp63_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
|
||||
acp63_writel(ext_int_ctrl, adata->acp63_base + ACP_EXTERNAL_INTR_CNTL);
|
||||
mutex_unlock(adata->acp_lock);
|
||||
}
|
||||
|
||||
static void acp63_disable_pdm_interrupts(void __iomem *acp_base)
|
||||
static void acp63_disable_pdm_interrupts(struct pdm_dev_data *adata)
|
||||
{
|
||||
u32 ext_int_ctrl;
|
||||
|
||||
ext_int_ctrl = acp63_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
|
||||
mutex_lock(adata->acp_lock);
|
||||
ext_int_ctrl = acp63_readl(adata->acp63_base + ACP_EXTERNAL_INTR_CNTL);
|
||||
ext_int_ctrl &= ~PDM_DMA_INTR_MASK;
|
||||
acp63_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
|
||||
acp63_writel(ext_int_ctrl, adata->acp63_base + ACP_EXTERNAL_INTR_CNTL);
|
||||
mutex_unlock(adata->acp_lock);
|
||||
}
|
||||
|
||||
static bool acp63_check_pdm_dma_status(void __iomem *acp_base)
|
||||
@ -196,7 +206,7 @@ static int acp63_pdm_dma_open(struct snd_soc_component *component,
|
||||
return ret;
|
||||
}
|
||||
|
||||
acp63_enable_pdm_interrupts(adata->acp63_base);
|
||||
acp63_enable_pdm_interrupts(adata);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
|
||||
adata->capture_stream = substream;
|
||||
@ -272,7 +282,7 @@ static int acp63_pdm_dma_close(struct snd_soc_component *component,
|
||||
struct pdm_dev_data *adata = dev_get_drvdata(component->dev);
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
|
||||
acp63_disable_pdm_interrupts(adata->acp63_base);
|
||||
acp63_disable_pdm_interrupts(adata);
|
||||
adata->capture_stream = NULL;
|
||||
kfree(runtime->private_data);
|
||||
return 0;
|
||||
@ -353,6 +363,10 @@ static int acp63_pdm_audio_probe(struct platform_device *pdev)
|
||||
struct pdm_dev_data *adata;
|
||||
int status;
|
||||
|
||||
if (!pdev->dev.platform_data) {
|
||||
dev_err(&pdev->dev, "platform_data not retrieved\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
|
||||
@ -368,7 +382,7 @@ static int acp63_pdm_audio_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
adata->capture_stream = NULL;
|
||||
|
||||
adata->acp_lock = pdev->dev.platform_data;
|
||||
dev_set_drvdata(&pdev->dev, adata);
|
||||
status = devm_snd_soc_register_component(&pdev->dev,
|
||||
&acp63_pdm_component,
|
||||
@ -408,7 +422,7 @@ static int __maybe_unused acp63_pdm_resume(struct device *dev)
|
||||
acp63_init_pdm_ring_buffer(PDM_MEM_WINDOW_START, buffer_len,
|
||||
period_bytes, adata->acp63_base);
|
||||
}
|
||||
acp63_enable_pdm_interrupts(adata->acp63_base);
|
||||
acp63_enable_pdm_interrupts(adata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -417,7 +431,7 @@ static int __maybe_unused acp63_pdm_suspend(struct device *dev)
|
||||
struct pdm_dev_data *adata;
|
||||
|
||||
adata = dev_get_drvdata(dev);
|
||||
acp63_disable_pdm_interrupts(adata->acp63_base);
|
||||
acp63_disable_pdm_interrupts(adata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -426,7 +440,7 @@ static int __maybe_unused acp63_pdm_runtime_resume(struct device *dev)
|
||||
struct pdm_dev_data *adata;
|
||||
|
||||
adata = dev_get_drvdata(dev);
|
||||
acp63_enable_pdm_interrupts(adata->acp63_base);
|
||||
acp63_enable_pdm_interrupts(adata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -315,16 +315,8 @@ static int acp3x_dai_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acp3x_dai_remove(struct platform_device *pdev)
|
||||
{
|
||||
/* As we use devm_ memory alloc there is nothing TBD here */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver acp3x_dai_driver = {
|
||||
.probe = acp3x_dai_probe,
|
||||
.remove = acp3x_dai_remove,
|
||||
.driver = {
|
||||
.name = "acp3x_i2s_playcap",
|
||||
},
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
@ -17,6 +18,10 @@
|
||||
|
||||
#define DRV_NAME "acp_rn_pdm_dma"
|
||||
|
||||
static int pdm_gain = 3;
|
||||
module_param(pdm_gain, int, 0644);
|
||||
MODULE_PARM_DESC(pdm_gain, "Gain control (0-3)");
|
||||
|
||||
static const struct snd_pcm_hardware acp_pdm_hardware_capture = {
|
||||
.info = SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
@ -80,7 +85,8 @@ static void enable_pdm_clock(void __iomem *acp_base)
|
||||
|
||||
rn_writel(pdm_clk_enable, acp_base + ACP_WOV_CLK_CTRL);
|
||||
pdm_ctrl = rn_readl(acp_base + ACP_WOV_MISC_CTRL);
|
||||
pdm_ctrl |= ACP_WOV_MISC_CTRL_MASK;
|
||||
pdm_ctrl &= ~ACP_WOV_GAIN_CONTROL;
|
||||
pdm_ctrl |= FIELD_PREP(ACP_WOV_GAIN_CONTROL, clamp(pdm_gain, 0, 3));
|
||||
rn_writel(pdm_ctrl, acp_base + ACP_WOV_MISC_CTRL);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
#define ACP_ERROR_STAT 29
|
||||
#define PDM_DECIMATION_FACTOR 0x2
|
||||
#define ACP_PDM_CLK_FREQ_MASK 0x07
|
||||
#define ACP_WOV_MISC_CTRL_MASK 0x10
|
||||
#define ACP_WOV_GAIN_CONTROL GENMASK(4, 3)
|
||||
#define ACP_PDM_ENABLE 0x01
|
||||
#define ACP_PDM_DISABLE 0x00
|
||||
#define ACP_PDM_DMA_EN_STATUS 0x02
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <sound/pcm_params.h>
|
||||
@ -18,6 +19,10 @@
|
||||
|
||||
#define DRV_NAME "acp_yc_pdm_dma"
|
||||
|
||||
static int pdm_gain = 3;
|
||||
module_param(pdm_gain, int, 0644);
|
||||
MODULE_PARM_DESC(pdm_gain, "Gain control (0-3)");
|
||||
|
||||
static const struct snd_pcm_hardware acp6x_pdm_hardware_capture = {
|
||||
.info = SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
@ -55,7 +60,8 @@ static void acp6x_enable_pdm_clock(void __iomem *acp_base)
|
||||
|
||||
acp6x_writel(pdm_clk_enable, acp_base + ACP_WOV_CLK_CTRL);
|
||||
pdm_ctrl = acp6x_readl(acp_base + ACP_WOV_MISC_CTRL);
|
||||
pdm_ctrl |= ACP_WOV_MISC_CTRL_MASK;
|
||||
pdm_ctrl &= ~ACP_WOV_GAIN_CONTROL;
|
||||
pdm_ctrl |= FIELD_PREP(ACP_WOV_GAIN_CONTROL, clamp(pdm_gain, 0, 3));
|
||||
acp6x_writel(pdm_ctrl, acp_base + ACP_WOV_MISC_CTRL);
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
#define ACP_ERROR_STAT 29
|
||||
#define PDM_DECIMATION_FACTOR 2
|
||||
#define ACP_PDM_CLK_FREQ_MASK 7
|
||||
#define ACP_WOV_MISC_CTRL_MASK 0x10
|
||||
#define ACP_WOV_GAIN_CONTROL GENMASK(4, 3)
|
||||
#define ACP_PDM_ENABLE 1
|
||||
#define ACP_PDM_DISABLE 0
|
||||
#define ACP_PDM_DMA_EN_STATUS 2
|
||||
|
@ -616,11 +616,6 @@ unregister_codec:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int atmel_classd_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver atmel_classd_driver = {
|
||||
.driver = {
|
||||
.name = "atmel-classd",
|
||||
@ -628,7 +623,6 @@ static struct platform_driver atmel_classd_driver = {
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = atmel_classd_probe,
|
||||
.remove = atmel_classd_remove,
|
||||
};
|
||||
module_platform_driver(atmel_classd_driver);
|
||||
|
||||
|
@ -692,11 +692,6 @@ unregister_codec:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int atmel_pdmic_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver atmel_pdmic_driver = {
|
||||
.driver = {
|
||||
.name = "atmel-pdmic",
|
||||
@ -704,7 +699,6 @@ static struct platform_driver atmel_pdmic_driver = {
|
||||
.pm = &snd_soc_pm_ops,
|
||||
},
|
||||
.probe = atmel_pdmic_probe,
|
||||
.remove = atmel_pdmic_remove,
|
||||
};
|
||||
module_platform_driver(atmel_pdmic_driver);
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
@ -112,10 +113,10 @@ struct mchp_pdmc {
|
||||
struct clk *pclk;
|
||||
struct clk *gclk;
|
||||
u32 pdmcen;
|
||||
u32 suspend_irq;
|
||||
int mic_no;
|
||||
int sinc_order;
|
||||
bool audio_filter_en;
|
||||
u8 gclk_enabled:1;
|
||||
};
|
||||
|
||||
static const char *const mchp_pdmc_sinc_filter_order_text[] = {
|
||||
@ -454,13 +455,6 @@ static int mchp_pdmc_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mchp_pdmc *dd = snd_soc_dai_get_drvdata(dai);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(dd->pclk);
|
||||
if (ret) {
|
||||
dev_err(dd->dev, "failed to enable the peripheral clock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
regmap_write(dd->regmap, MCHP_PDMC_CR, MCHP_PDMC_CR_SWRST);
|
||||
|
||||
@ -470,14 +464,6 @@ static int mchp_pdmc_startup(struct snd_pcm_substream *substream,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mchp_pdmc_shutdown(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mchp_pdmc *dd = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
clk_disable_unprepare(dd->pclk);
|
||||
}
|
||||
|
||||
static int mchp_pdmc_dai_probe(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mchp_pdmc *dd = snd_soc_dai_get_drvdata(dai);
|
||||
@ -594,11 +580,6 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
|
||||
cfgr_val |= MCHP_PDMC_CFGR_BSSEL(i);
|
||||
}
|
||||
|
||||
if (dd->gclk_enabled) {
|
||||
clk_disable_unprepare(dd->gclk);
|
||||
dd->gclk_enabled = 0;
|
||||
}
|
||||
|
||||
for (osr_start = dd->audio_filter_en ? 64 : 8;
|
||||
osr_start <= 256 && best_diff_rate; osr_start *= 2) {
|
||||
long round_rate;
|
||||
@ -620,8 +601,12 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* CLK is enabled by runtime PM. */
|
||||
clk_disable_unprepare(dd->gclk);
|
||||
|
||||
/* set the rate */
|
||||
ret = clk_set_rate(dd->gclk, gclk_rate);
|
||||
clk_prepare_enable(dd->gclk);
|
||||
if (ret) {
|
||||
dev_err(comp->dev, "unable to set rate %lu to GCLK: %d\n",
|
||||
gclk_rate, ret);
|
||||
@ -636,9 +621,6 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
|
||||
mr_val |= MCHP_PDMC_MR_CHUNK(dd->addr.maxburst);
|
||||
dev_dbg(comp->dev, "maxburst set to %d\n", dd->addr.maxburst);
|
||||
|
||||
clk_prepare_enable(dd->gclk);
|
||||
dd->gclk_enabled = 1;
|
||||
|
||||
snd_soc_component_update_bits(comp, MCHP_PDMC_MR,
|
||||
MCHP_PDMC_MR_OSR_MASK |
|
||||
MCHP_PDMC_MR_SINCORDER_MASK |
|
||||
@ -650,19 +632,6 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mchp_pdmc_hw_free(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mchp_pdmc *dd = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
if (dd->gclk_enabled) {
|
||||
clk_disable_unprepare(dd->gclk);
|
||||
dd->gclk_enabled = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mchp_pdmc_trigger(struct snd_pcm_substream *substream,
|
||||
int cmd, struct snd_soc_dai *dai)
|
||||
{
|
||||
@ -673,22 +642,27 @@ static int mchp_pdmc_trigger(struct snd_pcm_substream *substream,
|
||||
#endif
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
/* Enable overrun and underrun error interrupts */
|
||||
regmap_write(dd->regmap, MCHP_PDMC_IER,
|
||||
regmap_write(dd->regmap, MCHP_PDMC_IER, dd->suspend_irq |
|
||||
MCHP_PDMC_IR_RXOVR | MCHP_PDMC_IR_RXUDR);
|
||||
dd->suspend_irq = 0;
|
||||
fallthrough;
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
snd_soc_component_update_bits(cpu, MCHP_PDMC_MR,
|
||||
MCHP_PDMC_MR_PDMCEN_MASK,
|
||||
dd->pdmcen);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
regmap_read(dd->regmap, MCHP_PDMC_IMR, &dd->suspend_irq);
|
||||
fallthrough;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
/* Disable overrun and underrun error interrupts */
|
||||
regmap_write(dd->regmap, MCHP_PDMC_IDR,
|
||||
regmap_write(dd->regmap, MCHP_PDMC_IDR, dd->suspend_irq |
|
||||
MCHP_PDMC_IR_RXOVR | MCHP_PDMC_IR_RXUDR);
|
||||
fallthrough;
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
snd_soc_component_update_bits(cpu, MCHP_PDMC_MR,
|
||||
MCHP_PDMC_MR_PDMCEN_MASK, 0);
|
||||
break;
|
||||
@ -711,9 +685,7 @@ static int mchp_pdmc_trigger(struct snd_pcm_substream *substream,
|
||||
static const struct snd_soc_dai_ops mchp_pdmc_dai_ops = {
|
||||
.set_fmt = mchp_pdmc_set_fmt,
|
||||
.startup = mchp_pdmc_startup,
|
||||
.shutdown = mchp_pdmc_shutdown,
|
||||
.hw_params = mchp_pdmc_hw_params,
|
||||
.hw_free = mchp_pdmc_hw_free,
|
||||
.trigger = mchp_pdmc_trigger,
|
||||
};
|
||||
|
||||
@ -864,6 +836,7 @@ static const struct regmap_config mchp_pdmc_regmap_config = {
|
||||
.readable_reg = mchp_pdmc_readable_reg,
|
||||
.writeable_reg = mchp_pdmc_writeable_reg,
|
||||
.precious_reg = mchp_pdmc_precious_reg,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static int mchp_pdmc_dt_init(struct mchp_pdmc *dd)
|
||||
@ -970,6 +943,49 @@ static struct snd_dmaengine_pcm_config mchp_pdmc_config = {
|
||||
.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
|
||||
};
|
||||
|
||||
static int mchp_pdmc_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct mchp_pdmc *dd = dev_get_drvdata(dev);
|
||||
|
||||
regcache_cache_only(dd->regmap, true);
|
||||
|
||||
clk_disable_unprepare(dd->gclk);
|
||||
clk_disable_unprepare(dd->pclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mchp_pdmc_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct mchp_pdmc *dd = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(dd->pclk);
|
||||
if (ret) {
|
||||
dev_err(dd->dev,
|
||||
"failed to enable the peripheral clock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = clk_prepare_enable(dd->gclk);
|
||||
if (ret) {
|
||||
dev_err(dd->dev,
|
||||
"failed to enable generic clock: %d\n", ret);
|
||||
goto disable_pclk;
|
||||
}
|
||||
|
||||
regcache_cache_only(dd->regmap, false);
|
||||
regcache_mark_dirty(dd->regmap);
|
||||
ret = regcache_sync(dd->regmap);
|
||||
if (ret) {
|
||||
regcache_cache_only(dd->regmap, true);
|
||||
clk_disable_unprepare(dd->gclk);
|
||||
disable_pclk:
|
||||
clk_disable_unprepare(dd->pclk);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mchp_pdmc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@ -1039,18 +1055,25 @@ static int mchp_pdmc_probe(struct platform_device *pdev)
|
||||
dd->addr.addr = (dma_addr_t)res->start + MCHP_PDMC_RHR;
|
||||
platform_set_drvdata(pdev, dd);
|
||||
|
||||
pm_runtime_enable(dd->dev);
|
||||
if (!pm_runtime_enabled(dd->dev)) {
|
||||
ret = mchp_pdmc_runtime_resume(dd->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* register platform */
|
||||
ret = devm_snd_dmaengine_pcm_register(dev, &mchp_pdmc_config, 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "could not register platform: %d\n", ret);
|
||||
return ret;
|
||||
goto pm_runtime_suspend;
|
||||
}
|
||||
|
||||
ret = devm_snd_soc_register_component(dev, &mchp_pdmc_dai_component,
|
||||
&mchp_pdmc_dai, 1);
|
||||
if (ret) {
|
||||
dev_err(dev, "could not register CPU DAI: %d\n", ret);
|
||||
return ret;
|
||||
goto pm_runtime_suspend;
|
||||
}
|
||||
|
||||
/* print IP version */
|
||||
@ -1059,6 +1082,25 @@ static int mchp_pdmc_probe(struct platform_device *pdev)
|
||||
version & MCHP_PDMC_VER_VERSION);
|
||||
|
||||
return 0;
|
||||
|
||||
pm_runtime_suspend:
|
||||
if (!pm_runtime_status_suspended(dd->dev))
|
||||
mchp_pdmc_runtime_suspend(dd->dev);
|
||||
pm_runtime_disable(dd->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mchp_pdmc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mchp_pdmc *dd = platform_get_drvdata(pdev);
|
||||
|
||||
if (!pm_runtime_status_suspended(dd->dev))
|
||||
mchp_pdmc_runtime_suspend(dd->dev);
|
||||
|
||||
pm_runtime_disable(dd->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id mchp_pdmc_of_match[] = {
|
||||
@ -1070,13 +1112,20 @@ static const struct of_device_id mchp_pdmc_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mchp_pdmc_of_match);
|
||||
|
||||
static const struct dev_pm_ops mchp_pdmc_pm_ops = {
|
||||
SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
|
||||
RUNTIME_PM_OPS(mchp_pdmc_runtime_suspend, mchp_pdmc_runtime_resume,
|
||||
NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver mchp_pdmc_driver = {
|
||||
.driver = {
|
||||
.name = "mchp-pdmc",
|
||||
.of_match_table = of_match_ptr(mchp_pdmc_of_match),
|
||||
.pm = &snd_soc_pm_ops,
|
||||
.pm = pm_ptr(&mchp_pdmc_pm_ops),
|
||||
},
|
||||
.probe = mchp_pdmc_probe,
|
||||
.remove = mchp_pdmc_remove,
|
||||
};
|
||||
module_platform_driver(mchp_pdmc_driver);
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
@ -192,6 +193,43 @@ static bool mchp_spdifrx_precious_reg(struct device *dev, unsigned int reg)
|
||||
}
|
||||
}
|
||||
|
||||
static bool mchp_spdifrx_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case SPDIFRX_IMR:
|
||||
case SPDIFRX_ISR:
|
||||
case SPDIFRX_RSR:
|
||||
case SPDIFRX_CHSR(0, 0):
|
||||
case SPDIFRX_CHSR(0, 1):
|
||||
case SPDIFRX_CHSR(0, 2):
|
||||
case SPDIFRX_CHSR(0, 3):
|
||||
case SPDIFRX_CHSR(0, 4):
|
||||
case SPDIFRX_CHSR(0, 5):
|
||||
case SPDIFRX_CHUD(0, 0):
|
||||
case SPDIFRX_CHUD(0, 1):
|
||||
case SPDIFRX_CHUD(0, 2):
|
||||
case SPDIFRX_CHUD(0, 3):
|
||||
case SPDIFRX_CHUD(0, 4):
|
||||
case SPDIFRX_CHUD(0, 5):
|
||||
case SPDIFRX_CHSR(1, 0):
|
||||
case SPDIFRX_CHSR(1, 1):
|
||||
case SPDIFRX_CHSR(1, 2):
|
||||
case SPDIFRX_CHSR(1, 3):
|
||||
case SPDIFRX_CHSR(1, 4):
|
||||
case SPDIFRX_CHSR(1, 5):
|
||||
case SPDIFRX_CHUD(1, 0):
|
||||
case SPDIFRX_CHUD(1, 1):
|
||||
case SPDIFRX_CHUD(1, 2):
|
||||
case SPDIFRX_CHUD(1, 3):
|
||||
case SPDIFRX_CHUD(1, 4):
|
||||
case SPDIFRX_CHUD(1, 5):
|
||||
case SPDIFRX_VERSION:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct regmap_config mchp_spdifrx_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
@ -200,6 +238,8 @@ static const struct regmap_config mchp_spdifrx_regmap_config = {
|
||||
.readable_reg = mchp_spdifrx_readable_reg,
|
||||
.writeable_reg = mchp_spdifrx_writeable_reg,
|
||||
.precious_reg = mchp_spdifrx_precious_reg,
|
||||
.volatile_reg = mchp_spdifrx_volatile_reg,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
#define SPDIFRX_GCLK_RATIO_MIN (12 * 64)
|
||||
@ -209,17 +249,34 @@ static const struct regmap_config mchp_spdifrx_regmap_config = {
|
||||
|
||||
#define SPDIFRX_CHANNELS 2
|
||||
|
||||
/**
|
||||
* struct mchp_spdifrx_ch_stat: MCHP SPDIFRX channel status
|
||||
* @data: channel status bits
|
||||
* @done: completion to signal channel status bits acquisition done
|
||||
*/
|
||||
struct mchp_spdifrx_ch_stat {
|
||||
unsigned char data[SPDIFRX_CS_BITS / 8];
|
||||
struct completion done;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mchp_spdifrx_user_data: MCHP SPDIFRX user data
|
||||
* @data: user data bits
|
||||
* @done: completion to signal user data bits acquisition done
|
||||
*/
|
||||
struct mchp_spdifrx_user_data {
|
||||
unsigned char data[SPDIFRX_UD_BITS / 8];
|
||||
struct completion done;
|
||||
spinlock_t lock; /* protect access to user data */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mchp_spdifrx_mixer_control: MCHP SPDIFRX mixer control data structure
|
||||
* @ch_stat: array of channel statuses
|
||||
* @user_data: array of user data
|
||||
* @ulock: ulock bit status
|
||||
* @badf: badf bit status
|
||||
* @signal: signal bit status
|
||||
*/
|
||||
struct mchp_spdifrx_mixer_control {
|
||||
struct mchp_spdifrx_ch_stat ch_stat[SPDIFRX_CHANNELS];
|
||||
struct mchp_spdifrx_user_data user_data[SPDIFRX_CHANNELS];
|
||||
@ -228,17 +285,26 @@ struct mchp_spdifrx_mixer_control {
|
||||
bool signal;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mchp_spdifrx_dev: MCHP SPDIFRX device data structure
|
||||
* @capture: DAI DMA configuration data
|
||||
* @control: mixer controls
|
||||
* @mlock: mutex to protect concurency b/w configuration and control APIs
|
||||
* @dev: struct device
|
||||
* @regmap: regmap for this device
|
||||
* @pclk: peripheral clock
|
||||
* @gclk: generic clock
|
||||
* @trigger_enabled: true if enabled though trigger() ops
|
||||
*/
|
||||
struct mchp_spdifrx_dev {
|
||||
struct snd_dmaengine_dai_dma_data capture;
|
||||
struct mchp_spdifrx_mixer_control control;
|
||||
spinlock_t blockend_lock; /* protect access to blockend_refcount */
|
||||
int blockend_refcount;
|
||||
struct mutex mlock;
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct clk *pclk;
|
||||
struct clk *gclk;
|
||||
unsigned int fmt;
|
||||
unsigned int gclk_enabled:1;
|
||||
unsigned int trigger_enabled;
|
||||
};
|
||||
|
||||
static void mchp_spdifrx_channel_status_read(struct mchp_spdifrx_dev *dev,
|
||||
@ -275,37 +341,11 @@ static void mchp_spdifrx_channel_user_data_read(struct mchp_spdifrx_dev *dev,
|
||||
}
|
||||
}
|
||||
|
||||
/* called from non-atomic context only */
|
||||
static void mchp_spdifrx_isr_blockend_en(struct mchp_spdifrx_dev *dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dev->blockend_lock, flags);
|
||||
dev->blockend_refcount++;
|
||||
/* don't enable BLOCKEND interrupt if it's already enabled */
|
||||
if (dev->blockend_refcount == 1)
|
||||
regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_BLOCKEND);
|
||||
spin_unlock_irqrestore(&dev->blockend_lock, flags);
|
||||
}
|
||||
|
||||
/* called from atomic/non-atomic context */
|
||||
static void mchp_spdifrx_isr_blockend_dis(struct mchp_spdifrx_dev *dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dev->blockend_lock, flags);
|
||||
dev->blockend_refcount--;
|
||||
/* don't enable BLOCKEND interrupt if it's already enabled */
|
||||
if (dev->blockend_refcount == 0)
|
||||
regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND);
|
||||
spin_unlock_irqrestore(&dev->blockend_lock, flags);
|
||||
}
|
||||
|
||||
static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct mchp_spdifrx_dev *dev = dev_id;
|
||||
struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
|
||||
u32 sr, imr, pending, idr = 0;
|
||||
u32 sr, imr, pending;
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
int ch;
|
||||
|
||||
@ -320,13 +360,10 @@ static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id)
|
||||
|
||||
if (pending & SPDIFRX_IR_BLOCKEND) {
|
||||
for (ch = 0; ch < SPDIFRX_CHANNELS; ch++) {
|
||||
spin_lock(&ctrl->user_data[ch].lock);
|
||||
mchp_spdifrx_channel_user_data_read(dev, ch);
|
||||
spin_unlock(&ctrl->user_data[ch].lock);
|
||||
|
||||
complete(&ctrl->user_data[ch].done);
|
||||
}
|
||||
mchp_spdifrx_isr_blockend_dis(dev);
|
||||
regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND);
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -334,7 +371,7 @@ static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id)
|
||||
if (pending & SPDIFRX_IR_CSC(ch)) {
|
||||
mchp_spdifrx_channel_status_read(dev, ch);
|
||||
complete(&ctrl->ch_stat[ch].done);
|
||||
idr |= SPDIFRX_IR_CSC(ch);
|
||||
regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_CSC(ch));
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
}
|
||||
@ -344,8 +381,6 @@ static irqreturn_t mchp_spdif_interrupt(int irq, void *dev_id)
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
regmap_write(dev->regmap, SPDIFRX_IDR, idr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -353,47 +388,40 @@ static int mchp_spdifrx_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
|
||||
u32 mr;
|
||||
int running;
|
||||
int ret;
|
||||
|
||||
regmap_read(dev->regmap, SPDIFRX_MR, &mr);
|
||||
running = !!(mr & SPDIFRX_MR_RXEN_ENABLE);
|
||||
int ret = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
if (!running) {
|
||||
mr &= ~SPDIFRX_MR_RXEN_MASK;
|
||||
mr |= SPDIFRX_MR_RXEN_ENABLE;
|
||||
/* enable overrun interrupts */
|
||||
regmap_write(dev->regmap, SPDIFRX_IER,
|
||||
SPDIFRX_IR_OVERRUN);
|
||||
}
|
||||
mutex_lock(&dev->mlock);
|
||||
/* Enable overrun interrupts */
|
||||
regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_OVERRUN);
|
||||
|
||||
/* Enable receiver. */
|
||||
regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK,
|
||||
SPDIFRX_MR_RXEN_ENABLE);
|
||||
dev->trigger_enabled = true;
|
||||
mutex_unlock(&dev->mlock);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
if (running) {
|
||||
mr &= ~SPDIFRX_MR_RXEN_MASK;
|
||||
mr |= SPDIFRX_MR_RXEN_DISABLE;
|
||||
/* disable overrun interrupts */
|
||||
regmap_write(dev->regmap, SPDIFRX_IDR,
|
||||
SPDIFRX_IR_OVERRUN);
|
||||
}
|
||||
mutex_lock(&dev->mlock);
|
||||
/* Disable overrun interrupts */
|
||||
regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_OVERRUN);
|
||||
|
||||
/* Disable receiver. */
|
||||
regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK,
|
||||
SPDIFRX_MR_RXEN_DISABLE);
|
||||
dev->trigger_enabled = false;
|
||||
mutex_unlock(&dev->mlock);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
ret = regmap_write(dev->regmap, SPDIFRX_MR, mr);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "unable to enable/disable RX: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream,
|
||||
@ -401,7 +429,7 @@ static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
|
||||
u32 mr;
|
||||
u32 mr = 0;
|
||||
int ret;
|
||||
|
||||
dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u\n",
|
||||
@ -413,13 +441,6 @@ static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regmap_read(dev->regmap, SPDIFRX_MR, &mr);
|
||||
|
||||
if (mr & SPDIFRX_MR_RXEN_ENABLE) {
|
||||
dev_err(dev->dev, "PCM already running\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (params_channels(params) != SPDIFRX_CHANNELS) {
|
||||
dev_err(dev->dev, "unsupported number of channels: %d\n",
|
||||
params_channels(params));
|
||||
@ -445,47 +466,46 @@ static int mchp_spdifrx_hw_params(struct snd_pcm_substream *substream,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dev->gclk_enabled) {
|
||||
clk_disable_unprepare(dev->gclk);
|
||||
dev->gclk_enabled = 0;
|
||||
mutex_lock(&dev->mlock);
|
||||
if (dev->trigger_enabled) {
|
||||
dev_err(dev->dev, "PCM already running\n");
|
||||
ret = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* GCLK is enabled by runtime PM. */
|
||||
clk_disable_unprepare(dev->gclk);
|
||||
|
||||
ret = clk_set_min_rate(dev->gclk, params_rate(params) *
|
||||
SPDIFRX_GCLK_RATIO_MIN + 1);
|
||||
if (ret) {
|
||||
dev_err(dev->dev,
|
||||
"unable to set gclk min rate: rate %u * ratio %u + 1\n",
|
||||
params_rate(params), SPDIFRX_GCLK_RATIO_MIN);
|
||||
return ret;
|
||||
/* Restore runtime PM state. */
|
||||
clk_prepare_enable(dev->gclk);
|
||||
goto unlock;
|
||||
}
|
||||
ret = clk_prepare_enable(dev->gclk);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "unable to enable gclk: %d\n", ret);
|
||||
return ret;
|
||||
goto unlock;
|
||||
}
|
||||
dev->gclk_enabled = 1;
|
||||
|
||||
dev_dbg(dev->dev, "GCLK range min set to %d\n",
|
||||
params_rate(params) * SPDIFRX_GCLK_RATIO_MIN + 1);
|
||||
|
||||
return regmap_write(dev->regmap, SPDIFRX_MR, mr);
|
||||
}
|
||||
ret = regmap_write(dev->regmap, SPDIFRX_MR, mr);
|
||||
|
||||
static int mchp_spdifrx_hw_free(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
|
||||
unlock:
|
||||
mutex_unlock(&dev->mlock);
|
||||
|
||||
if (dev->gclk_enabled) {
|
||||
clk_disable_unprepare(dev->gclk);
|
||||
dev->gclk_enabled = 0;
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops mchp_spdifrx_dai_ops = {
|
||||
.trigger = mchp_spdifrx_trigger,
|
||||
.hw_params = mchp_spdifrx_hw_params,
|
||||
.hw_free = mchp_spdifrx_hw_free,
|
||||
};
|
||||
|
||||
#define MCHP_SPDIF_RATES SNDRV_PCM_RATE_8000_192000
|
||||
@ -515,22 +535,58 @@ static int mchp_spdifrx_cs_get(struct mchp_spdifrx_dev *dev,
|
||||
{
|
||||
struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
|
||||
struct mchp_spdifrx_ch_stat *ch_stat = &ctrl->ch_stat[channel];
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_CSC(channel));
|
||||
/* check for new data available */
|
||||
ret = wait_for_completion_interruptible_timeout(&ch_stat->done,
|
||||
msecs_to_jiffies(100));
|
||||
/* IP might not be started or valid stream might not be present */
|
||||
if (ret < 0) {
|
||||
dev_dbg(dev->dev, "channel status for channel %d timeout\n",
|
||||
channel);
|
||||
mutex_lock(&dev->mlock);
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev->dev);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
|
||||
/*
|
||||
* We may reach this point with both clocks enabled but the receiver
|
||||
* still disabled. To void waiting for completion and return with
|
||||
* timeout check the dev->trigger_enabled.
|
||||
*
|
||||
* To retrieve data:
|
||||
* - if the receiver is enabled CSC IRQ will update the data in software
|
||||
* caches (ch_stat->data)
|
||||
* - otherwise we just update it here the software caches with latest
|
||||
* available information and return it; in this case we don't need
|
||||
* spin locking as the IRQ is disabled and will not be raised from
|
||||
* anywhere else.
|
||||
*/
|
||||
|
||||
if (dev->trigger_enabled) {
|
||||
reinit_completion(&ch_stat->done);
|
||||
regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_CSC(channel));
|
||||
/* Check for new data available */
|
||||
ret = wait_for_completion_interruptible_timeout(&ch_stat->done,
|
||||
msecs_to_jiffies(100));
|
||||
/* Valid stream might not be present */
|
||||
if (ret <= 0) {
|
||||
dev_dbg(dev->dev, "channel status for channel %d timeout\n",
|
||||
channel);
|
||||
regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_CSC(channel));
|
||||
ret = ret ? : -ETIMEDOUT;
|
||||
goto pm_runtime_put;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
} else {
|
||||
/* Update software cache with latest channel status. */
|
||||
mchp_spdifrx_channel_status_read(dev, channel);
|
||||
}
|
||||
|
||||
memcpy(uvalue->value.iec958.status, ch_stat->data,
|
||||
sizeof(ch_stat->data));
|
||||
|
||||
return 0;
|
||||
pm_runtime_put:
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
unlock:
|
||||
mutex_unlock(&dev->mlock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mchp_spdifrx_cs1_get(struct snd_kcontrol *kcontrol,
|
||||
@ -564,29 +620,56 @@ static int mchp_spdifrx_subcode_ch_get(struct mchp_spdifrx_dev *dev,
|
||||
int channel,
|
||||
struct snd_ctl_elem_value *uvalue)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
|
||||
struct mchp_spdifrx_user_data *user_data = &ctrl->user_data[channel];
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
reinit_completion(&user_data->done);
|
||||
mchp_spdifrx_isr_blockend_en(dev);
|
||||
ret = wait_for_completion_interruptible_timeout(&user_data->done,
|
||||
msecs_to_jiffies(100));
|
||||
/* IP might not be started or valid stream might not be present */
|
||||
if (ret <= 0) {
|
||||
dev_dbg(dev->dev, "user data for channel %d timeout\n",
|
||||
channel);
|
||||
mchp_spdifrx_isr_blockend_dis(dev);
|
||||
return ret;
|
||||
mutex_lock(&dev->mlock);
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev->dev);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
|
||||
/*
|
||||
* We may reach this point with both clocks enabled but the receiver
|
||||
* still disabled. To void waiting for completion to just timeout we
|
||||
* check here the dev->trigger_enabled flag.
|
||||
*
|
||||
* To retrieve data:
|
||||
* - if the receiver is enabled we need to wait for blockend IRQ to read
|
||||
* data to and update it for us in software caches
|
||||
* - otherwise reading the SPDIFRX_CHUD() registers is enough.
|
||||
*/
|
||||
|
||||
if (dev->trigger_enabled) {
|
||||
reinit_completion(&user_data->done);
|
||||
regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_BLOCKEND);
|
||||
ret = wait_for_completion_interruptible_timeout(&user_data->done,
|
||||
msecs_to_jiffies(100));
|
||||
/* Valid stream might not be present. */
|
||||
if (ret <= 0) {
|
||||
dev_dbg(dev->dev, "user data for channel %d timeout\n",
|
||||
channel);
|
||||
regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND);
|
||||
ret = ret ? : -ETIMEDOUT;
|
||||
goto pm_runtime_put;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
} else {
|
||||
/* Update software cache with last available data. */
|
||||
mchp_spdifrx_channel_user_data_read(dev, channel);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&user_data->lock, flags);
|
||||
memcpy(uvalue->value.iec958.subcode, user_data->data,
|
||||
sizeof(user_data->data));
|
||||
spin_unlock_irqrestore(&user_data->lock, flags);
|
||||
|
||||
return 0;
|
||||
pm_runtime_put:
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
unlock:
|
||||
mutex_unlock(&dev->mlock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mchp_spdifrx_subcode_ch1_get(struct snd_kcontrol *kcontrol,
|
||||
@ -625,12 +708,34 @@ static int mchp_spdifrx_ulock_get(struct snd_kcontrol *kcontrol,
|
||||
struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
|
||||
struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
|
||||
u32 val;
|
||||
int ret;
|
||||
bool ulock_old = ctrl->ulock;
|
||||
|
||||
regmap_read(dev->regmap, SPDIFRX_RSR, &val);
|
||||
ctrl->ulock = !(val & SPDIFRX_RSR_ULOCK);
|
||||
mutex_lock(&dev->mlock);
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev->dev);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
|
||||
/*
|
||||
* The RSR.ULOCK has wrong value if both pclk and gclk are enabled
|
||||
* and the receiver is disabled. Thus we take into account the
|
||||
* dev->trigger_enabled here to return a real status.
|
||||
*/
|
||||
if (dev->trigger_enabled) {
|
||||
regmap_read(dev->regmap, SPDIFRX_RSR, &val);
|
||||
ctrl->ulock = !(val & SPDIFRX_RSR_ULOCK);
|
||||
} else {
|
||||
ctrl->ulock = 0;
|
||||
}
|
||||
|
||||
uvalue->value.integer.value[0] = ctrl->ulock;
|
||||
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
unlock:
|
||||
mutex_unlock(&dev->mlock);
|
||||
|
||||
return ulock_old != ctrl->ulock;
|
||||
}
|
||||
|
||||
@ -641,10 +746,32 @@ static int mchp_spdifrx_badf_get(struct snd_kcontrol *kcontrol,
|
||||
struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
|
||||
struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
|
||||
u32 val;
|
||||
int ret;
|
||||
bool badf_old = ctrl->badf;
|
||||
|
||||
regmap_read(dev->regmap, SPDIFRX_RSR, &val);
|
||||
ctrl->badf = !!(val & SPDIFRX_RSR_BADF);
|
||||
mutex_lock(&dev->mlock);
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev->dev);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
|
||||
/*
|
||||
* The RSR.ULOCK has wrong value if both pclk and gclk are enabled
|
||||
* and the receiver is disabled. Thus we take into account the
|
||||
* dev->trigger_enabled here to return a real status.
|
||||
*/
|
||||
if (dev->trigger_enabled) {
|
||||
regmap_read(dev->regmap, SPDIFRX_RSR, &val);
|
||||
ctrl->badf = !!(val & SPDIFRX_RSR_BADF);
|
||||
} else {
|
||||
ctrl->badf = 0;
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
unlock:
|
||||
mutex_unlock(&dev->mlock);
|
||||
|
||||
uvalue->value.integer.value[0] = ctrl->badf;
|
||||
|
||||
return badf_old != ctrl->badf;
|
||||
@ -656,11 +783,49 @@ static int mchp_spdifrx_signal_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
|
||||
struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
|
||||
struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
|
||||
u32 val;
|
||||
u32 val = ~0U, loops = 10;
|
||||
int ret;
|
||||
bool signal_old = ctrl->signal;
|
||||
|
||||
regmap_read(dev->regmap, SPDIFRX_RSR, &val);
|
||||
ctrl->signal = !(val & SPDIFRX_RSR_NOSIGNAL);
|
||||
mutex_lock(&dev->mlock);
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev->dev);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
|
||||
/*
|
||||
* To get the signal we need to have receiver enabled. This
|
||||
* could be enabled also from trigger() function thus we need to
|
||||
* take care of not disabling the receiver when it runs.
|
||||
*/
|
||||
if (!dev->trigger_enabled) {
|
||||
regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK,
|
||||
SPDIFRX_MR_RXEN_ENABLE);
|
||||
|
||||
/* Wait for RSR.ULOCK bit. */
|
||||
while (--loops) {
|
||||
regmap_read(dev->regmap, SPDIFRX_RSR, &val);
|
||||
if (!(val & SPDIFRX_RSR_ULOCK))
|
||||
break;
|
||||
usleep_range(100, 150);
|
||||
}
|
||||
|
||||
regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK,
|
||||
SPDIFRX_MR_RXEN_DISABLE);
|
||||
} else {
|
||||
regmap_read(dev->regmap, SPDIFRX_RSR, &val);
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&dev->mlock);
|
||||
|
||||
if (!(val & SPDIFRX_RSR_ULOCK))
|
||||
ctrl->signal = !(val & SPDIFRX_RSR_NOSIGNAL);
|
||||
else
|
||||
ctrl->signal = 0;
|
||||
uvalue->value.integer.value[0] = ctrl->signal;
|
||||
|
||||
return signal_old != ctrl->signal;
|
||||
@ -682,22 +847,44 @@ static int mchp_spdifrx_rate_get(struct snd_kcontrol *kcontrol,
|
||||
{
|
||||
struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
|
||||
struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
|
||||
unsigned long rate;
|
||||
u32 val;
|
||||
int rate;
|
||||
int ret;
|
||||
|
||||
regmap_read(dev->regmap, SPDIFRX_RSR, &val);
|
||||
mutex_lock(&dev->mlock);
|
||||
|
||||
/* if the receiver is not locked, ISF data is invalid */
|
||||
if (val & SPDIFRX_RSR_ULOCK || !(val & SPDIFRX_RSR_IFS_MASK)) {
|
||||
ret = pm_runtime_resume_and_get(dev->dev);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
|
||||
/*
|
||||
* The RSR.ULOCK has wrong value if both pclk and gclk are enabled
|
||||
* and the receiver is disabled. Thus we take into account the
|
||||
* dev->trigger_enabled here to return a real status.
|
||||
*/
|
||||
if (dev->trigger_enabled) {
|
||||
regmap_read(dev->regmap, SPDIFRX_RSR, &val);
|
||||
/* If the receiver is not locked, ISF data is invalid. */
|
||||
if (val & SPDIFRX_RSR_ULOCK || !(val & SPDIFRX_RSR_IFS_MASK)) {
|
||||
ucontrol->value.integer.value[0] = 0;
|
||||
goto pm_runtime_put;
|
||||
}
|
||||
} else {
|
||||
/* Reveicer is not locked, IFS data is invalid. */
|
||||
ucontrol->value.integer.value[0] = 0;
|
||||
return 0;
|
||||
goto pm_runtime_put;
|
||||
}
|
||||
|
||||
rate = clk_get_rate(dev->gclk);
|
||||
|
||||
ucontrol->value.integer.value[0] = rate / (32 * SPDIFRX_RSR_IFS(val));
|
||||
|
||||
return 0;
|
||||
pm_runtime_put:
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
unlock:
|
||||
mutex_unlock(&dev->mlock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new mchp_spdifrx_ctrls[] = {
|
||||
@ -787,14 +974,6 @@ static int mchp_spdifrx_dai_probe(struct snd_soc_dai *dai)
|
||||
struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
|
||||
struct mchp_spdifrx_mixer_control *ctrl = &dev->control;
|
||||
int ch;
|
||||
int err;
|
||||
|
||||
err = clk_prepare_enable(dev->pclk);
|
||||
if (err) {
|
||||
dev_err(dev->dev,
|
||||
"failed to enable the peripheral clock: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
snd_soc_dai_init_dma_data(dai, NULL, &dev->capture);
|
||||
|
||||
@ -808,11 +987,9 @@ static int mchp_spdifrx_dai_probe(struct snd_soc_dai *dai)
|
||||
SPDIFRX_MR_AUTORST_NOACTION |
|
||||
SPDIFRX_MR_PACK_DISABLED);
|
||||
|
||||
dev->blockend_refcount = 0;
|
||||
for (ch = 0; ch < SPDIFRX_CHANNELS; ch++) {
|
||||
init_completion(&ctrl->ch_stat[ch].done);
|
||||
init_completion(&ctrl->user_data[ch].done);
|
||||
spin_lock_init(&ctrl->user_data[ch].lock);
|
||||
}
|
||||
|
||||
/* Add controls */
|
||||
@ -827,9 +1004,7 @@ static int mchp_spdifrx_dai_remove(struct snd_soc_dai *dai)
|
||||
struct mchp_spdifrx_dev *dev = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
/* Disable interrupts */
|
||||
regmap_write(dev->regmap, SPDIFRX_IDR, 0xFF);
|
||||
|
||||
clk_disable_unprepare(dev->pclk);
|
||||
regmap_write(dev->regmap, SPDIFRX_IDR, GENMASK(14, 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -861,6 +1036,48 @@ static const struct of_device_id mchp_spdifrx_dt_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mchp_spdifrx_dt_ids);
|
||||
|
||||
static int mchp_spdifrx_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct mchp_spdifrx_dev *spdifrx = dev_get_drvdata(dev);
|
||||
|
||||
regcache_cache_only(spdifrx->regmap, true);
|
||||
clk_disable_unprepare(spdifrx->gclk);
|
||||
clk_disable_unprepare(spdifrx->pclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mchp_spdifrx_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct mchp_spdifrx_dev *spdifrx = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(spdifrx->pclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_prepare_enable(spdifrx->gclk);
|
||||
if (ret)
|
||||
goto disable_pclk;
|
||||
|
||||
regcache_cache_only(spdifrx->regmap, false);
|
||||
regcache_mark_dirty(spdifrx->regmap);
|
||||
ret = regcache_sync(spdifrx->regmap);
|
||||
if (ret) {
|
||||
regcache_cache_only(spdifrx->regmap, true);
|
||||
clk_disable_unprepare(spdifrx->gclk);
|
||||
disable_pclk:
|
||||
clk_disable_unprepare(spdifrx->pclk);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops mchp_spdifrx_pm_ops = {
|
||||
RUNTIME_PM_OPS(mchp_spdifrx_runtime_suspend, mchp_spdifrx_runtime_resume,
|
||||
NULL)
|
||||
};
|
||||
|
||||
static int mchp_spdifrx_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mchp_spdifrx_dev *dev;
|
||||
@ -913,19 +1130,36 @@ static int mchp_spdifrx_probe(struct platform_device *pdev)
|
||||
"failed to get the PMC generated clock: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
spin_lock_init(&dev->blockend_lock);
|
||||
|
||||
/*
|
||||
* Signal control need a valid rate on gclk. hw_params() configures
|
||||
* it propertly but requesting signal before any hw_params() has been
|
||||
* called lead to invalid value returned for signal. Thus, configure
|
||||
* gclk at a valid rate, here, in initialization, to simplify the
|
||||
* control path.
|
||||
*/
|
||||
clk_set_min_rate(dev->gclk, 48000 * SPDIFRX_GCLK_RATIO_MIN + 1);
|
||||
|
||||
mutex_init(&dev->mlock);
|
||||
|
||||
dev->dev = &pdev->dev;
|
||||
dev->regmap = regmap;
|
||||
platform_set_drvdata(pdev, dev);
|
||||
|
||||
pm_runtime_enable(dev->dev);
|
||||
if (!pm_runtime_enabled(dev->dev)) {
|
||||
err = mchp_spdifrx_runtime_resume(dev->dev);
|
||||
if (err)
|
||||
goto pm_runtime_disable;
|
||||
}
|
||||
|
||||
dev->capture.addr = (dma_addr_t)mem->start + SPDIFRX_RHR;
|
||||
dev->capture.maxburst = 1;
|
||||
|
||||
err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "failed to register PCM: %d\n", err);
|
||||
return err;
|
||||
goto pm_runtime_suspend;
|
||||
}
|
||||
|
||||
err = devm_snd_soc_register_component(&pdev->dev,
|
||||
@ -933,20 +1167,40 @@ static int mchp_spdifrx_probe(struct platform_device *pdev)
|
||||
&mchp_spdifrx_dai, 1);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "fail to register dai\n");
|
||||
return err;
|
||||
goto pm_runtime_suspend;
|
||||
}
|
||||
|
||||
regmap_read(regmap, SPDIFRX_VERSION, &vers);
|
||||
dev_info(&pdev->dev, "hw version: %#lx\n", vers & SPDIFRX_VERSION_MASK);
|
||||
|
||||
return 0;
|
||||
|
||||
pm_runtime_suspend:
|
||||
if (!pm_runtime_status_suspended(dev->dev))
|
||||
mchp_spdifrx_runtime_suspend(dev->dev);
|
||||
pm_runtime_disable:
|
||||
pm_runtime_disable(dev->dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mchp_spdifrx_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mchp_spdifrx_dev *dev = platform_get_drvdata(pdev);
|
||||
|
||||
pm_runtime_disable(dev->dev);
|
||||
if (!pm_runtime_status_suspended(dev->dev))
|
||||
mchp_spdifrx_runtime_suspend(dev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver mchp_spdifrx_driver = {
|
||||
.probe = mchp_spdifrx_probe,
|
||||
.remove = mchp_spdifrx_remove,
|
||||
.driver = {
|
||||
.name = "mchp_spdifrx",
|
||||
.of_match_table = of_match_ptr(mchp_spdifrx_dt_ids),
|
||||
.pm = pm_ptr(&mchp_spdifrx_pm_ops),
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
//
|
||||
// Author: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
@ -71,11 +72,11 @@
|
||||
|
||||
/* Valid Bits per Sample */
|
||||
#define SPDIFTX_MR_VBPS_MASK GENMASK(13, 8)
|
||||
#define SPDIFTX_MR_VBPS(bps) (((bps) << 8) & SPDIFTX_MR_VBPS_MASK)
|
||||
#define SPDIFTX_MR_VBPS(bps) FIELD_PREP(SPDIFTX_MR_VBPS_MASK, bps)
|
||||
|
||||
/* Chunk Size */
|
||||
#define SPDIFTX_MR_CHUNK_MASK GENMASK(19, 16)
|
||||
#define SPDIFTX_MR_CHUNK(size) (((size) << 16) & SPDIFTX_MR_CHUNK_MASK)
|
||||
#define SPDIFTX_MR_CHUNK(size) FIELD_PREP(SPDIFTX_MR_CHUNK_MASK, size)
|
||||
|
||||
/* Validity Bits for Channels 1 and 2 */
|
||||
#define SPDIFTX_MR_VALID1 BIT(24)
|
||||
@ -88,8 +89,7 @@
|
||||
|
||||
/* Bytes per Sample */
|
||||
#define SPDIFTX_MR_BPS_MASK GENMASK(29, 28)
|
||||
#define SPDIFTX_MR_BPS(bytes) \
|
||||
((((bytes) - 1) << 28) & SPDIFTX_MR_BPS_MASK)
|
||||
#define SPDIFTX_MR_BPS(bytes) FIELD_PREP(SPDIFTX_MR_BPS_MASK, (bytes - 1))
|
||||
|
||||
/*
|
||||
* ---- Interrupt Enable/Disable/Mask/Status Register (Write/Read-only) ----
|
||||
|
@ -323,8 +323,8 @@ static int ep93xx_ac97_dai_probe(struct snd_soc_dai *dai)
|
||||
info->dma_params_tx.filter_data = &ep93xx_ac97_pcm_out;
|
||||
info->dma_params_rx.filter_data = &ep93xx_ac97_pcm_in;
|
||||
|
||||
dai->playback_dma_data = &info->dma_params_tx;
|
||||
dai->capture_dma_data = &info->dma_params_rx;
|
||||
snd_soc_dai_init_dma_data(dai, &info->dma_params_tx,
|
||||
&info->dma_params_rx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -202,8 +202,8 @@ static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai)
|
||||
info->dma_params_rx.filter_data =
|
||||
&ep93xx_i2s_dma_data[SNDRV_PCM_STREAM_CAPTURE];
|
||||
|
||||
dai->playback_dma_data = &info->dma_params_tx;
|
||||
dai->capture_dma_data = &info->dma_params_rx;
|
||||
snd_soc_dai_init_dma_data(dai, &info->dma_params_tx,
|
||||
&info->dma_params_rx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -359,6 +359,8 @@ static int ep93xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
|
||||
|
||||
if (dir == SND_SOC_CLOCK_IN || clk_id != 0)
|
||||
return -EINVAL;
|
||||
if (!freq)
|
||||
return 0;
|
||||
|
||||
return clk_set_rate(info->mclk, freq);
|
||||
}
|
||||
|
@ -1386,17 +1386,11 @@ static int pm860x_codec_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pm860x_codec_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver pm860x_codec_driver = {
|
||||
.driver = {
|
||||
.name = "88pm860x-codec",
|
||||
},
|
||||
.probe = pm860x_codec_probe,
|
||||
.remove = pm860x_codec_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(pm860x_codec_driver);
|
||||
|
@ -54,6 +54,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_ALC5623
|
||||
imply SND_SOC_ALC5632
|
||||
imply SND_SOC_AW8738
|
||||
imply SND_SOC_AW88395
|
||||
imply SND_SOC_BT_SCO
|
||||
imply SND_SOC_BD28623
|
||||
imply SND_SOC_CQ0093VC
|
||||
@ -68,6 +69,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_CS35L45_I2C
|
||||
imply SND_SOC_CS35L45_SPI
|
||||
imply SND_SOC_CS42L42
|
||||
imply SND_SOC_CS42L42_SDW
|
||||
imply SND_SOC_CS42L51_I2C
|
||||
imply SND_SOC_CS42L52
|
||||
imply SND_SOC_CS42L56
|
||||
@ -107,6 +109,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_HDAC_HDMI
|
||||
imply SND_SOC_HDAC_HDA
|
||||
imply SND_SOC_ICS43432
|
||||
imply SND_SOC_IDT821034
|
||||
imply SND_SOC_INNO_RK3036
|
||||
imply SND_SOC_ISABELLE
|
||||
imply SND_SOC_JZ4740_CODEC
|
||||
@ -164,6 +167,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_PCM5102A
|
||||
imply SND_SOC_PCM512x_I2C
|
||||
imply SND_SOC_PCM512x_SPI
|
||||
imply SND_SOC_PEB2466
|
||||
imply SND_SOC_RK3328
|
||||
imply SND_SOC_RK817
|
||||
imply SND_SOC_RT274
|
||||
@ -195,6 +199,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_RT700_SDW
|
||||
imply SND_SOC_RT711_SDW
|
||||
imply SND_SOC_RT711_SDCA_SDW
|
||||
imply SND_SOC_RT712_SDCA_SDW
|
||||
imply SND_SOC_RT715_SDW
|
||||
imply SND_SOC_RT715_SDCA_SDW
|
||||
imply SND_SOC_RT1308_SDW
|
||||
@ -206,6 +211,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_SI476X
|
||||
imply SND_SOC_SIMPLE_AMPLIFIER
|
||||
imply SND_SOC_SIMPLE_MUX
|
||||
imply SND_SOC_SMA1303
|
||||
imply SND_SOC_SPDIF
|
||||
imply SND_SOC_SRC4XXX_I2C
|
||||
imply SND_SOC_SSM2305
|
||||
@ -599,6 +605,23 @@ config SND_SOC_AW8738
|
||||
SND_SOC_SIMPLE_AMPLIFIER, but additionally allows setting the
|
||||
operation mode using the Awinic-specific one-wire pulse control.
|
||||
|
||||
config SND_SOC_AW88395_LIB
|
||||
tristate
|
||||
|
||||
config SND_SOC_AW88395
|
||||
tristate "Soc Audio for awinic aw88395"
|
||||
depends on I2C
|
||||
select CRC8
|
||||
select CRC32
|
||||
select REGMAP_I2C
|
||||
select GPIOLIB
|
||||
select SND_SOC_AW88395_LIB
|
||||
help
|
||||
this option enables support for aw88395 Smart PA.
|
||||
The Awinic AW88395 is an I2S/TDM input, high efficiency
|
||||
digital Smart K audio amplifier with an integrated 10V
|
||||
smart boost convert.
|
||||
|
||||
config SND_SOC_BD28623
|
||||
tristate "ROHM BD28623 CODEC"
|
||||
help
|
||||
@ -665,9 +688,6 @@ config SND_SOC_CS35L41_I2C
|
||||
select SND_SOC_CS35L41
|
||||
select REGMAP_I2C
|
||||
|
||||
config SND_SOC_CS35L45_TABLES
|
||||
tristate
|
||||
|
||||
config SND_SOC_CS35L45
|
||||
tristate
|
||||
|
||||
@ -676,7 +696,6 @@ config SND_SOC_CS35L45_SPI
|
||||
depends on SPI_MASTER
|
||||
select REGMAP
|
||||
select REGMAP_SPI
|
||||
select SND_SOC_CS35L45_TABLES
|
||||
select SND_SOC_CS35L45
|
||||
help
|
||||
Enable support for Cirrus Logic CS35L45 smart speaker amplifier
|
||||
@ -687,7 +706,6 @@ config SND_SOC_CS35L45_I2C
|
||||
depends on I2C
|
||||
select REGMAP
|
||||
select REGMAP_I2C
|
||||
select SND_SOC_CS35L45_TABLES
|
||||
select SND_SOC_CS35L45
|
||||
help
|
||||
Enable support for Cirrus Logic CS35L45 smart speaker amplifier
|
||||
@ -703,6 +721,13 @@ config SND_SOC_CS42L42
|
||||
select REGMAP_I2C
|
||||
select SND_SOC_CS42L42_CORE
|
||||
|
||||
config SND_SOC_CS42L42_SDW
|
||||
tristate "Cirrus Logic CS42L42 CODEC on Soundwire"
|
||||
depends on SOUNDWIRE
|
||||
select SND_SOC_CS42L42_CORE
|
||||
help
|
||||
Enable support for Cirrus Logic CS42L42 codec with Soundwire control
|
||||
|
||||
config SND_SOC_CS42L51
|
||||
tristate
|
||||
|
||||
@ -972,6 +997,16 @@ config SND_SOC_HDA
|
||||
config SND_SOC_ICS43432
|
||||
tristate "ICS43423 and compatible i2s microphones"
|
||||
|
||||
config SND_SOC_IDT821034
|
||||
tristate "Renesas IDT821034 quad PCM codec"
|
||||
depends on SPI
|
||||
help
|
||||
Enable support for the Renesas IDT821034 quad PCM with
|
||||
programmable gain codec.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-soc-idt821034.
|
||||
|
||||
config SND_SOC_INNO_RK3036
|
||||
tristate "Inno codec driver for RK3036 SoC"
|
||||
select REGMAP_MMIO
|
||||
@ -1205,6 +1240,17 @@ config SND_SOC_PCM512x_SPI
|
||||
select SND_SOC_PCM512x
|
||||
select REGMAP_SPI
|
||||
|
||||
config SND_SOC_PEB2466
|
||||
tristate "Infineon PEB2466 quad PCM codec"
|
||||
depends on SPI
|
||||
select REGMAP_SPI
|
||||
help
|
||||
Enable support for the Infineon PEB2466 quad PCM codec,
|
||||
also named SICOFI 4-uC.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-soc-peb2466.
|
||||
|
||||
config SND_SOC_RK3328
|
||||
tristate "Rockchip RK3328 audio CODEC"
|
||||
select REGMAP_MMIO
|
||||
@ -1425,6 +1471,12 @@ config SND_SOC_RT711_SDCA_SDW
|
||||
select REGMAP_SOUNDWIRE
|
||||
select REGMAP_SOUNDWIRE_MBQ
|
||||
|
||||
config SND_SOC_RT712_SDCA_SDW
|
||||
tristate "Realtek RT712 SDCA Codec - SDW"
|
||||
depends on SOUNDWIRE
|
||||
select REGMAP_SOUNDWIRE
|
||||
select REGMAP_SOUNDWIRE_MBQ
|
||||
|
||||
config SND_SOC_RT715
|
||||
tristate
|
||||
|
||||
@ -1492,6 +1544,12 @@ config SND_SOC_SIMPLE_MUX
|
||||
tristate "Simple Audio Mux"
|
||||
depends on GPIOLIB
|
||||
|
||||
config SND_SOC_SMA1303
|
||||
tristate "Iron Device SMA1303 Audio Amplifier"
|
||||
depends on I2C
|
||||
help
|
||||
Enable support for Iron Device SMA1303 Boosted Class-D amplifier
|
||||
|
||||
config SND_SOC_SPDIF
|
||||
tristate "S/PDIF CODEC"
|
||||
|
||||
@ -2111,7 +2169,6 @@ config SND_SOC_MT6660
|
||||
|
||||
config SND_SOC_NAU8315
|
||||
tristate "Nuvoton Technology Corporation NAU8315 CODEC"
|
||||
depends on GPIOLIB
|
||||
|
||||
config SND_SOC_NAU8540
|
||||
tristate "Nuvoton Technology Corporation NAU85L40 CODEC"
|
||||
|
@ -46,6 +46,9 @@ snd-soc-ak5386-objs := ak5386.o
|
||||
snd-soc-ak5558-objs := ak5558.o
|
||||
snd-soc-arizona-objs := arizona.o arizona-jack.o
|
||||
snd-soc-aw8738-objs := aw8738.o
|
||||
snd-soc-aw88395-lib-objs := aw88395/aw88395_lib.o
|
||||
snd-soc-aw88395-objs := aw88395/aw88395.o \
|
||||
aw88395/aw88395_device.o
|
||||
snd-soc-bd28623-objs := bd28623.o
|
||||
snd-soc-bt-sco-objs := bt-sco.o
|
||||
snd-soc-cpcap-objs := cpcap.o
|
||||
@ -60,12 +63,12 @@ snd-soc-cs35l41-lib-objs := cs35l41-lib.o
|
||||
snd-soc-cs35l41-objs := cs35l41.o
|
||||
snd-soc-cs35l41-spi-objs := cs35l41-spi.o
|
||||
snd-soc-cs35l41-i2c-objs := cs35l41-i2c.o
|
||||
snd-soc-cs35l45-tables-objs := cs35l45-tables.o
|
||||
snd-soc-cs35l45-objs := cs35l45.o
|
||||
snd-soc-cs35l45-objs := cs35l45.o cs35l45-tables.o
|
||||
snd-soc-cs35l45-spi-objs := cs35l45-spi.o
|
||||
snd-soc-cs35l45-i2c-objs := cs35l45-i2c.o
|
||||
snd-soc-cs42l42-objs := cs42l42.o
|
||||
snd-soc-cs42l42-i2c-objs := cs42l42-i2c.o
|
||||
snd-soc-cs42l42-sdw-objs := cs42l42-sdw.o
|
||||
snd-soc-cs42l51-objs := cs42l51.o
|
||||
snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
|
||||
snd-soc-cs42l52-objs := cs42l52.o
|
||||
@ -111,6 +114,7 @@ snd-soc-hdac-hdmi-objs := hdac_hdmi.o
|
||||
snd-soc-hdac-hda-objs := hdac_hda.o
|
||||
snd-soc-hda-codec-objs := hda.o hda-dai.o
|
||||
snd-soc-ics43432-objs := ics43432.o
|
||||
snd-soc-idt821034-objs := idt821034.o
|
||||
snd-soc-inno-rk3036-objs := inno_rk3036.o
|
||||
snd-soc-isabelle-objs := isabelle.o
|
||||
snd-soc-jz4740-codec-objs := jz4740.o
|
||||
@ -183,6 +187,7 @@ snd-soc-pcm5102a-objs := pcm5102a.o
|
||||
snd-soc-pcm512x-objs := pcm512x.o
|
||||
snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
|
||||
snd-soc-pcm512x-spi-objs := pcm512x-spi.o
|
||||
snd-soc-peb2466-objs := peb2466.o
|
||||
snd-soc-rk3328-objs := rk3328_codec.o
|
||||
snd-soc-rk817-objs := rk817_codec.o
|
||||
snd-soc-rl6231-objs := rl6231.o
|
||||
@ -222,6 +227,7 @@ snd-soc-rt5682s-objs := rt5682s.o
|
||||
snd-soc-rt700-objs := rt700.o rt700-sdw.o
|
||||
snd-soc-rt711-objs := rt711.o rt711-sdw.o
|
||||
snd-soc-rt711-sdca-objs := rt711-sdca.o rt711-sdca-sdw.o
|
||||
snd-soc-rt712-sdca-objs := rt712-sdca.o rt712-sdca-sdw.o
|
||||
snd-soc-rt715-objs := rt715.o rt715-sdw.o
|
||||
snd-soc-rt715-sdca-objs := rt715-sdca.o rt715-sdca-sdw.o
|
||||
snd-soc-rt9120-objs := rt9120.o
|
||||
@ -233,6 +239,7 @@ 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-sma1303-objs := sma1303.o
|
||||
snd-soc-spdif-tx-objs := spdif_transmitter.o
|
||||
snd-soc-spdif-rx-objs := spdif_receiver.o
|
||||
snd-soc-src4xxx-objs := src4xxx.o
|
||||
@ -407,6 +414,8 @@ obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
|
||||
obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
|
||||
obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
|
||||
obj-$(CONFIG_SND_SOC_AW8738) += snd-soc-aw8738.o
|
||||
obj-$(CONFIG_SND_SOC_AW88395_LIB) += snd-soc-aw88395-lib.o
|
||||
obj-$(CONFIG_SND_SOC_AW88395) +=snd-soc-aw88395.o
|
||||
obj-$(CONFIG_SND_SOC_BD28623) += snd-soc-bd28623.o
|
||||
obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o
|
||||
obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
|
||||
@ -421,12 +430,12 @@ obj-$(CONFIG_SND_SOC_CS35L41) += snd-soc-cs35l41.o
|
||||
obj-$(CONFIG_SND_SOC_CS35L41_LIB) += snd-soc-cs35l41-lib.o
|
||||
obj-$(CONFIG_SND_SOC_CS35L41_SPI) += snd-soc-cs35l41-spi.o
|
||||
obj-$(CONFIG_SND_SOC_CS35L41_I2C) += snd-soc-cs35l41-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_CS35L45_TABLES) += snd-soc-cs35l45-tables.o
|
||||
obj-$(CONFIG_SND_SOC_CS35L45) += snd-soc-cs35l45.o
|
||||
obj-$(CONFIG_SND_SOC_CS35L45_SPI) += snd-soc-cs35l45-spi.o
|
||||
obj-$(CONFIG_SND_SOC_CS35L45_I2C) += snd-soc-cs35l45-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L42_CORE) += snd-soc-cs42l42.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L42_SDW) += snd-soc-cs42l42-sdw.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
|
||||
@ -472,6 +481,7 @@ obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o
|
||||
obj-$(CONFIG_SND_SOC_HDAC_HDA) += snd-soc-hdac-hda.o
|
||||
obj-$(CONFIG_SND_SOC_HDA) += snd-soc-hda-codec.o
|
||||
obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o
|
||||
obj-$(CONFIG_SND_SOC_IDT821034) += snd-soc-idt821034.o
|
||||
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
|
||||
@ -539,6 +549,7 @@ obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o
|
||||
obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o
|
||||
obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
|
||||
obj-$(CONFIG_SND_SOC_PEB2466) += snd-soc-peb2466.o
|
||||
obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o
|
||||
obj-$(CONFIG_SND_SOC_RK817) += snd-soc-rk817.o
|
||||
obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
|
||||
@ -579,6 +590,7 @@ obj-$(CONFIG_SND_SOC_RT5682S) += snd-soc-rt5682s.o
|
||||
obj-$(CONFIG_SND_SOC_RT700) += snd-soc-rt700.o
|
||||
obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o
|
||||
obj-$(CONFIG_SND_SOC_RT711_SDCA_SDW) += snd-soc-rt711-sdca.o
|
||||
obj-$(CONFIG_SND_SOC_RT712_SDCA_SDW) += snd-soc-rt712-sdca.o
|
||||
obj-$(CONFIG_SND_SOC_RT715) += snd-soc-rt715.o
|
||||
obj-$(CONFIG_SND_SOC_RT715_SDCA_SDW) += snd-soc-rt715-sdca.o
|
||||
obj-$(CONFIG_SND_SOC_RT9120) += snd-soc-rt9120.o
|
||||
@ -588,6 +600,7 @@ obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
|
||||
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_SMA1303) += snd-soc-sma1303.o
|
||||
obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
|
||||
obj-$(CONFIG_SND_SOC_SRC4XXX) += snd-soc-src4xxx.o
|
||||
obj-$(CONFIG_SND_SOC_SRC4XXX_I2C) += snd-soc-src4xxx-i2c.o
|
||||
|
@ -127,18 +127,12 @@ static int ac97_probe(struct platform_device *pdev)
|
||||
&soc_component_dev_ac97, &ac97_dai, 1);
|
||||
}
|
||||
|
||||
static int ac97_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ac97_codec_driver = {
|
||||
.driver = {
|
||||
.name = "ac97-codec",
|
||||
},
|
||||
|
||||
.probe = ac97_probe,
|
||||
.remove = ac97_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(ac97_codec_driver);
|
||||
|
@ -100,11 +100,6 @@ static int adau7002_probe(struct platform_device *pdev)
|
||||
&adau7002_dai, 1);
|
||||
}
|
||||
|
||||
static int adau7002_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id adau7002_dt_ids[] = {
|
||||
{ .compatible = "adi,adau7002", },
|
||||
@ -128,7 +123,6 @@ static struct platform_driver adau7002_driver = {
|
||||
.acpi_match_table = ACPI_PTR(adau7002_acpi_match),
|
||||
},
|
||||
.probe = adau7002_probe,
|
||||
.remove = adau7002_remove,
|
||||
};
|
||||
module_platform_driver(adau7002_driver);
|
||||
|
||||
|
579
sound/soc/codecs/aw88395/aw88395.c
Normal file
579
sound/soc/codecs/aw88395/aw88395.c
Normal file
@ -0,0 +1,579 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
// aw88395.c -- ALSA SoC AW88395 codec support
|
||||
//
|
||||
// Copyright (c) 2022-2023 AWINIC Technology CO., LTD
|
||||
//
|
||||
// Author: Bruce zhao <zhaolei@awinic.com>
|
||||
// Author: Weidong Wang <wangweidong.a@awinic.com>
|
||||
//
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/soc.h>
|
||||
#include "aw88395.h"
|
||||
#include "aw88395_device.h"
|
||||
#include "aw88395_lib.h"
|
||||
#include "aw88395_reg.h"
|
||||
|
||||
static const struct regmap_config aw88395_remap_config = {
|
||||
.val_bits = 16,
|
||||
.reg_bits = 8,
|
||||
.max_register = AW88395_REG_MAX - 1,
|
||||
.reg_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
.val_format_endian = REGMAP_ENDIAN_BIG,
|
||||
};
|
||||
|
||||
static void aw88395_start_pa(struct aw88395 *aw88395)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; i < AW88395_START_RETRIES; i++) {
|
||||
ret = aw88395_dev_start(aw88395->aw_pa);
|
||||
if (ret) {
|
||||
dev_err(aw88395->aw_pa->dev, "aw88395 device start failed. retry = %d", i);
|
||||
ret = aw88395_dev_fw_update(aw88395->aw_pa, AW88395_DSP_FW_UPDATE_ON, true);
|
||||
if (ret < 0) {
|
||||
dev_err(aw88395->aw_pa->dev, "fw update failed");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
dev_info(aw88395->aw_pa->dev, "start success\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void aw88395_startup_work(struct work_struct *work)
|
||||
{
|
||||
struct aw88395 *aw88395 =
|
||||
container_of(work, struct aw88395, start_work.work);
|
||||
|
||||
mutex_lock(&aw88395->lock);
|
||||
aw88395_start_pa(aw88395);
|
||||
mutex_unlock(&aw88395->lock);
|
||||
}
|
||||
|
||||
static void aw88395_start(struct aw88395 *aw88395, bool sync_start)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (aw88395->aw_pa->fw_status != AW88395_DEV_FW_OK)
|
||||
return;
|
||||
|
||||
if (aw88395->aw_pa->status == AW88395_DEV_PW_ON)
|
||||
return;
|
||||
|
||||
ret = aw88395_dev_fw_update(aw88395->aw_pa, AW88395_DSP_FW_UPDATE_OFF, true);
|
||||
if (ret < 0) {
|
||||
dev_err(aw88395->aw_pa->dev, "fw update failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sync_start == AW88395_SYNC_START)
|
||||
aw88395_start_pa(aw88395);
|
||||
else
|
||||
queue_delayed_work(system_wq,
|
||||
&aw88395->start_work,
|
||||
AW88395_START_WORK_DELAY_MS);
|
||||
}
|
||||
|
||||
static struct snd_soc_dai_driver aw88395_dai[] = {
|
||||
{
|
||||
.name = "aw88395-aif",
|
||||
.id = 1,
|
||||
.playback = {
|
||||
.stream_name = "Speaker_Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = AW88395_RATES,
|
||||
.formats = AW88395_FORMATS,
|
||||
},
|
||||
.capture = {
|
||||
.stream_name = "Speaker_Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = AW88395_RATES,
|
||||
.formats = AW88395_FORMATS,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static int aw88395_get_fade_in_time(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(component);
|
||||
struct aw_device *aw_dev = aw88395->aw_pa;
|
||||
|
||||
ucontrol->value.integer.value[0] = aw_dev->fade_in_time;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88395_set_fade_in_time(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(component);
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
struct aw_device *aw_dev = aw88395->aw_pa;
|
||||
int time;
|
||||
|
||||
time = ucontrol->value.integer.value[0];
|
||||
|
||||
if (time < mc->min || time > mc->max)
|
||||
return -EINVAL;
|
||||
|
||||
if (time != aw_dev->fade_in_time) {
|
||||
aw_dev->fade_in_time = time;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88395_get_fade_out_time(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(component);
|
||||
struct aw_device *aw_dev = aw88395->aw_pa;
|
||||
|
||||
ucontrol->value.integer.value[0] = aw_dev->fade_out_time;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88395_set_fade_out_time(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(component);
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
struct aw_device *aw_dev = aw88395->aw_pa;
|
||||
int time;
|
||||
|
||||
time = ucontrol->value.integer.value[0];
|
||||
if (time < mc->min || time > mc->max)
|
||||
return -EINVAL;
|
||||
|
||||
if (time != aw_dev->fade_out_time) {
|
||||
aw_dev->fade_out_time = time;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88395_profile_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(codec);
|
||||
const char *prof_name;
|
||||
char *name;
|
||||
int count;
|
||||
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
|
||||
uinfo->count = 1;
|
||||
|
||||
count = aw88395_dev_get_profile_count(aw88395->aw_pa);
|
||||
if (count <= 0) {
|
||||
uinfo->value.enumerated.items = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uinfo->value.enumerated.items = count;
|
||||
|
||||
if (uinfo->value.enumerated.item >= count)
|
||||
uinfo->value.enumerated.item = count - 1;
|
||||
|
||||
name = uinfo->value.enumerated.name;
|
||||
count = uinfo->value.enumerated.item;
|
||||
|
||||
prof_name = aw88395_dev_get_prof_name(aw88395->aw_pa, count);
|
||||
if (!prof_name) {
|
||||
strscpy(uinfo->value.enumerated.name, "null",
|
||||
strlen("null") + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strscpy(name, prof_name, sizeof(uinfo->value.enumerated.name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88395_profile_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(codec);
|
||||
|
||||
ucontrol->value.integer.value[0] = aw88395_dev_get_profile_index(aw88395->aw_pa);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88395_profile_set(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(codec);
|
||||
int ret;
|
||||
|
||||
/* pa stop or stopping just set profile */
|
||||
mutex_lock(&aw88395->lock);
|
||||
ret = aw88395_dev_set_profile_index(aw88395->aw_pa, ucontrol->value.integer.value[0]);
|
||||
if (ret < 0) {
|
||||
dev_dbg(codec->dev, "profile index does not change");
|
||||
mutex_unlock(&aw88395->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (aw88395->aw_pa->status) {
|
||||
aw88395_dev_stop(aw88395->aw_pa);
|
||||
aw88395_start(aw88395, AW88395_SYNC_START);
|
||||
}
|
||||
|
||||
mutex_unlock(&aw88395->lock);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aw88395_volume_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(codec);
|
||||
struct aw_volume_desc *vol_desc = &aw88395->aw_pa->volume_desc;
|
||||
|
||||
ucontrol->value.integer.value[0] = vol_desc->ctl_volume;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88395_volume_set(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(codec);
|
||||
struct aw_volume_desc *vol_desc = &aw88395->aw_pa->volume_desc;
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
int value;
|
||||
|
||||
value = ucontrol->value.integer.value[0];
|
||||
if (value < mc->min || value > mc->max)
|
||||
return -EINVAL;
|
||||
|
||||
if (vol_desc->ctl_volume != value) {
|
||||
vol_desc->ctl_volume = value;
|
||||
aw88395_dev_set_volume(aw88395->aw_pa, vol_desc->ctl_volume);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88395_get_fade_step(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(codec);
|
||||
|
||||
ucontrol->value.integer.value[0] = aw88395->aw_pa->fade_step;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88395_set_fade_step(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(codec);
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
int value;
|
||||
|
||||
value = ucontrol->value.integer.value[0];
|
||||
if (value < mc->min || value > mc->max)
|
||||
return -EINVAL;
|
||||
|
||||
if (aw88395->aw_pa->fade_step != value) {
|
||||
aw88395->aw_pa->fade_step = value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88395_re_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(codec);
|
||||
struct aw_device *aw_dev = aw88395->aw_pa;
|
||||
|
||||
ucontrol->value.integer.value[0] = aw_dev->cali_desc.cali_re;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw88395_re_set(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(codec);
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
struct aw_device *aw_dev = aw88395->aw_pa;
|
||||
int value;
|
||||
|
||||
value = ucontrol->value.integer.value[0];
|
||||
if (value < mc->min || value > mc->max)
|
||||
return -EINVAL;
|
||||
|
||||
if (aw_dev->cali_desc.cali_re != value) {
|
||||
aw_dev->cali_desc.cali_re = value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new aw88395_controls[] = {
|
||||
SOC_SINGLE_EXT("PCM Playback Volume", AW88395_SYSCTRL2_REG,
|
||||
6, AW88395_MUTE_VOL, 0, aw88395_volume_get,
|
||||
aw88395_volume_set),
|
||||
SOC_SINGLE_EXT("Fade Step", 0, 0, AW88395_MUTE_VOL, 0,
|
||||
aw88395_get_fade_step, aw88395_set_fade_step),
|
||||
SOC_SINGLE_EXT("Volume Ramp Up Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN,
|
||||
aw88395_get_fade_in_time, aw88395_set_fade_in_time),
|
||||
SOC_SINGLE_EXT("Volume Ramp Down Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN,
|
||||
aw88395_get_fade_out_time, aw88395_set_fade_out_time),
|
||||
SOC_SINGLE_EXT("Calib", 0, 0, 100, 0,
|
||||
aw88395_re_get, aw88395_re_set),
|
||||
AW88395_PROFILE_EXT("Profile Set", aw88395_profile_info,
|
||||
aw88395_profile_get, aw88395_profile_set),
|
||||
};
|
||||
|
||||
static int aw88395_playback_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
mutex_lock(&aw88395->lock);
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
aw88395_start(aw88395, AW88395_ASYNC_START);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
aw88395_dev_stop(aw88395->aw_pa);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&aw88395->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget aw88395_dapm_widgets[] = {
|
||||
/* playback */
|
||||
SND_SOC_DAPM_AIF_IN_E("AIF_RX", "Speaker_Playback", 0, 0, 0, 0,
|
||||
aw88395_playback_event,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_OUTPUT("DAC Output"),
|
||||
|
||||
/* capture */
|
||||
SND_SOC_DAPM_AIF_OUT("AIF_TX", "Speaker_Capture", 0, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_INPUT("ADC Input"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route aw88395_audio_map[] = {
|
||||
{"DAC Output", NULL, "AIF_RX"},
|
||||
{"AIF_TX", NULL, "ADC Input"},
|
||||
};
|
||||
|
||||
static int aw88395_codec_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(component);
|
||||
int ret;
|
||||
|
||||
INIT_DELAYED_WORK(&aw88395->start_work, aw88395_startup_work);
|
||||
|
||||
/* add widgets */
|
||||
ret = snd_soc_dapm_new_controls(dapm, aw88395_dapm_widgets,
|
||||
ARRAY_SIZE(aw88395_dapm_widgets));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* add route */
|
||||
ret = snd_soc_dapm_add_routes(dapm, aw88395_audio_map,
|
||||
ARRAY_SIZE(aw88395_audio_map));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = snd_soc_add_component_controls(component, aw88395_controls,
|
||||
ARRAY_SIZE(aw88395_controls));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void aw88395_codec_remove(struct snd_soc_component *aw_codec)
|
||||
{
|
||||
struct aw88395 *aw88395 = snd_soc_component_get_drvdata(aw_codec);
|
||||
|
||||
cancel_delayed_work_sync(&aw88395->start_work);
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver soc_codec_dev_aw88395 = {
|
||||
.probe = aw88395_codec_probe,
|
||||
.remove = aw88395_codec_remove,
|
||||
};
|
||||
|
||||
static struct aw88395 *aw88395_malloc_init(struct i2c_client *i2c)
|
||||
{
|
||||
struct aw88395 *aw88395 = devm_kzalloc(&i2c->dev,
|
||||
sizeof(struct aw88395), GFP_KERNEL);
|
||||
if (!aw88395)
|
||||
return NULL;
|
||||
|
||||
mutex_init(&aw88395->lock);
|
||||
|
||||
return aw88395;
|
||||
}
|
||||
|
||||
static void aw88395_hw_reset(struct aw88395 *aw88395)
|
||||
{
|
||||
if (aw88395->reset_gpio) {
|
||||
gpiod_set_value_cansleep(aw88395->reset_gpio, 0);
|
||||
usleep_range(AW88395_1000_US, AW88395_1000_US + 10);
|
||||
gpiod_set_value_cansleep(aw88395->reset_gpio, 1);
|
||||
usleep_range(AW88395_1000_US, AW88395_1000_US + 10);
|
||||
} else {
|
||||
dev_err(aw88395->aw_pa->dev, "%s failed", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
static int aw88395_request_firmware_file(struct aw88395 *aw88395)
|
||||
{
|
||||
const struct firmware *cont = NULL;
|
||||
int ret;
|
||||
|
||||
aw88395->aw_pa->fw_status = AW88395_DEV_FW_FAILED;
|
||||
|
||||
ret = request_firmware(&cont, AW88395_ACF_FILE, aw88395->aw_pa->dev);
|
||||
if ((ret < 0) || (!cont)) {
|
||||
dev_err(aw88395->aw_pa->dev, "load [%s] failed!", AW88395_ACF_FILE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(aw88395->aw_pa->dev, "loaded %s - size: %zu\n",
|
||||
AW88395_ACF_FILE, cont ? cont->size : 0);
|
||||
|
||||
aw88395->aw_cfg = devm_kzalloc(aw88395->aw_pa->dev, cont->size + sizeof(int), GFP_KERNEL);
|
||||
if (!aw88395->aw_cfg) {
|
||||
release_firmware(cont);
|
||||
return -ENOMEM;
|
||||
}
|
||||
aw88395->aw_cfg->len = (int)cont->size;
|
||||
memcpy(aw88395->aw_cfg->data, cont->data, cont->size);
|
||||
release_firmware(cont);
|
||||
|
||||
ret = aw88395_dev_load_acf_check(aw88395->aw_pa, aw88395->aw_cfg);
|
||||
if (ret < 0) {
|
||||
dev_err(aw88395->aw_pa->dev, "Load [%s] failed ....!", AW88395_ACF_FILE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(aw88395->aw_pa->dev, "%s : bin load success\n", __func__);
|
||||
|
||||
mutex_lock(&aw88395->lock);
|
||||
/* aw device init */
|
||||
ret = aw88395_dev_init(aw88395->aw_pa, aw88395->aw_cfg);
|
||||
if (ret < 0)
|
||||
dev_err(aw88395->aw_pa->dev, "dev init failed");
|
||||
mutex_unlock(&aw88395->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aw88395_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct aw88395 *aw88395;
|
||||
int ret;
|
||||
|
||||
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
|
||||
dev_err(&i2c->dev, "check_functionality failed");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
aw88395 = aw88395_malloc_init(i2c);
|
||||
if (!aw88395) {
|
||||
dev_err(&i2c->dev, "malloc aw88395 failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
i2c_set_clientdata(i2c, aw88395);
|
||||
|
||||
aw88395->reset_gpio = devm_gpiod_get_optional(&i2c->dev, "reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(aw88395->reset_gpio))
|
||||
dev_info(&i2c->dev, "reset gpio not defined\n");
|
||||
|
||||
/* hardware reset */
|
||||
aw88395_hw_reset(aw88395);
|
||||
|
||||
aw88395->regmap = devm_regmap_init_i2c(i2c, &aw88395_remap_config);
|
||||
if (IS_ERR(aw88395->regmap)) {
|
||||
ret = PTR_ERR(aw88395->regmap);
|
||||
dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* aw pa init */
|
||||
ret = aw88395_init(&aw88395->aw_pa, i2c, aw88395->regmap);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = aw88395_request_firmware_file(aw88395);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c->dev, "%s failed\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_snd_soc_register_component(&i2c->dev,
|
||||
&soc_codec_dev_aw88395,
|
||||
aw88395_dai, ARRAY_SIZE(aw88395_dai));
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c->dev, "failed to register aw88395: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id aw88395_i2c_id[] = {
|
||||
{ AW88395_I2C_NAME, 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, aw88395_i2c_id);
|
||||
|
||||
static struct i2c_driver aw88395_i2c_driver = {
|
||||
.driver = {
|
||||
.name = AW88395_I2C_NAME,
|
||||
},
|
||||
.probe_new = aw88395_i2c_probe,
|
||||
.id_table = aw88395_i2c_id,
|
||||
};
|
||||
module_i2c_driver(aw88395_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC AW88395 Smart PA Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
58
sound/soc/codecs/aw88395/aw88395.h
Normal file
58
sound/soc/codecs/aw88395/aw88395.h
Normal file
@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
// aw88395.h -- ALSA SoC AW88395 codec support
|
||||
//
|
||||
// Copyright (c) 2022-2023 AWINIC Technology CO., LTD
|
||||
//
|
||||
// Author: Bruce zhao <zhaolei@awinic.com>
|
||||
//
|
||||
|
||||
#ifndef __AW88395_H__
|
||||
#define __AW88395_H__
|
||||
|
||||
#define AW88395_CHIP_ID_REG (0x00)
|
||||
#define AW88395_START_RETRIES (5)
|
||||
#define AW88395_START_WORK_DELAY_MS (0)
|
||||
|
||||
#define AW88395_DSP_16_DATA_MASK (0x0000ffff)
|
||||
|
||||
#define AW88395_I2C_NAME "aw88395_smartpa"
|
||||
|
||||
#define AW88395_RATES (SNDRV_PCM_RATE_8000_48000 | \
|
||||
SNDRV_PCM_RATE_96000)
|
||||
#define AW88395_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
SNDRV_PCM_FMTBIT_S24_LE | \
|
||||
SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
||||
#define FADE_TIME_MAX 100000
|
||||
#define FADE_TIME_MIN 0
|
||||
|
||||
#define AW88395_PROFILE_EXT(xname, profile_info, profile_get, profile_set) \
|
||||
{ \
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
|
||||
.name = xname, \
|
||||
.info = profile_info, \
|
||||
.get = profile_get, \
|
||||
.put = profile_set, \
|
||||
}
|
||||
|
||||
enum {
|
||||
AW88395_SYNC_START = 0,
|
||||
AW88395_ASYNC_START,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW88395_STREAM_CLOSE = 0,
|
||||
AW88395_STREAM_OPEN,
|
||||
};
|
||||
|
||||
struct aw88395 {
|
||||
struct aw_device *aw_pa;
|
||||
struct mutex lock;
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct delayed_work start_work;
|
||||
struct regmap *regmap;
|
||||
struct aw_container *aw_cfg;
|
||||
};
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user