mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 21:51:40 +00:00
sound updates for 5.16-rc1
Lots of code development have been see in ASoC side as usual, while the continued development on memalloc helper and USB-audio low- latency support are found in the rest. Note that a few changes in the unusual places like arch/sh are included, which are a part of ASoC DAI format cleanups. ALSA core: - Continued memallloc helper updates and cleanups, now supporting non-coherent and non-contiguous pages - Fixes for races in mixer OSS layer ASoC: - A new version of the audio graph card which supports a wider range of systems - Several conversions to YAML DT bindings - Continuing cleanups to the SOF and Intel code - Move of the Cirrus DSP framework into drivers/firmware to allow for future use by non-audio DSPs - An overhaul of the cs42l42 driver, correcting many problems - DAI format terminology conversions over many drivers for cleanups - Support for AMD Vangogh and Yelow Cap, Cirrus CS35L41, Maxim MAX98520 and MAX98360A, Mediatek MT8195, Nuvoton NAU8821, nVidia Tegra210, NXP i.MX8ULP, Qualcomm AudioReach, Realtek ALC5682I-VS, RT5682S, and RT9120 and Rockchip RV1126 and RK3568 USB-audio: - Continued improvements on low-latency playback - Quirks for Pioneer devices, Line6 HX-Stomp XL, Audient iD14 HD-audio: - Reduce excessive udelay() calls on Intel platforms; this should reduce the CPU load with PulseAudio - Quirks for HP and Clevo laptops FireWire: - Support for meter information on MOTU -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmGCYqkOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE9JDQ//bjjRIVH+JmvhNgLJgJdtdpidaplKUtimEsWk 8/bFJT0lqPjGMz43bALaj4UTvO2N39ZIW8FVmHDVGh54Xuw8Qu+M/NKiD3J2p4xO Pc2rljsiJr7G2VfcBEyDb74wF4fdiFqe6N8PsIT2EG7GxhZiZ6i4+7sdpKoXqmgv 9ltUzPrtIQQva8c0ER+xHNG1sYVX0bh9vzRIA1aEosYmCPqMIatFBocqwT6fM4Ls Ko3GK3GBOnlfVoN+O/ZOsR6Lv6XYApUyp2HqCSrnZK1KvVY4ptYP8XLVwPdEi3OX 5l0oilOvAch2KIj++K2yzk+xpoEQZ/MIO/1eehLN2ioWyayUNNbeHM0fl3dmdLUQ Gow8DbA9o63auERTt6qJs6ed7KOmXewKT9IKiSK6f991JaD0n7nCbcw6yRx1OqWA CafXVIVW1CsqTGJuMZzdzBvBZ2ex9OpdhpUw2v12vf2OXKQax9WsfJjVL+qmA0PC zbb6viwRKLhAYzoPh/pdHOLm2cvRvdJZstnW8w5+52g96LEF9v4bale7aPi4bqdi 0o5l/0VGjiXjicT2tf/x8WhuExqPSA64L21adshZ0vmSrPmaGJb6IX4j4zd9TW5L v3xUUyKRmq3j7fYN2fN2hGh2qGq+EcdcfNyWOj2XrJm+JFB50/Ac1hcYd5WIZKrh xn1luaw= =UBNY -----END PGP SIGNATURE----- Merge tag 'sound-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound updates from Takashi Iwai: "Lots of code development have been see in ASoC side as usual, while the continued development on memalloc helper and USB-audio low- latency support are found in the rest. Note that a few changes in the unusual places like arch/sh are included, which are a part of ASoC DAI format cleanups. ALSA core: - Continued memalloc helper updates and cleanups, now supporting non-coherent and non-contiguous pages - Fixes for races in mixer OSS layer ASoC: - A new version of the audio graph card which supports a wider range of systems - Several conversions to YAML DT bindings - Continuing cleanups to the SOF and Intel code - Move of the Cirrus DSP framework into drivers/firmware to allow for future use by non-audio DSPs - An overhaul of the cs42l42 driver, correcting many problems - DAI format terminology conversions over many drivers for cleanups - Support for AMD Vangogh and Yelow Cap, Cirrus CS35L41, Maxim MAX98520 and MAX98360A, Mediatek MT8195, Nuvoton NAU8821, nVidia Tegra210, NXP i.MX8ULP, Qualcomm AudioReach, Realtek ALC5682I-VS, RT5682S, and RT9120 and Rockchip RV1126 and RK3568 USB-audio: - Continued improvements on low-latency playback - Quirks for Pioneer devices, Line6 HX-Stomp XL, Audient iD14 HD-audio: - Reduce excessive udelay() calls on Intel platforms; this should reduce the CPU load with PulseAudio - Quirks for HP and Clevo laptops FireWire: - Support for meter information on MOTU" * tag 'sound-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (513 commits) ALSA: usb-audio: Add quirk for Audient iD14 ALSA: hda/realtek: Add quirk for Clevo PC70HS ALSA: usb-audio: Line6 HX-Stomp XL USB_ID for 48k-fixed quirk ALSA: usb-audio: Add registration quirk for JBL Quantum 400 ASoC: rsnd: Fix an error handling path in 'rsnd_node_count()' ASoC: tlv320aic3x: Make aic3x_remove() return void ASoC: Intel: soc-acpi: use const for all uses of snd_soc_acpi_codecs ASoC: Intel: soc-acpi-cht: shrink tables using compatible IDs ASoC: Intel: soc-acpi-byt: shrink tables using compatible IDs ASoC: Intel: sof_rt5682: use comp_ids to enumerate rt5682s ASoC: Intel: sof_rt5682: detect codec variant in probe function ASoC: soc-acpi: add comp_ids field for machine driver matching ASoC: mediatek: mt8195: add mt8195-mt6359-rt1011-rt5682 bindings document ASoC: mediatek: mt8195: add machine driver with mt6359, rt1011 and rt5682 ASoC: Stop dummy from overriding hwparams ASoC: topology: Change topology device to card device ASoC: topology: Use correct device for prints ASoC: topology: Check for dapm widget completeness ASoC: topology: Add header payload_size verification ASoC: core: Remove invalid snd_soc_component_set_jack call ...
This commit is contained in:
commit
ff0700f036
@ -1,134 +0,0 @@
|
||||
Qualcomm APR (Asynchronous Packet Router) binding
|
||||
|
||||
This binding describes the Qualcomm APR. APR is a IPC protocol for
|
||||
communication between Application processor and QDSP. APR is mainly
|
||||
used for audio/voice services on the QDSP.
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must be "qcom,apr-v<VERSION-NUMBER>", example "qcom,apr-v2"
|
||||
|
||||
- qcom,apr-domain
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Destination processor ID.
|
||||
Possible values are :
|
||||
1 - APR simulator
|
||||
2 - PC
|
||||
3 - MODEM
|
||||
4 - ADSP
|
||||
5 - APPS
|
||||
6 - MODEM2
|
||||
7 - APPS2
|
||||
|
||||
= APR SERVICES
|
||||
Each subnode of the APR node represents service tied to this apr. The name
|
||||
of the nodes are not important. The properties of these nodes are defined
|
||||
by the individual bindings for the specific service
|
||||
- All APR services MUST contain the following property:
|
||||
|
||||
- reg
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: APR Service ID
|
||||
Possible values are :
|
||||
3 - DSP Core Service
|
||||
4 - Audio Front End Service.
|
||||
5 - Voice Stream Manager Service.
|
||||
6 - Voice processing manager.
|
||||
7 - Audio Stream Manager Service.
|
||||
8 - Audio Device Manager Service.
|
||||
9 - Multimode voice manager.
|
||||
10 - Core voice stream.
|
||||
11 - Core voice processor.
|
||||
12 - Ultrasound stream manager.
|
||||
13 - Listen stream manager.
|
||||
|
||||
- qcom,protection-domain
|
||||
Usage: optional
|
||||
Value type: <stringlist>
|
||||
Definition: Must list the protection domain service name and path
|
||||
that the particular apr service has a dependency on.
|
||||
Possible values are :
|
||||
"avs/audio", "msm/adsp/audio_pd".
|
||||
"kernel/elf_loader", "msm/modem/wlan_pd".
|
||||
"tms/servreg", "msm/adsp/audio_pd".
|
||||
"tms/servreg", "msm/modem/wlan_pd".
|
||||
"tms/servreg", "msm/slpi/sensor_pd".
|
||||
|
||||
= EXAMPLE
|
||||
The following example represents a QDSP based sound card on a MSM8996 device
|
||||
which uses apr as communication between Apps and QDSP.
|
||||
|
||||
apr {
|
||||
compatible = "qcom,apr-v2";
|
||||
qcom,apr-domain = <APR_DOMAIN_ADSP>;
|
||||
|
||||
apr-service@3 {
|
||||
compatible = "qcom,q6core";
|
||||
reg = <APR_SVC_ADSP_CORE>;
|
||||
};
|
||||
|
||||
apr-service@4 {
|
||||
compatible = "qcom,q6afe";
|
||||
reg = <APR_SVC_AFE>;
|
||||
|
||||
dais {
|
||||
#sound-dai-cells = <1>;
|
||||
dai@1 {
|
||||
reg = <HDMI_RX>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
apr-service@7 {
|
||||
compatible = "qcom,q6asm";
|
||||
reg = <APR_SVC_ASM>;
|
||||
...
|
||||
};
|
||||
|
||||
apr-service@8 {
|
||||
compatible = "qcom,q6adm";
|
||||
reg = <APR_SVC_ADM>;
|
||||
...
|
||||
};
|
||||
};
|
||||
|
||||
= EXAMPLE 2
|
||||
The following example represents a QDSP based sound card with protection domain
|
||||
dependencies specified. Here some of the apr services are dependent on services
|
||||
running on protection domain hosted on ADSP/SLPI remote processors while others
|
||||
have no such dependency.
|
||||
|
||||
apr {
|
||||
compatible = "qcom,apr-v2";
|
||||
qcom,glink-channels = "apr_audio_svc";
|
||||
qcom,apr-domain = <APR_DOMAIN_ADSP>;
|
||||
|
||||
apr-service@3 {
|
||||
compatible = "qcom,q6core";
|
||||
reg = <APR_SVC_ADSP_CORE>;
|
||||
};
|
||||
|
||||
q6afe: apr-service@4 {
|
||||
compatible = "qcom,q6afe";
|
||||
reg = <APR_SVC_AFE>;
|
||||
qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
|
||||
...
|
||||
};
|
||||
|
||||
q6asm: apr-service@7 {
|
||||
compatible = "qcom,q6asm";
|
||||
reg = <APR_SVC_ASM>;
|
||||
qcom,protection-domain = "tms/servreg", "msm/slpi/sensor_pd";
|
||||
...
|
||||
};
|
||||
|
||||
q6adm: apr-service@8 {
|
||||
compatible = "qcom,q6adm";
|
||||
reg = <APR_SVC_ADM>;
|
||||
qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
|
||||
...
|
||||
};
|
||||
};
|
177
Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml
Normal file
177
Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml
Normal file
@ -0,0 +1,177 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/soc/qcom/qcom,apr.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Qualcomm APR/GPR (Asynchronous/Generic Packet Router) binding
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
description: |
|
||||
This binding describes the Qualcomm APR/GPR, APR/GPR is a IPC protocol for
|
||||
communication between Application processor and QDSP. APR/GPR is mainly
|
||||
used for audio/voice services on the QDSP.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,apr-v2
|
||||
- qcom,gpr
|
||||
|
||||
qcom,apr-domain:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [1, 2, 3, 4, 5, 6, 7]
|
||||
description:
|
||||
Selects the processor domain for apr
|
||||
1 = APR simulator
|
||||
2 = PC Domain
|
||||
3 = Modem Domain
|
||||
4 = ADSP Domain
|
||||
5 = Application processor Domain
|
||||
6 = Modem2 Domain
|
||||
7 = Application Processor2 Domain
|
||||
deprecated: true
|
||||
|
||||
qcom,domain:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 1
|
||||
maximum: 7
|
||||
description:
|
||||
Selects the processor domain for apr
|
||||
1 = APR simulator
|
||||
2 = PC Domain
|
||||
3 = Modem Domain
|
||||
4 = ADSP Domain
|
||||
5 = Application processor Domain
|
||||
6 = Modem2 Domain
|
||||
7 = Application Processor2 Domain
|
||||
Selects the processor domain for gpr
|
||||
1 = Modem Domain
|
||||
2 = Audio DSP Domain
|
||||
3 = Application Processor Domain
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
#APR/GPR Services
|
||||
patternProperties:
|
||||
"^service@[1-9a-d]$":
|
||||
type: object
|
||||
description:
|
||||
APR/GPR node's client devices use subnodes for desired static port services.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,q6core
|
||||
- qcom,q6asm
|
||||
- qcom,q6afe
|
||||
- qcom,q6adm
|
||||
- qcom,q6apm
|
||||
- qcom,q6prm
|
||||
|
||||
reg:
|
||||
minimum: 1
|
||||
maximum: 13
|
||||
description:
|
||||
APR Service ID
|
||||
3 = DSP Core Service
|
||||
4 = Audio Front End Service.
|
||||
5 = Voice Stream Manager Service.
|
||||
6 = Voice processing manager.
|
||||
7 = Audio Stream Manager Service.
|
||||
8 = Audio Device Manager Service.
|
||||
9 = Multimode voice manager.
|
||||
10 = Core voice stream.
|
||||
11 = Core voice processor.
|
||||
12 = Ultrasound stream manager.
|
||||
13 = Listen stream manager.
|
||||
GPR Service ID
|
||||
1 = Audio Process Manager Service
|
||||
2 = Proxy Resource Manager Service.
|
||||
3 = AMDB Service.
|
||||
4 = Voice processing manager.
|
||||
|
||||
qcom,protection-domain:
|
||||
$ref: /schemas/types.yaml#/definitions/string-array
|
||||
description: protection domain service name and path for apr service
|
||||
possible values are
|
||||
"avs/audio", "msm/adsp/audio_pd".
|
||||
"kernel/elf_loader", "msm/modem/wlan_pd".
|
||||
"tms/servreg", "msm/adsp/audio_pd".
|
||||
"tms/servreg", "msm/modem/wlan_pd".
|
||||
"tms/servreg", "msm/slpi/sensor_pd".
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"^.*@[0-9a-f]+$":
|
||||
type: object
|
||||
description:
|
||||
Service based devices like clock controllers or digital audio interfaces.
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- qcom,domain
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/soc/qcom,apr.h>
|
||||
apr {
|
||||
compatible = "qcom,apr-v2";
|
||||
qcom,domain = <APR_DOMAIN_ADSP>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
q6core: service@3 {
|
||||
compatible = "qcom,q6core";
|
||||
reg = <APR_SVC_ADSP_CORE>;
|
||||
qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
|
||||
};
|
||||
|
||||
q6afe: service@4 {
|
||||
compatible = "qcom,q6afe";
|
||||
reg = <APR_SVC_AFE>;
|
||||
qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
|
||||
};
|
||||
|
||||
q6asm: service@7 {
|
||||
compatible = "qcom,q6asm";
|
||||
reg = <APR_SVC_ASM>;
|
||||
qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
|
||||
};
|
||||
|
||||
q6adm: service@8 {
|
||||
compatible = "qcom,q6adm";
|
||||
reg = <APR_SVC_ADM>;
|
||||
qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/soc/qcom,gpr.h>
|
||||
gpr {
|
||||
compatible = "qcom,gpr";
|
||||
qcom,domain = <GPR_DOMAIN_ID_ADSP>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
service@1 {
|
||||
compatible = "qcom,q6apm";
|
||||
reg = <GPR_APM_MODULE_IID>;
|
||||
qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
|
||||
};
|
||||
};
|
@ -34,6 +34,10 @@ properties:
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
AVDD-supply:
|
||||
description:
|
||||
Analogue power supply.
|
||||
|
||||
required:
|
||||
- "#sound-dai-cells"
|
||||
- compatible
|
||||
@ -41,6 +45,7 @@ required:
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- AVDD-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
@ -56,4 +61,5 @@ examples:
|
||||
clocks = <&clkc CLKID_AUDIO_CODEC>;
|
||||
clock-names = "pclk";
|
||||
resets = <&reset RESET_AUDIO_CODEC>;
|
||||
AVDD-supply = <&vddao_1v8>;
|
||||
};
|
||||
|
@ -0,0 +1,57 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/audio-graph-card2.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Audio Graph Card2 Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- audio-graph-card2
|
||||
links:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
label:
|
||||
maxItems: 1
|
||||
routing:
|
||||
description: |
|
||||
A list of the connections between audio components.
|
||||
Each entry is a pair of strings, the first being the
|
||||
connection's sink, the second being the connection's source.
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
multi:
|
||||
description: Multi-CPU/Codec node
|
||||
dpcm:
|
||||
description: DPCM node
|
||||
codec2codec:
|
||||
description: Codec to Codec node
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- links
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sound {
|
||||
compatible = "audio-graph-card2";
|
||||
|
||||
links = <&cpu_port>;
|
||||
};
|
||||
|
||||
cpu {
|
||||
compatible = "cpu-driver";
|
||||
|
||||
cpu_port: port { cpu_ep: endpoint { remote-endpoint = <&codec_ep>; }; };
|
||||
};
|
||||
|
||||
codec {
|
||||
compatible = "codec-driver";
|
||||
|
||||
port { codec_ep: endpoint { remote-endpoint = <&cpu_ep>; }; };
|
||||
};
|
@ -1,13 +0,0 @@
|
||||
Bluetooth-SCO audio CODEC
|
||||
|
||||
This device support generic Bluetooth SCO link.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "delta,dfbmcs320" or "linux,bt-sco"
|
||||
|
||||
Example:
|
||||
|
||||
codec: bt_sco {
|
||||
compatible = "delta,dfbmcs320";
|
||||
};
|
157
Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml
Normal file
157
Documentation/devicetree/bindings/sound/cirrus,cs35l41.yaml
Normal file
@ -0,0 +1,157 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/cirrus,cs35l41.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Cirrus Logic CS35L41 Speaker Amplifier
|
||||
|
||||
maintainers:
|
||||
- david.rhodes@cirrus.com
|
||||
|
||||
description: |
|
||||
CS35L41 is a boosted mono Class D amplifier with DSP
|
||||
speaker protection and equalization
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- cirrus,cs35l40
|
||||
- cirrus,cs35l41
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#sound-dai-cells':
|
||||
description:
|
||||
The first cell indicating the audio interface.
|
||||
const: 1
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
VA-supply:
|
||||
description: voltage regulator phandle for the VA supply
|
||||
|
||||
VP-supply:
|
||||
description: voltage regulator phandle for the VP supply
|
||||
|
||||
cirrus,boost-peak-milliamp:
|
||||
description:
|
||||
Boost-converter peak current limit in mA.
|
||||
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"
|
||||
minimum: 1600
|
||||
maximum: 4500
|
||||
default: 4500
|
||||
|
||||
cirrus,boost-ind-nanohenry:
|
||||
description:
|
||||
Boost inductor value, expressed in nH. Valid
|
||||
values include 1000, 1200, 1500 and 2200.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
minimum: 1000
|
||||
maximum: 2200
|
||||
|
||||
cirrus,boost-cap-microfarad:
|
||||
description:
|
||||
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"
|
||||
|
||||
cirrus,asp-sdout-hiz:
|
||||
description:
|
||||
Audio serial port SDOUT Hi-Z control. Sets the Hi-Z
|
||||
configuration for SDOUT pin of amplifier.
|
||||
0 = Logic 0 during unused slots, and while all transmit channels disabled
|
||||
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"
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
default: 2
|
||||
|
||||
cirrus,gpio1-polarity-invert:
|
||||
description:
|
||||
Boolean which specifies whether the GPIO1
|
||||
level is inverted. If this property is not present the level is not inverted.
|
||||
type: boolean
|
||||
|
||||
cirrus,gpio1-output-enable:
|
||||
description:
|
||||
Boolean which specifies whether the GPIO1 pin
|
||||
is configured as an output. If this property is not present the
|
||||
pin will be configured as an input.
|
||||
type: boolean
|
||||
|
||||
cirrus,gpio1-src-select:
|
||||
description:
|
||||
Configures the function of the GPIO1 pin.
|
||||
Note that the options are different from the GPIO2 pin
|
||||
0 = High Impedance (Default)
|
||||
1 = GPIO
|
||||
2 = Sync
|
||||
3 = MCLK input
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
|
||||
cirrus,gpio2-polarity-invert:
|
||||
description:
|
||||
Boolean which specifies whether the GPIO2
|
||||
level is inverted. If this property is not present the level is not inverted.
|
||||
type: boolean
|
||||
|
||||
cirrus,gpio2-output-enable:
|
||||
description:
|
||||
Boolean which specifies whether the GPIO2 pin
|
||||
is configured as an output. If this property is not present the
|
||||
pin will be configured as an input.
|
||||
type: boolean
|
||||
|
||||
cirrus,gpio2-src-select:
|
||||
description:
|
||||
Configures the function of the GPIO2 pin.
|
||||
Note that the options are different from the GPIO1 pin.
|
||||
0 = High Impedance (Default)
|
||||
1 = GPIO
|
||||
2 = Open Drain INTB
|
||||
3 = MCLK input
|
||||
4 = Push-pull INTB (active low)
|
||||
5 = Push-pull INT (active high)
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
minimum: 0
|
||||
maximum: 5
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
- cirrus,boost-peak-milliamp
|
||||
- cirrus,boost-ind-nanohenry
|
||||
- cirrus,boost-cap-microfarad
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
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>;
|
||||
cirrus,boost-peak-milliamp = <4500>;
|
||||
cirrus,boost-ind-nanohenry = <1000>;
|
||||
cirrus,boost-cap-microfarad = <15>;
|
||||
};
|
||||
};
|
@ -19,13 +19,14 @@ Optional properties:
|
||||
(See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
|
||||
for further information relating to interrupt properties)
|
||||
|
||||
- cirrus,ts-inv : Boolean property. For jacks that invert the tip sense
|
||||
polarity. Normal jacks will short tip sense pin to HS1 when headphones are
|
||||
plugged in and leave tip sense floating when not plugged in. Inverting jacks
|
||||
short tip sense when unplugged and float when plugged in.
|
||||
- cirrus,ts-inv : Boolean property. Sets the behaviour of the jack plug
|
||||
detect switch.
|
||||
|
||||
0 = (Default) Non-inverted
|
||||
1 = Inverted
|
||||
0 = (Default) Shorted to tip when unplugged, open when plugged.
|
||||
This is "inverted tip sense (ITS)" in the datasheet.
|
||||
|
||||
1 = Open when unplugged, shorted to tip when plugged.
|
||||
This is "normal tip sense (TS)" in the datasheet.
|
||||
|
||||
- cirrus,ts-dbnc-rise : Debounce the rising edge of TIP_SENSE_PLUG. With no
|
||||
debounce, the tip sense pin might be noisy on a plug event.
|
||||
|
38
Documentation/devicetree/bindings/sound/linux,bt-sco.yaml
Normal file
38
Documentation/devicetree/bindings/sound/linux,bt-sco.yaml
Normal file
@ -0,0 +1,38 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/linux,bt-sco.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Bluetooth SCO Audio Codec Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Mark Brown <broonie@kernel.org>
|
||||
|
||||
properties:
|
||||
'#sound-dai-cells':
|
||||
enum:
|
||||
- 0
|
||||
|
||||
# For Wideband PCM
|
||||
- 1
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- delta,dfbmcs320
|
||||
- linux,bt-sco
|
||||
|
||||
required:
|
||||
- '#sound-dai-cells'
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
codec {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "linux,bt-sco";
|
||||
};
|
||||
|
||||
...
|
32
Documentation/devicetree/bindings/sound/linux,spdif-dit.yaml
Normal file
32
Documentation/devicetree/bindings/sound/linux,spdif-dit.yaml
Normal file
@ -0,0 +1,32 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/linux,spdif-dit.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Dummy SPDIF Transmitter Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Mark Brown <broonie@kernel.org>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: linux,spdif-dit
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- "#sound-dai-cells"
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
spdif-out {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "linux,spdif-dit";
|
||||
};
|
||||
|
||||
...
|
@ -30,6 +30,9 @@ Required properties:
|
||||
|
||||
- reg : the I2C address of the device for I2C
|
||||
|
||||
Optional properties:
|
||||
- reset-gpios : GPIO to reset the device
|
||||
|
||||
Example:
|
||||
|
||||
codec: max98927@3a {
|
||||
|
36
Documentation/devicetree/bindings/sound/maxim,max98520.yaml
Normal file
36
Documentation/devicetree/bindings/sound/maxim,max98520.yaml
Normal file
@ -0,0 +1,36 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/maxim,max98520.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Maxim Integrated MAX98520 Speaker Amplifier Driver
|
||||
|
||||
maintainers:
|
||||
- George Song <george.song@maximintegrated.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: maxim,max98520
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: I2C address of the device.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
max98520: amplifier@38 {
|
||||
compatible = "maxim,max98520";
|
||||
reg = <0x38>;
|
||||
};
|
||||
};
|
||||
|
100
Documentation/devicetree/bindings/sound/mt8192-afe-pcm.yaml
Normal file
100
Documentation/devicetree/bindings/sound/mt8192-afe-pcm.yaml
Normal file
@ -0,0 +1,100 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mt8192-afe-pcm.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Mediatek AFE PCM controller for mt8192
|
||||
|
||||
maintainers:
|
||||
- Jiaxin Yu <jiaxin.yu@mediatek.com>
|
||||
- Shane Chien <shane.chien@mediatek.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8192-audio
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
const: audiosys
|
||||
|
||||
mediatek,apmixedsys:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of the mediatek apmixedsys controller
|
||||
|
||||
mediatek,infracfg:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of the mediatek infracfg controller
|
||||
|
||||
mediatek,topckgen:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of the mediatek topckgen controller
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: AFE clock
|
||||
- description: ADDA DAC clock
|
||||
- description: ADDA DAC pre-distortion clock
|
||||
- description: audio infra sys clock
|
||||
- description: audio infra 26M clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: aud_afe_clk
|
||||
- const: aud_dac_clk
|
||||
- const: aud_dac_predis_clk
|
||||
- const: aud_infra_clk
|
||||
- const: aud_infra_26m_clk
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- interrupts
|
||||
- resets
|
||||
- reset-names
|
||||
- mediatek,apmixedsys
|
||||
- mediatek,infracfg
|
||||
- mediatek,topckgen
|
||||
- power-domains
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/mt8192-clk.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/power/mt8192-power.h>
|
||||
#include <dt-bindings/reset/mt8192-resets.h>
|
||||
|
||||
afe: mt8192-afe-pcm {
|
||||
compatible = "mediatek,mt8192-audio";
|
||||
interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>;
|
||||
resets = <&watchdog MT8192_TOPRGU_AUDIO_SW_RST>;
|
||||
reset-names = "audiosys";
|
||||
mediatek,apmixedsys = <&apmixedsys>;
|
||||
mediatek,infracfg = <&infracfg>;
|
||||
mediatek,topckgen = <&topckgen>;
|
||||
power-domains = <&scpsys MT8192_POWER_DOMAIN_AUDIO>;
|
||||
clocks = <&audsys CLK_AUD_AFE>,
|
||||
<&audsys CLK_AUD_DAC>,
|
||||
<&audsys CLK_AUD_DAC_PREDIS>,
|
||||
<&infracfg CLK_INFRA_AUDIO>,
|
||||
<&infracfg CLK_INFRA_AUDIO_26M_B>;
|
||||
clock-names = "aud_afe_clk",
|
||||
"aud_dac_clk",
|
||||
"aud_dac_predis_clk",
|
||||
"aud_infra_clk",
|
||||
"aud_infra_26m_clk";
|
||||
};
|
||||
|
||||
...
|
@ -0,0 +1,47 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mt8195-mt6359-rt1011-rt5682.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Mediatek MT8195 with MT6359, RT1011 and RT5682 ASoC sound card driver
|
||||
|
||||
maintainers:
|
||||
- Trevor Wu <trevor.wu@mediatek.com>
|
||||
|
||||
description:
|
||||
This binding describes the MT8195 sound card with RT1011 and RT5682.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8195_mt6359_rt1011_rt5682
|
||||
|
||||
mediatek,platform:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of MT8195 ASoC platform.
|
||||
|
||||
mediatek,dptx-codec:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of MT8195 Display Port Tx codec node.
|
||||
|
||||
mediatek,hdmi-codec:
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: The phandle of MT8195 HDMI codec node.
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- mediatek,platform
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
sound: mt8195-sound {
|
||||
compatible = "mediatek,mt8195_mt6359_rt1011_rt5682";
|
||||
mediatek,platform = <&afe>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&aud_pins_default>;
|
||||
};
|
||||
|
||||
...
|
@ -1,24 +0,0 @@
|
||||
Name prefix:
|
||||
|
||||
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 the name prefix property to prepend the
|
||||
name of their sinks/sources with the provided string.
|
||||
|
||||
Optional name prefix property:
|
||||
- sound-name-prefix : string using as prefix for the sink/source names of
|
||||
the component.
|
||||
|
||||
Example: Two instances of the same component.
|
||||
|
||||
amp0: analog-amplifier@0 {
|
||||
compatible = "simple-audio-amplifier";
|
||||
enable-gpios = <&gpio GPIOH_3 0>;
|
||||
sound-name-prefix = "FRONT";
|
||||
};
|
||||
|
||||
amp1: analog-amplifier@1 {
|
||||
compatible = "simple-audio-amplifier";
|
||||
enable-gpios = <&gpio GPIOH_4 0>;
|
||||
sound-name-prefix = "BACK";
|
||||
};
|
21
Documentation/devicetree/bindings/sound/name-prefix.yaml
Normal file
21
Documentation/devicetree/bindings/sound/name-prefix.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/name-prefix.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Component sound name prefix
|
||||
|
||||
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
|
55
Documentation/devicetree/bindings/sound/nau8821.txt
Normal file
55
Documentation/devicetree/bindings/sound/nau8821.txt
Normal file
@ -0,0 +1,55 @@
|
||||
Nuvoton NAU88L21 audio codec
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
- compatible : Must be "nuvoton,nau8821"
|
||||
|
||||
- reg : the I2C address of the device. This is either 0x1B (CSB=0) or 0x54 (CSB=1).
|
||||
|
||||
Optional properties:
|
||||
- nuvoton,jkdet-enable: Enable jack detection via JKDET pin.
|
||||
- nuvoton,jkdet-pull-enable: Enable JKDET pin pull. If set - pin pull enabled,
|
||||
otherwise pin in high impedance state.
|
||||
- nuvoton,jkdet-pull-up: Pull-up JKDET pin. If set then JKDET pin is pull up, otherwise pull down.
|
||||
- nuvoton,jkdet-polarity: JKDET pin polarity. 0 - active high, 1 - active low.
|
||||
|
||||
- nuvoton,vref-impedance: VREF Impedance selection
|
||||
0 - Open
|
||||
1 - 25 kOhm
|
||||
2 - 125 kOhm
|
||||
3 - 2.5 kOhm
|
||||
|
||||
- nuvoton,micbias-voltage: Micbias voltage level.
|
||||
0 - VDDA
|
||||
1 - VDDA
|
||||
2 - VDDA * 1.1
|
||||
3 - VDDA * 1.2
|
||||
4 - VDDA * 1.3
|
||||
5 - VDDA * 1.4
|
||||
6 - VDDA * 1.53
|
||||
7 - VDDA * 1.53
|
||||
|
||||
- nuvoton,jack-insert-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
|
||||
- nuvoton,jack-eject-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
|
||||
|
||||
- nuvoton,dmic-clk-threshold: the ADC threshold of DMIC clock.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
headset: nau8821@1b {
|
||||
compatible = "nuvoton,nau8821";
|
||||
reg = <0x1b>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
|
||||
nuvoton,jkdet-enable;
|
||||
nuvoton,jkdet-pull-enable;
|
||||
nuvoton,jkdet-pull-up;
|
||||
nuvoton,jkdet-polarity = <GPIO_ACTIVE_LOW>;
|
||||
nuvoton,vref-impedance = <2>;
|
||||
nuvoton,micbias-voltage = <6>;
|
||||
nuvoton,jack-insert-debounce = <7>;
|
||||
nuvoton,jack-eject-debounce = <7>;
|
||||
nuvoton,dmic-clk-threshold = 3072000;
|
||||
};
|
@ -17,6 +17,9 @@ maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: name-prefix.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^dspk@[0-9a-f]*$"
|
||||
@ -48,12 +51,6 @@ properties:
|
||||
|
||||
sound-name-prefix:
|
||||
pattern: "^DSPK[1-9]$"
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
Used as prefix for sink/source names of the component. Must be a
|
||||
unique string among multiple instances of the same component.
|
||||
The name can be "DSPK1" or "DSPKx", where x depends on the maximum
|
||||
available instances on a Tegra SoC.
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
@ -0,0 +1,76 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nvidia,tegra210-adx.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Tegra210 ADX Device Tree Bindings
|
||||
|
||||
description: |
|
||||
The Audio Demultiplexer (ADX) block takes an input stream with up to
|
||||
16 channels and demultiplexes it into four output streams of up to 16
|
||||
channels each. A byte RAM helps to form output frames by any combination
|
||||
of bytes from the input frame. Its design is identical to that of byte
|
||||
RAM in the AMX except that the data flow direction is reversed.
|
||||
|
||||
maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Mohan Kumar <mkumard@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: name-prefix.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^adx@[0-9a-f]*$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: nvidia,tegra210-adx
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra194-adx
|
||||
- nvidia,tegra186-adx
|
||||
- const: nvidia,tegra210-adx
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
sound-name-prefix:
|
||||
pattern: "^ADX[1-9]$"
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
description: |
|
||||
ADX has one input and four outputs. Accordingly ACIF (Audio Client
|
||||
Interface) port nodes are defined to represent ADX input (port 0)
|
||||
and outputs (ports 1 to 4). These are connected to corresponding
|
||||
ports on AHUB (Audio Hub).
|
||||
properties:
|
||||
port@0:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: ADX ACIF input port
|
||||
patternProperties:
|
||||
'^port@[1-4]':
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: ADX ACIF output ports
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
adx@702d3800 {
|
||||
compatible = "nvidia,tegra210-adx";
|
||||
reg = <0x702d3800 0x100>;
|
||||
sound-name-prefix = "ADX1";
|
||||
};
|
||||
|
||||
...
|
@ -85,6 +85,26 @@ patternProperties:
|
||||
type: object
|
||||
$ref: nvidia,tegra186-dspk.yaml#
|
||||
|
||||
'^mvc@[0-9a-f]+$':
|
||||
type: object
|
||||
$ref: nvidia,tegra210-mvc.yaml#
|
||||
|
||||
'^sfc@[0-9a-f]+$':
|
||||
type: object
|
||||
$ref: nvidia,tegra210-sfc.yaml#
|
||||
|
||||
'^amx@[0-9a-f]+$':
|
||||
type: object
|
||||
$ref: nvidia,tegra210-amx.yaml#
|
||||
|
||||
'^adx@[0-9a-f]+$':
|
||||
type: object
|
||||
$ref: nvidia,tegra210-adx.yaml#
|
||||
|
||||
'^amixer@[0-9a-f]+$':
|
||||
type: object
|
||||
$ref: nvidia,tegra210-mixer.yaml#
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
@ -0,0 +1,76 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nvidia,tegra210-amx.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Tegra210 AMX Device Tree Bindings
|
||||
|
||||
description: |
|
||||
The Audio Multiplexer (AMX) block can multiplex up to four input streams
|
||||
each of which can have maximum 16 channels and generate an output stream
|
||||
with maximum 16 channels. A byte RAM helps to form an output frame by
|
||||
any combination of bytes from the input frames.
|
||||
|
||||
maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Mohan Kumar <mkumard@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: name-prefix.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^amx@[0-9a-f]*$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: nvidia,tegra210-amx
|
||||
- items:
|
||||
- const: nvidia,tegra186-amx
|
||||
- const: nvidia,tegra210-amx
|
||||
- const: nvidia,tegra194-amx
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
sound-name-prefix:
|
||||
pattern: "^AMX[1-9]$"
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
description: |
|
||||
AMX has four inputs and one output. Accordingly ACIF (Audio Client
|
||||
Interfaces) port nodes are defined to represent AMX inputs (port 0
|
||||
to 3) and output (port 4). These are connected to corresponding
|
||||
ports on AHUB (Audio Hub).
|
||||
|
||||
patternProperties:
|
||||
'^port@[0-3]':
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: AMX ACIF input ports
|
||||
|
||||
properties:
|
||||
port@4:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: AMX ACIF output port
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
amx@702d3000 {
|
||||
compatible = "nvidia,tegra210-amx";
|
||||
reg = <0x702d3000 0x100>;
|
||||
sound-name-prefix = "AMX1";
|
||||
};
|
||||
|
||||
...
|
@ -16,6 +16,9 @@ maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: name-prefix.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^dmic@[0-9a-f]*$"
|
||||
@ -49,12 +52,6 @@ properties:
|
||||
|
||||
sound-name-prefix:
|
||||
pattern: "^DMIC[1-9]$"
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
used as prefix for sink/source names of the component. Must be a
|
||||
unique string among multiple instances of the same component.
|
||||
The name can be "DMIC1" or "DMIC2" ... "DMICx", where x depends
|
||||
on the maximum available instances on a Tegra SoC.
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
@ -16,6 +16,9 @@ maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: name-prefix.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^i2s@[0-9a-f]*$"
|
||||
@ -65,12 +68,6 @@ properties:
|
||||
|
||||
sound-name-prefix:
|
||||
pattern: "^I2S[1-9]$"
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
Used as prefix for sink/source names of the component. Must be a
|
||||
unique string among multiple instances of the same component.
|
||||
The name can be "I2S1" or "I2S2" ... "I2Sx", where x depends
|
||||
on the maximum available instances on a Tegra SoC.
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
@ -0,0 +1,74 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nvidia,tegra210-mixer.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Tegra210 Mixer Device Tree Bindings
|
||||
|
||||
description: |
|
||||
The Mixer supports mixing of up to ten 7.1 audio input streams and
|
||||
generate five outputs (each of which can be any combination of the
|
||||
ten input streams).
|
||||
|
||||
maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Mohan Kumar <mkumard@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: name-prefix.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^amixer@[0-9a-f]*$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: nvidia,tegra210-amixer
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra194-amixer
|
||||
- nvidia,tegra186-amixer
|
||||
- const: nvidia,tegra210-amixer
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
sound-name-prefix:
|
||||
pattern: "^MIXER[1-9]$"
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
description: |
|
||||
Mixer has ten inputs and five outputs. Accordingly ACIF (Audio
|
||||
Client Interfaces) port nodes are defined to represent Mixer
|
||||
inputs (port 0 to 9) and outputs (port 10 to 14). These are
|
||||
connected to corresponding ports on AHUB (Audio Hub).
|
||||
|
||||
patternProperties:
|
||||
'^port@[0-9]':
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: Mixer ACIF input ports
|
||||
'^port@[10-14]':
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: Mixer ACIF output ports
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
amixer@702dbb00 {
|
||||
compatible = "nvidia,tegra210-amixer";
|
||||
reg = <0x702dbb00 0x800>;
|
||||
sound-name-prefix = "MIXER1";
|
||||
};
|
||||
|
||||
...
|
@ -0,0 +1,76 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nvidia,tegra210-mvc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Tegra210 MVC Device Tree Bindings
|
||||
|
||||
description: |
|
||||
The Master Volume Control (MVC) provides gain or attenuation to a digital
|
||||
signal path. It can be used in input or output signal path for per-stream
|
||||
volume control or it can be used as master volume control. The MVC block
|
||||
has one input and one output. The input digital stream can be mono or
|
||||
multi-channel (up to 7.1 channels) stream. An independent mute control is
|
||||
also included in the MVC block.
|
||||
|
||||
maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Mohan Kumar <mkumard@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: name-prefix.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^mvc@[0-9a-f]*$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: nvidia,tegra210-mvc
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra194-mvc
|
||||
- nvidia,tegra186-mvc
|
||||
- const: nvidia,tegra210-mvc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
sound-name-prefix:
|
||||
pattern: "^MVC[1-9]$"
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
properties:
|
||||
port@0:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: |
|
||||
MVC ACIF (Audio Client Interface) input port. This is connected
|
||||
to corresponding ACIF output port on AHUB (Audio Hub).
|
||||
|
||||
port@1:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: |
|
||||
MVC ACIF output port. This is connected to corresponding ACIF
|
||||
input port on AHUB.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
mvc@702da000 {
|
||||
compatible = "nvidia,tegra210-mvc";
|
||||
reg = <0x702da000 0x200>;
|
||||
sound-name-prefix = "MVC1";
|
||||
};
|
||||
|
||||
...
|
@ -0,0 +1,73 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nvidia,tegra210-sfc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Tegra210 SFC Device Tree Bindings
|
||||
|
||||
description: |
|
||||
The Sampling Frequency Converter (SFC) converts the sampling frequency
|
||||
of the input signal from one frequency to another. It supports sampling
|
||||
frequency conversions of streams of up to two channels (stereo).
|
||||
|
||||
maintainers:
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
- Mohan Kumar <mkumard@nvidia.com>
|
||||
- Sameer Pujar <spujar@nvidia.com>
|
||||
|
||||
allOf:
|
||||
- $ref: name-prefix.yaml#
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^sfc@[0-9a-f]*$"
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: nvidia,tegra210-sfc
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra194-sfc
|
||||
- nvidia,tegra186-sfc
|
||||
- const: nvidia,tegra210-sfc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
sound-name-prefix:
|
||||
pattern: "^SFC[1-9]$"
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
properties:
|
||||
port@0:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: |
|
||||
SFC ACIF (Audio Client Interface) input port. This is connected
|
||||
to corresponding ACIF output port on AHUB (Audio Hub).
|
||||
|
||||
port@1:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: |
|
||||
SFC ACIF output port. This is connected to corresponding ACIF
|
||||
input port on AHUB.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
sfc@702d2000 {
|
||||
compatible = "nvidia,tegra210-sfc";
|
||||
reg = <0x702d2000 0x200>;
|
||||
sound-name-prefix = "SFC1";
|
||||
};
|
||||
|
||||
...
|
@ -9,6 +9,9 @@ title: NXP/Goodix TFA989X (TFA1) Audio Amplifiers
|
||||
maintainers:
|
||||
- Stephan Gerhold <stephan@gerhold.net>
|
||||
|
||||
allOf:
|
||||
- $ref: name-prefix.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
@ -21,11 +24,7 @@ properties:
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
sound-name-prefix:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
Used as prefix for sink/source names of the component. Must be a
|
||||
unique string among multiple instances of the same component.
|
||||
sound-name-prefix: true
|
||||
|
||||
vddd-supply:
|
||||
description: regulator phandle for the VDDD power supply.
|
||||
|
@ -11,7 +11,9 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8250-lpass-rx-macro
|
||||
enum:
|
||||
- qcom,sc7280-lpass-rx-macro
|
||||
- qcom,sm8250-lpass-rx-macro
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -11,7 +11,9 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8250-lpass-tx-macro
|
||||
enum:
|
||||
- qcom,sc7280-lpass-tx-macro
|
||||
- qcom,sm8250-lpass-tx-macro
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -11,7 +11,9 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8250-lpass-va-macro
|
||||
enum:
|
||||
- qcom,sc7280-lpass-va-macro
|
||||
- qcom,sm8250-lpass-va-macro
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -11,7 +11,9 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8250-lpass-wsa-macro
|
||||
enum:
|
||||
- qcom,sc7280-lpass-wsa-macro
|
||||
- qcom,sm8250-lpass-wsa-macro
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -12,190 +12,9 @@ used by all apr services. Must contain the following properties.
|
||||
from DSP.
|
||||
example "qcom,q6afe"
|
||||
|
||||
= AFE DAIs (Digial Audio Interface)
|
||||
"dais" subnode of the AFE node. It represents afe dais, each afe dai is a
|
||||
subnode of "dais" representing board specific dai setup.
|
||||
"dais" node should have following properties followed by dai children.
|
||||
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must be "qcom,q6afe-dais"
|
||||
|
||||
- #sound-dai-cells
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Must be 1
|
||||
|
||||
- #address-cells
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Must be 1
|
||||
|
||||
- #size-cells
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Must be 0
|
||||
|
||||
== AFE DAI is subnode of "dais" and represent a dai, it includes board specific
|
||||
configuration of each dai. Must contain the following properties.
|
||||
|
||||
- reg
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Must be dai id
|
||||
|
||||
- qcom,sd-lines
|
||||
Usage: required for mi2s interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Must be list of serial data lines used by this dai.
|
||||
should be one or more of the 0-3 sd lines.
|
||||
|
||||
- qcom,tdm-sync-mode:
|
||||
Usage: required for tdm interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Synchronization mode.
|
||||
0 - Short sync bit mode
|
||||
1 - Long sync mode
|
||||
2 - Short sync slot mode
|
||||
|
||||
- qcom,tdm-sync-src:
|
||||
Usage: required for tdm interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Synchronization source.
|
||||
0 - External source
|
||||
1 - Internal source
|
||||
|
||||
- qcom,tdm-data-out:
|
||||
Usage: required for tdm interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Data out signal to drive with other masters.
|
||||
0 - Disable
|
||||
1 - Enable
|
||||
|
||||
- qcom,tdm-invert-sync:
|
||||
Usage: required for tdm interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Invert the sync.
|
||||
0 - Normal
|
||||
1 - Invert
|
||||
|
||||
- qcom,tdm-data-delay:
|
||||
Usage: required for tdm interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Number of bit clock to delay data
|
||||
with respect to sync edge.
|
||||
0 - 0 bit clock cycle
|
||||
1 - 1 bit clock cycle
|
||||
2 - 2 bit clock cycle
|
||||
|
||||
- qcom,tdm-data-align:
|
||||
Usage: required for tdm interface
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: Indicate how data is packed
|
||||
within the slot. For example, 32 slot width in case of
|
||||
sample bit width is 24.
|
||||
0 - MSB
|
||||
1 - LSB
|
||||
|
||||
= AFE CLOCKSS
|
||||
"clocks" subnode of the AFE node. It represents q6afe clocks
|
||||
"clocks" node should have following properties.
|
||||
- compatible:
|
||||
Usage: required
|
||||
Value type: <stringlist>
|
||||
Definition: must be "qcom,q6afe-clocks"
|
||||
|
||||
- #clock-cells:
|
||||
Usage: required
|
||||
Value type: <u32>
|
||||
Definition: Must be 2. Clock Id followed by
|
||||
below valid clock coupling attributes.
|
||||
1 - for no coupled clock
|
||||
2 - for dividend of the coupled clock
|
||||
3 - for divisor of the coupled clock
|
||||
4 - for inverted and no couple clock
|
||||
|
||||
= EXAMPLE
|
||||
|
||||
apr-service@4 {
|
||||
compatible = "qcom,q6afe";
|
||||
reg = <APR_SVC_AFE>;
|
||||
|
||||
dais {
|
||||
compatible = "qcom,q6afe-dais";
|
||||
#sound-dai-cells = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
dai@1 {
|
||||
reg = <HDMI_RX>;
|
||||
};
|
||||
|
||||
dai@24 {
|
||||
reg = <PRIMARY_TDM_RX_0>;
|
||||
qcom,tdm-sync-mode = <1>:
|
||||
qcom,tdm-sync-src = <1>;
|
||||
qcom,tdm-data-out = <0>;
|
||||
qcom,tdm-invert-sync = <1>;
|
||||
qcom,tdm-data-delay = <1>;
|
||||
qcom,tdm-data-align = <0>;
|
||||
|
||||
};
|
||||
|
||||
dai@25 {
|
||||
reg = <PRIMARY_TDM_TX_0>;
|
||||
qcom,tdm-sync-mode = <1>:
|
||||
qcom,tdm-sync-src = <1>;
|
||||
qcom,tdm-data-out = <0>;
|
||||
qcom,tdm-invert-sync = <1>;
|
||||
qcom,tdm-data-delay <1>:
|
||||
qcom,tdm-data-align = <0>;
|
||||
};
|
||||
|
||||
dai@16 {
|
||||
reg = <PRIMARY_MI2S_RX>;
|
||||
qcom,sd-lines = <0 2>;
|
||||
};
|
||||
|
||||
dai@17 {
|
||||
reg = <PRIMARY_MI2S_TX>;
|
||||
qcom,sd-lines = <1>;
|
||||
};
|
||||
|
||||
dai@18 {
|
||||
reg = <SECONDARY_MI2S_RX>;
|
||||
qcom,sd-lines = <0 3>;
|
||||
};
|
||||
|
||||
dai@19 {
|
||||
reg = <SECONDARY_MI2S_TX>;
|
||||
qcom,sd-lines = <1>;
|
||||
};
|
||||
|
||||
dai@20 {
|
||||
reg = <TERTIARY_MI2S_RX>;
|
||||
qcom,sd-lines = <1 3>;
|
||||
};
|
||||
|
||||
dai@21 {
|
||||
reg = <TERTIARY_MI2S_TX>;
|
||||
qcom,sd-lines = <0>;
|
||||
};
|
||||
|
||||
dai@22 {
|
||||
reg = <QUATERNARY_MI2S_RX>;
|
||||
qcom,sd-lines = <0>;
|
||||
};
|
||||
|
||||
dai@23 {
|
||||
reg = <QUATERNARY_MI2S_TX>;
|
||||
qcom,sd-lines = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
clocks {
|
||||
compatible = "qcom,q6afe-clocks";
|
||||
#clock-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
53
Documentation/devicetree/bindings/sound/qcom,q6apm-dai.yaml
Normal file
53
Documentation/devicetree/bindings/sound/qcom,q6apm-dai.yaml
Normal file
@ -0,0 +1,53 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/sound/qcom,q6apm-dai.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Qualcomm Audio Process Manager Digital Audio Interfaces binding
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
description: |
|
||||
This binding describes the Qualcomm APM DAIs in DSP
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,q6apm-dais
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- iommus
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/soc/qcom,gpr.h>
|
||||
gpr {
|
||||
compatible = "qcom,gpr";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
qcom,domain = <GPR_DOMAIN_ID_ADSP>;
|
||||
service@1 {
|
||||
compatible = "qcom,q6apm";
|
||||
reg = <1>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
apm-dai@1 {
|
||||
compatible = "qcom,q6apm-dais";
|
||||
iommus = <&apps_smmu 0x1801 0x0>;
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
@ -14,7 +14,7 @@ used by the apr service device.
|
||||
from DSP.
|
||||
example "qcom,q6asm-v2.0"
|
||||
|
||||
= ASM DAIs (Digial Audio Interface)
|
||||
= ASM DAIs (Digital Audio Interface)
|
||||
"dais" subnode of the ASM node represents dai specific configuration
|
||||
|
||||
- compatible:
|
||||
|
@ -0,0 +1,77 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/sound/qcom,q6dsp-lpass-clocks.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Qualcomm DSP LPASS Clock Controller binding
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
description: |
|
||||
This binding describes the Qualcomm DSP Clock Controller
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,q6afe-clocks
|
||||
- qcom,q6prm-lpass-clocks
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 2
|
||||
description:
|
||||
Clock Id is followed by clock coupling attributes.
|
||||
1 = for no coupled clock
|
||||
2 = for dividend of the coupled clock
|
||||
3 = for divisor of the coupled clock
|
||||
4 = for inverted and no couple clock
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#clock-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/soc/qcom,apr.h>
|
||||
#include <dt-bindings/sound/qcom,q6afe.h>
|
||||
apr {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
apr-service@4 {
|
||||
reg = <APR_SVC_AFE>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
clock-controller@2 {
|
||||
compatible = "qcom,q6afe-clocks";
|
||||
reg = <2>;
|
||||
#clock-cells = <2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/soc/qcom,gpr.h>
|
||||
gpr {
|
||||
compatible = "qcom,gpr";
|
||||
qcom,domain = <GPR_DOMAIN_ID_ADSP>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
service@2 {
|
||||
reg = <GPR_PRM_MODULE_IID>;
|
||||
compatible = "qcom,q6prm";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
clock-controller@2 {
|
||||
compatible = "qcom,q6prm-lpass-clocks";
|
||||
reg = <2>;
|
||||
#clock-cells = <2>;
|
||||
};
|
||||
};
|
||||
};
|
@ -0,0 +1,205 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/sound/qcom,q6dsp-lpass-ports.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Qualcomm DSP LPASS(Low Power Audio SubSystem) Audio Ports binding
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
description: |
|
||||
This binding describes the Qualcomm DSP LPASS Audio ports
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,q6afe-dais
|
||||
- qcom,q6apm-lpass-dais
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
#Digital Audio Interfaces
|
||||
patternProperties:
|
||||
'^dai@[0-9]+$':
|
||||
type: object
|
||||
description:
|
||||
Q6DSP Digital Audio Interfaces.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description:
|
||||
Digital Audio Interface ID
|
||||
|
||||
qcom,sd-lines:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description:
|
||||
List of serial data lines used by this dai.should be one or more of the 0-3 sd lines.
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
uniqueItems: true
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
|
||||
qcom,tdm-sync-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2]
|
||||
description:
|
||||
TDM Synchronization mode
|
||||
0 = Short sync bit mode
|
||||
1 = Long sync mode
|
||||
2 = Short sync slot mode
|
||||
|
||||
qcom,tdm-sync-src:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description:
|
||||
TDM Synchronization source
|
||||
0 = External source
|
||||
1 = Internal source
|
||||
|
||||
qcom,tdm-data-out:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description:
|
||||
TDM Data out signal to drive with other masters
|
||||
0 = Disable
|
||||
1 = Enable
|
||||
|
||||
qcom,tdm-invert-sync:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description:
|
||||
TDM Invert the sync
|
||||
0 = Normal
|
||||
1 = Invert
|
||||
|
||||
qcom,tdm-data-delay:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2]
|
||||
description:
|
||||
TDM Number of bit clock to delay data
|
||||
0 = 0 bit clock cycle
|
||||
1 = 1 bit clock cycle
|
||||
2 = 2 bit clock cycle
|
||||
|
||||
qcom,tdm-data-align:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1]
|
||||
description:
|
||||
Indicate how data is packed within the slot. For example, 32 slot
|
||||
width in case of sample bit width is 24TDM Invert the sync.
|
||||
0 = MSB
|
||||
1 = LSB
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
reg:
|
||||
contains:
|
||||
# TDM DAI ID range from PRIMARY_TDM_RX_0 - QUINARY_TDM_TX_7
|
||||
items:
|
||||
minimum: 24
|
||||
maximum: 103
|
||||
then:
|
||||
required:
|
||||
- qcom,tdm-sync-mode
|
||||
- qcom,tdm-sync-src
|
||||
- qcom,tdm-data-out
|
||||
- qcom,tdm-invert-sync
|
||||
- qcom,tdm-data-delay
|
||||
- qcom,tdm-data-align
|
||||
|
||||
- if:
|
||||
properties:
|
||||
reg:
|
||||
contains:
|
||||
# MI2S DAI ID range PRIMARY_MI2S_RX - QUATERNARY_MI2S_TX and
|
||||
# QUINARY_MI2S_RX - QUINARY_MI2S_TX
|
||||
items:
|
||||
oneOf:
|
||||
- minimum: 16
|
||||
maximum: 23
|
||||
- minimum: 127
|
||||
maximum: 128
|
||||
then:
|
||||
required:
|
||||
- qcom,sd-lines
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/soc/qcom,apr.h>
|
||||
#include <dt-bindings/sound/qcom,q6afe.h>
|
||||
apr {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
apr-service@4 {
|
||||
reg = <APR_SVC_AFE>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
q6afedai@1 {
|
||||
compatible = "qcom,q6afe-dais";
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#sound-dai-cells = <1>;
|
||||
|
||||
dai@22 {
|
||||
reg = <QUATERNARY_MI2S_RX>;
|
||||
qcom,sd-lines = <0 1 2 3>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
- |
|
||||
#include <dt-bindings/soc/qcom,gpr.h>
|
||||
gpr {
|
||||
compatible = "qcom,gpr";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
qcom,domain = <GPR_DOMAIN_ID_ADSP>;
|
||||
service@1 {
|
||||
compatible = "qcom,q6apm";
|
||||
reg = <GPR_APM_MODULE_IID>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
q6apmdai@1 {
|
||||
compatible = "qcom,q6apm-lpass-dais";
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#sound-dai-cells = <1>;
|
||||
|
||||
dai@22 {
|
||||
reg = <QUATERNARY_MI2S_RX>;
|
||||
qcom,sd-lines = <0 1 2 3>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
117
Documentation/devicetree/bindings/sound/realtek,rt5682s.yaml
Normal file
117
Documentation/devicetree/bindings/sound/realtek,rt5682s.yaml
Normal file
@ -0,0 +1,117 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/realtek,rt5682s.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Realtek rt5682s codec devicetree bindings
|
||||
|
||||
maintainers:
|
||||
- Derek Fang <derek.fang@realtek.com>
|
||||
|
||||
description: |
|
||||
Rt5682s(ALC5682I-VS) is a rt5682i variant which supports I2C only.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: realtek,rt5682s
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: I2C address of the device.
|
||||
|
||||
interrupts:
|
||||
description: The CODEC's interrupt output.
|
||||
|
||||
realtek,dmic1-data-pin:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum:
|
||||
- 0 # dmic1 data is not used
|
||||
- 1 # using GPIO2 pin as dmic1 data pin
|
||||
- 2 # using GPIO5 pin as dmic1 data pin
|
||||
description: |
|
||||
Specify which GPIO pin be used as DMIC1 data pin.
|
||||
|
||||
realtek,dmic1-clk-pin:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum:
|
||||
- 0 # dmic1 clk is not used
|
||||
- 1 # using GPIO1 pin as dmic1 clock pin
|
||||
- 2 # using GPIO3 pin as dmic1 clock pin
|
||||
description: |
|
||||
Specify which GPIO pin be used as DMIC1 clk pin.
|
||||
|
||||
realtek,jd-src:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum:
|
||||
- 0 # No JD is used
|
||||
- 1 # using JD1 as JD source
|
||||
description: |
|
||||
Specify which JD source be used.
|
||||
|
||||
realtek,ldo1-en-gpios:
|
||||
description: |
|
||||
The GPIO that controls the CODEC's LDO1_EN pin.
|
||||
|
||||
realtek,dmic-clk-rate-hz:
|
||||
description: |
|
||||
Set the clock rate (hz) for the requirement of the particular DMIC.
|
||||
|
||||
realtek,dmic-delay-ms:
|
||||
description: |
|
||||
Set the delay time (ms) for the requirement of the particular DMIC.
|
||||
|
||||
realtek,dmic-clk-driving-high:
|
||||
type: boolean
|
||||
description: |
|
||||
Set the high driving of the DMIC clock out.
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: phandle and clock specifier for codec MCLK.
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
clock-output-names:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
description: Name given for DAI word clock and bit clock outputs.
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/tegra-gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
codec@1a {
|
||||
compatible = "realtek,rt5682s";
|
||||
reg = <0x1a>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <TEGRA_GPIO(U, 6) IRQ_TYPE_LEVEL_HIGH>;
|
||||
realtek,ldo1-en-gpios =
|
||||
<&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
|
||||
realtek,dmic1-data-pin = <1>;
|
||||
realtek,dmic1-clk-pin = <1>;
|
||||
realtek,jd-src = <1>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
clock-output-names = "rt5682-dai-wclk", "rt5682-dai-bclk";
|
||||
|
||||
clocks = <&osc>;
|
||||
clock-names = "mclk";
|
||||
};
|
||||
};
|
59
Documentation/devicetree/bindings/sound/richtek,rt9120.yaml
Normal file
59
Documentation/devicetree/bindings/sound/richtek,rt9120.yaml
Normal file
@ -0,0 +1,59 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/richtek,rt9120.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Richtek RT9120 Class-D audio amplifier
|
||||
|
||||
maintainers:
|
||||
- ChiYuan Huang <cy_huang@richtek.com>
|
||||
|
||||
description: |
|
||||
The RT9120 is a high efficiency, I2S-input, stereo audio power amplifier
|
||||
delivering 2*20W into 8 Ohm BTL speaker loads. It supports the wide input
|
||||
voltage range from 4.5V to 26.4V to meet the need on most common
|
||||
applications like as TV, monitors. home entertainment, electronic music
|
||||
equipment.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- richtek,rt9120
|
||||
|
||||
reg:
|
||||
description: I2C device address
|
||||
maxItems: 1
|
||||
|
||||
pwdnn-gpios:
|
||||
description: GPIO used for power down, low active
|
||||
maxItems: 1
|
||||
|
||||
dvdd-supply:
|
||||
description: |
|
||||
Supply for the default on DVDD power, voltage domain must be 3P3V or 1P8V
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- dvdd-supply
|
||||
- '#sound-dai-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
rt9120@1a {
|
||||
compatible = "richtek,rt9120";
|
||||
reg = <0x1a>;
|
||||
pwdnn-gpios = <&gpio26 2 0>;
|
||||
dvdd-supply = <&vdd_io_reg>;
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
};
|
182
Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
Normal file
182
Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
Normal file
@ -0,0 +1,182 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/rockchip,i2s-tdm.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Rockchip I2S/TDM Controller
|
||||
|
||||
description:
|
||||
The Rockchip I2S/TDM Controller is a Time Division Multiplexed
|
||||
audio interface found in various Rockchip SoCs, allowing up
|
||||
to 8 channels of audio over a serial interface.
|
||||
|
||||
maintainers:
|
||||
- Nicolas Frattaroli <frattaroli.nicolas@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- rockchip,px30-i2s-tdm
|
||||
- rockchip,rk1808-i2s-tdm
|
||||
- rockchip,rk3308-i2s-tdm
|
||||
- rockchip,rk3568-i2s-tdm
|
||||
- rockchip,rv1126-i2s-tdm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
dmas:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
dma-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
enum:
|
||||
- rx
|
||||
- tx
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
items:
|
||||
- description: clock for TX
|
||||
- description: clock for RX
|
||||
- description: AHB clock driving the interface
|
||||
- description:
|
||||
Parent clock for mclk_tx (only required when using mclk-calibrate)
|
||||
- description:
|
||||
Parent clock for mclk_rx (only required when using mclk-calibrate)
|
||||
- description:
|
||||
Clock for sample rates that are an integer multiple of 8000
|
||||
(only required when using mclk-calibrate)
|
||||
- description:
|
||||
Clock for sample rates that are an integer multiple of 11025
|
||||
(only required when using mclk-calibrate)
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
items:
|
||||
- const: mclk_tx
|
||||
- const: mclk_rx
|
||||
- const: hclk
|
||||
- const: mclk_tx_src
|
||||
- const: mclk_rx_src
|
||||
- const: mclk_root0
|
||||
- const: mclk_root1
|
||||
|
||||
resets:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
description: resets for the tx and rx directions
|
||||
|
||||
reset-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
enum:
|
||||
- tx-m
|
||||
- rx-m
|
||||
|
||||
rockchip,grf:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
The phandle of the syscon node for the GRF register.
|
||||
|
||||
rockchip,trcm-sync-tx-only:
|
||||
type: boolean
|
||||
description: Use TX BCLK/LRCK for both TX and RX.
|
||||
|
||||
rockchip,trcm-sync-rx-only:
|
||||
type: boolean
|
||||
description: Use RX BCLK/LRCK for both TX and RX.
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
rockchip,i2s-rx-route:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description:
|
||||
Defines the mapping of I2S RX sdis to I2S data bus lines.
|
||||
By default, they are mapped one-to-one.
|
||||
rockchip,i2s-rx-route = <3> would mean sdi3 is receiving from data0.
|
||||
maxItems: 4
|
||||
items:
|
||||
enum: [0, 1, 2, 3]
|
||||
|
||||
rockchip,i2s-tx-route:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description:
|
||||
Defines the mapping of I2S TX sdos to I2S data bus lines.
|
||||
By default, they are mapped one-to-one.
|
||||
rockchip,i2s-tx-route = <3> would mean sdo3 is sending to data0.
|
||||
maxItems: 4
|
||||
items:
|
||||
enum: [0, 1, 2, 3]
|
||||
|
||||
rockchip,io-multiplex:
|
||||
description:
|
||||
Specify that the GPIO lines on the I2S bus are multiplexed such that
|
||||
the direction (input/output) needs to be dynamically adjusted.
|
||||
type: boolean
|
||||
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- dmas
|
||||
- dma-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- rockchip,grf
|
||||
- "#sound-dai-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/rk3568-cru.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
|
||||
bus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
i2s@fe410000 {
|
||||
compatible = "rockchip,rk3568-i2s-tdm";
|
||||
reg = <0x0 0xfe410000 0x0 0x1000>;
|
||||
interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru MCLK_I2S1_8CH_TX>, <&cru MCLK_I2S1_8CH_RX>,
|
||||
<&cru HCLK_I2S1_8CH>;
|
||||
clock-names = "mclk_tx", "mclk_rx", "hclk";
|
||||
dmas = <&dmac1 3>, <&dmac1 2>;
|
||||
dma-names = "rx", "tx";
|
||||
resets = <&cru SRST_M_I2S1_8CH_TX>, <&cru SRST_M_I2S1_8CH_RX>;
|
||||
reset-names = "tx-m", "rx-m";
|
||||
rockchip,trcm-sync-tx-only;
|
||||
rockchip,grf = <&grf>;
|
||||
#sound-dai-cells = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 =
|
||||
<&i2s1m0_sclktx
|
||||
&i2s1m0_sclkrx
|
||||
&i2s1m0_lrcktx
|
||||
&i2s1m0_lrckrx
|
||||
&i2s1m0_sdi0
|
||||
&i2s1m0_sdi1
|
||||
&i2s1m0_sdi2
|
||||
&i2s1m0_sdi3
|
||||
&i2s1m0_sdo0
|
||||
&i2s1m0_sdo1
|
||||
&i2s1m0_sdo2
|
||||
&i2s1m0_sdo3>;
|
||||
};
|
||||
};
|
@ -1,46 +0,0 @@
|
||||
* Rockchip PDM controller
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: "rockchip,pdm"
|
||||
- "rockchip,px30-pdm"
|
||||
- "rockchip,rk1808-pdm"
|
||||
- "rockchip,rk3308-pdm"
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
- dmas: DMA specifiers for rx dma. See the DMA client binding,
|
||||
Documentation/devicetree/bindings/dma/dma.txt
|
||||
- dma-names: should include "rx".
|
||||
- clocks: a list of phandle + clock-specifer pairs, one for each entry in clock-names.
|
||||
- clock-names: should contain following:
|
||||
- "pdm_hclk": clock for PDM BUS
|
||||
- "pdm_clk" : clock for PDM controller
|
||||
- resets: a list of phandle + reset-specifer paris, one for each entry in reset-names.
|
||||
- reset-names: reset names, should include "pdm-m".
|
||||
- pinctrl-names: Must contain a "default" entry.
|
||||
- pinctrl-N: One property must exist for each entry in
|
||||
pinctrl-names. See ../pinctrl/pinctrl-bindings.txt
|
||||
for details of the property values.
|
||||
|
||||
Example for rk3328 PDM controller:
|
||||
|
||||
pdm: pdm@ff040000 {
|
||||
compatible = "rockchip,pdm";
|
||||
reg = <0x0 0xff040000 0x0 0x1000>;
|
||||
clocks = <&clk_pdm>, <&clk_gates28 0>;
|
||||
clock-names = "pdm_clk", "pdm_hclk";
|
||||
dmas = <&pdma 16>;
|
||||
#dma-cells = <1>;
|
||||
dma-names = "rx";
|
||||
pinctrl-names = "default", "sleep";
|
||||
pinctrl-0 = <&pdmm0_clk
|
||||
&pdmm0_sdi0
|
||||
&pdmm0_sdi1
|
||||
&pdmm0_sdi2
|
||||
&pdmm0_sdi3>;
|
||||
pinctrl-1 = <&pdmm0_clk_sleep
|
||||
&pdmm0_sdi0_sleep
|
||||
&pdmm0_sdi1_sleep
|
||||
&pdmm0_sdi2_sleep
|
||||
&pdmm0_sdi3_sleep>;
|
||||
};
|
120
Documentation/devicetree/bindings/sound/rockchip,pdm.yaml
Normal file
120
Documentation/devicetree/bindings/sound/rockchip,pdm.yaml
Normal file
@ -0,0 +1,120 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/rockchip,pdm.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Rockchip PDM controller
|
||||
|
||||
description:
|
||||
The Pulse Density Modulation Interface Controller (PDMC) is
|
||||
a PDM interface controller and decoder that support PDM format.
|
||||
It integrates a clock generator driving the PDM microphone
|
||||
and embeds filters which decimate the incoming bit stream to
|
||||
obtain most common audio rates.
|
||||
|
||||
maintainers:
|
||||
- Heiko Stuebner <heiko@sntech.de>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- rockchip,pdm
|
||||
- rockchip,px30-pdm
|
||||
- rockchip,rk1808-pdm
|
||||
- rockchip,rk3308-pdm
|
||||
- rockchip,rk3568-pdm
|
||||
- rockchip,rv1126-pdm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: clock for PDM controller
|
||||
- description: clock for PDM BUS
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pdm_clk
|
||||
- const: pdm_hclk
|
||||
|
||||
dmas:
|
||||
maxItems: 1
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: rx
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: reset for PDM controller
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: pdm-m
|
||||
|
||||
rockchip,path-map:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description:
|
||||
Defines the mapping of PDM SDIx to PDM PATHx.
|
||||
By default, they are mapped one-to-one.
|
||||
maxItems: 4
|
||||
uniqueItems: true
|
||||
items:
|
||||
enum: [ 0, 1, 2, 3 ]
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- dmas
|
||||
- dma-names
|
||||
- "#sound-dai-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/rk3328-cru.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/pinctrl/rockchip.h>
|
||||
|
||||
bus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
pdm@ff040000 {
|
||||
compatible = "rockchip,pdm";
|
||||
reg = <0x0 0xff040000 0x0 0x1000>;
|
||||
interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru SCLK_PDM>, <&cru HCLK_PDM>;
|
||||
clock-names = "pdm_clk", "pdm_hclk";
|
||||
dmas = <&dmac 16>;
|
||||
dma-names = "rx";
|
||||
#sound-dai-cells = <0>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
pinctrl-0 = <&pdmm0_clk
|
||||
&pdmm0_sdi0
|
||||
&pdmm0_sdi1
|
||||
&pdmm0_sdi2
|
||||
&pdmm0_sdi3>;
|
||||
pinctrl-1 = <&pdmm0_clk_sleep
|
||||
&pdmm0_sdi0_sleep
|
||||
&pdmm0_sdi1_sleep
|
||||
&pdmm0_sdi2_sleep
|
||||
&pdmm0_sdi3_sleep>;
|
||||
};
|
||||
};
|
@ -42,7 +42,7 @@ Optional properties:
|
||||
- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
|
||||
- realtek,reset-gpios : The GPIO that controls the CODEC's RESET pin.
|
||||
|
||||
- sound-name-prefix: Please refer to name-prefix.txt
|
||||
- sound-name-prefix: Please refer to name-prefix.yaml
|
||||
|
||||
- ports: A Codec may have a single or multiple I2S interfaces. These
|
||||
interfaces on Codec side can be described under 'ports' or 'port'.
|
||||
|
@ -1,17 +0,0 @@
|
||||
Simple Amplifier Audio Driver
|
||||
|
||||
Required properties:
|
||||
- compatible : "dioo,dio2125" or "simple-audio-amplifier"
|
||||
|
||||
Optional properties:
|
||||
- enable-gpios : the gpio connected to the enable pin of the simple amplifier
|
||||
- VCC-supply : power supply for the device, as covered
|
||||
in Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
|
||||
Example:
|
||||
|
||||
amp: analog-amplifier {
|
||||
compatible = "simple-audio-amplifier";
|
||||
VCC-supply = <®ulator>;
|
||||
enable-gpios = <&gpio GPIOH_3 0>;
|
||||
};
|
@ -0,0 +1,45 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/simple-audio-amplifier.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Simple Audio Amplifier Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Jerome Brunet <jbrunet@baylibre.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- dioo,dio2125
|
||||
- simple-audio-amplifier
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
|
||||
VCC-supply:
|
||||
description: >
|
||||
power supply for the device
|
||||
|
||||
sound-name-prefix:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: >
|
||||
See ./name-prefix.txt
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/meson8-gpio.h>
|
||||
|
||||
analog-amplifier {
|
||||
compatible = "simple-audio-amplifier";
|
||||
VCC-supply = <®ulator>;
|
||||
enable-gpios = <&gpio GPIOH_3 0>;
|
||||
};
|
||||
|
||||
...
|
@ -13,6 +13,9 @@ description: |
|
||||
Simple audio multiplexers are driven using gpios, allowing to select which of
|
||||
their input line is connected to the output line.
|
||||
|
||||
allOf:
|
||||
- $ref: name-prefix.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: simple-audio-mux
|
||||
@ -21,11 +24,7 @@ properties:
|
||||
description: |
|
||||
GPIOs used to select the input line.
|
||||
|
||||
sound-name-prefix:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
Used as prefix for sink/source names of the component. Must be a
|
||||
unique string among multiple instances of the same component.
|
||||
sound-name-prefix: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -46,7 +46,27 @@ properties:
|
||||
|
||||
patternProperties:
|
||||
"^port@[0-9]$":
|
||||
description: FIXME, Need to define what each port is.
|
||||
description: |
|
||||
Port number of DT node is specified by the following DAI channels that
|
||||
depends on SoC.
|
||||
ld11-aio,ld20-aio:
|
||||
0: hdmi
|
||||
1: pcmin2
|
||||
2: line
|
||||
3: hpcmout1
|
||||
4: pcmout3
|
||||
5: hiecout1
|
||||
6: epcmout2
|
||||
7: epcmout3
|
||||
8: hieccompout1
|
||||
pxs2-aio:
|
||||
0: hdmi
|
||||
1: line
|
||||
2: aux
|
||||
3: hiecout1
|
||||
4: iecout1
|
||||
5: hieccompout1
|
||||
6: ieccompout1
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
@ -40,7 +40,11 @@ properties:
|
||||
|
||||
patternProperties:
|
||||
"^port@[0-9]$":
|
||||
description: FIXME, Need to define what each port is.
|
||||
description: |
|
||||
Port number of DT node is specified by the following DAI channels.
|
||||
0: line1
|
||||
1: hp
|
||||
2: line2
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
Device-Tree bindings for dummy spdif transmitter
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "linux,spdif-dit".
|
||||
|
||||
Example node:
|
||||
|
||||
codec: spdif-transmitter {
|
||||
compatible = "linux,spdif-dit";
|
||||
};
|
33
Documentation/devicetree/bindings/sound/test-component.yaml
Normal file
33
Documentation/devicetree/bindings/sound/test-component.yaml
Normal file
@ -0,0 +1,33 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/test-component.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Test Component Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- test-cpu
|
||||
- test-cpu-verbose
|
||||
- test-cpu-verbose-dai
|
||||
- test-cpu-verbose-component
|
||||
- test-codec
|
||||
- test-codec-verbose
|
||||
- test-codec-verbose-dai
|
||||
- test-codec-verbose-component
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: true
|
||||
|
||||
examples:
|
||||
- |
|
||||
test_cpu {
|
||||
compatible = "test-cpu";
|
||||
};
|
118
Documentation/devicetree/bindings/sound/wlf,wm8962.yaml
Normal file
118
Documentation/devicetree/bindings/sound/wlf,wm8962.yaml
Normal file
@ -0,0 +1,118 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/wlf,wm8962.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Wolfson WM8962 Ultra-Low Power Stereo CODEC
|
||||
|
||||
maintainers:
|
||||
- patches@opensource.cirrus.com
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: wlf,wm8962
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
AVDD-supply:
|
||||
description: Analogue supply.
|
||||
|
||||
CPVDD-supply:
|
||||
description: Charge pump power supply.
|
||||
|
||||
DBVDD-supply:
|
||||
description: Digital Buffer Supply.
|
||||
|
||||
DCVDD-supply:
|
||||
description: Digital Core Supply.
|
||||
|
||||
MICVDD-supply:
|
||||
description: Microphone bias amp supply.
|
||||
|
||||
PLLVDD-supply:
|
||||
description: PLL Supply
|
||||
|
||||
SPKVDD1-supply:
|
||||
description: Supply for left speaker drivers.
|
||||
|
||||
SPKVDD2-supply:
|
||||
description: Supply for right speaker drivers.
|
||||
|
||||
spk-mono:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
If present, the SPK_MONO bit of R51 (Class D Control 2) gets set,
|
||||
indicating that the speaker is in mono mode.
|
||||
|
||||
mic-cfg:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Default register value for R48 (Additional Control 4).
|
||||
If absent, the default should be the register default.
|
||||
|
||||
gpio-cfg:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
description:
|
||||
A list of GPIO configuration register values. If absent, no
|
||||
configuration of these registers is performed. Note that only values
|
||||
within [0x0, 0xffff] are valid. Any other value is regarded as setting
|
||||
the GPIO register to its reset value 0x0.
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- AVDD-supply
|
||||
- CPVDD-supply
|
||||
- DBVDD-supply
|
||||
- DCVDD-supply
|
||||
- MICVDD-supply
|
||||
- PLLVDD-supply
|
||||
- SPKVDD1-supply
|
||||
- SPKVDD2-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/imx6qdl-clock.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
wm8962: codec@1a {
|
||||
compatible = "wlf,wm8962";
|
||||
reg = <0x1a>;
|
||||
clocks = <&clks IMX6QDL_CLK_CKO>;
|
||||
DCVDD-supply = <®_audio>;
|
||||
DBVDD-supply = <®_audio>;
|
||||
AVDD-supply = <®_audio>;
|
||||
CPVDD-supply = <®_audio>;
|
||||
MICVDD-supply = <®_audio>;
|
||||
PLLVDD-supply = <®_audio>;
|
||||
SPKVDD1-supply = <®_audio>;
|
||||
SPKVDD2-supply = <®_audio>;
|
||||
gpio-cfg = <
|
||||
0x0000 /* 0:Default */
|
||||
0x0000 /* 1:Default */
|
||||
0x0013 /* 2:FN_DMICCLK */
|
||||
0x0000 /* 3:Default */
|
||||
0x8014 /* 4:FN_DMICCDAT */
|
||||
0x0000 /* 5:Default */
|
||||
>;
|
||||
};
|
||||
};
|
58
Documentation/devicetree/bindings/sound/wlf,wm8978.yaml
Normal file
58
Documentation/devicetree/bindings/sound/wlf,wm8978.yaml
Normal file
@ -0,0 +1,58 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/wlf,wm8978.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Wolfson WM8978 Codec Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- patches@opensource.cirrus.com
|
||||
|
||||
properties:
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
compatible:
|
||||
const: wlf,wm8978
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 526000
|
||||
|
||||
required:
|
||||
- '#sound-dai-cells'
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
codec@0 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "wlf,wm8978";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <500000>;
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
codec@1a {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "wlf,wm8978";
|
||||
reg = <0x1a>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
@ -1,43 +0,0 @@
|
||||
WM8962 audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8962"
|
||||
|
||||
- reg : the I2C address of the device.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- clocks : The clock source of the mclk
|
||||
|
||||
- spk-mono: This is a boolean property. If present, the SPK_MONO bit
|
||||
of R51 (Class D Control 2) gets set, indicating that the speaker is
|
||||
in mono mode.
|
||||
|
||||
- mic-cfg : Default register value for R48 (Additional Control 4).
|
||||
If absent, the default should be the register default.
|
||||
|
||||
- gpio-cfg : A list of GPIO configuration register values. The list must
|
||||
be 6 entries long. If absent, no configuration of these registers is
|
||||
performed. And note that only the value within [0x0, 0xffff] is valid.
|
||||
Any other value is regarded as setting the GPIO register by its reset
|
||||
value 0x0.
|
||||
|
||||
Example:
|
||||
|
||||
wm8962: codec@1a {
|
||||
compatible = "wlf,wm8962";
|
||||
reg = <0x1a>;
|
||||
clocks = <&clks IMX6QDL_CLK_CKO>;
|
||||
|
||||
gpio-cfg = <
|
||||
0x0000 /* 0:Default */
|
||||
0x0000 /* 1:Default */
|
||||
0x0013 /* 2:FN_DMICCLK */
|
||||
0x0000 /* 3:Default */
|
||||
0x8014 /* 4:FN_DMICCDAT */
|
||||
0x0000 /* 5:Default */
|
||||
>;
|
||||
};
|
@ -100,6 +100,15 @@ amidi_map
|
||||
MIDI device number maps assigned to the 2st OSS device;
|
||||
Default: 1
|
||||
|
||||
Module snd-soc-core
|
||||
-------------------
|
||||
|
||||
The soc core module. It is used by all ALSA card drivers.
|
||||
It takes the following options which have global effects.
|
||||
|
||||
prealloc_buffer_size_kbytes
|
||||
Specify prealloc buffer size in kbytes (default: 512).
|
||||
|
||||
Common parameters for top sound card modules
|
||||
--------------------------------------------
|
||||
|
||||
|
@ -40,7 +40,7 @@ e.g.
|
||||
.prepare = wm8731_pcm_prepare,
|
||||
.hw_params = wm8731_hw_params,
|
||||
.shutdown = wm8731_shutdown,
|
||||
.digital_mute = wm8731_mute,
|
||||
.mute_stream = wm8731_mute,
|
||||
.set_sysclk = wm8731_set_dai_sysclk,
|
||||
.set_fmt = wm8731_set_dai_fmt,
|
||||
};
|
||||
@ -60,7 +60,7 @@ e.g.
|
||||
.rates = WM8731_RATES,
|
||||
.formats = WM8731_FORMATS,},
|
||||
.ops = &wm8731_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
.symmetric_rate = 1,
|
||||
};
|
||||
|
||||
|
||||
@ -177,10 +177,10 @@ when the mute is applied or freed.
|
||||
i.e.
|
||||
::
|
||||
|
||||
static int wm8974_mute(struct snd_soc_dai *dai, int mute)
|
||||
static int wm8974_mute(struct snd_soc_dai *dai, int mute, int direction)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
u16 mute_reg = snd_soc_component_read32(component, WM8974_DAC) & 0xffbf;
|
||||
u16 mute_reg = snd_soc_component_read(component, WM8974_DAC) & 0xffbf;
|
||||
|
||||
if (mute)
|
||||
snd_soc_component_write(component, WM8974_DAC, mute_reg | 0x40);
|
||||
|
18
MAINTAINERS
18
MAINTAINERS
@ -4468,6 +4468,17 @@ L: patches@opensource.cirrus.com
|
||||
S: Maintained
|
||||
F: sound/soc/codecs/cs*
|
||||
|
||||
CIRRUS LOGIC DSP FIRMWARE DRIVER
|
||||
M: Simon Trimmer <simont@opensource.cirrus.com>
|
||||
M: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
M: Richard Fitzgerald <rf@opensource.cirrus.com>
|
||||
L: patches@opensource.cirrus.com
|
||||
S: Supported
|
||||
W: https://github.com/CirrusLogic/linux-drivers/wiki
|
||||
T: git https://github.com/CirrusLogic/linux-drivers.git
|
||||
F: drivers/firmware/cirrus/*
|
||||
F: include/linux/firmware/cirrus/*
|
||||
|
||||
CIRRUS LOGIC EP93XX ETHERNET DRIVER
|
||||
M: Hartley Sweeten <hsweeten@visionengravers.com>
|
||||
L: netdev@vger.kernel.org
|
||||
@ -16227,6 +16238,13 @@ F: Documentation/ABI/*/sysfs-driver-hid-roccat*
|
||||
F: drivers/hid/hid-roccat*
|
||||
F: include/linux/hid-roccat*
|
||||
|
||||
ROCKCHIP I2S TDM DRIVER
|
||||
M: Nicolas Frattaroli <frattaroli.nicolas@gmail.com>
|
||||
L: linux-rockchip@lists.infradead.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.yaml
|
||||
F: sound/soc/rockchip/rockchip_i2s_tdm.*
|
||||
|
||||
ROCKCHIP ISP V1 DRIVER
|
||||
M: Helen Koike <helen.koike@collabora.com>
|
||||
M: Dafna Hirschfeld <dafna.hirschfeld@collabora.com>
|
||||
|
@ -886,7 +886,7 @@ static struct asoc_simple_card_info fsi_da7210_info = {
|
||||
.card = "FSIB-DA7210",
|
||||
.codec = "da7210.0-001a",
|
||||
.platform = "sh_fsi.0",
|
||||
.daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM,
|
||||
.daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBP_CFP,
|
||||
.cpu_dai = {
|
||||
.name = "fsib-dai",
|
||||
},
|
||||
|
@ -305,7 +305,7 @@ static struct asoc_simple_card_info fsi_ak4642_info = {
|
||||
.card = "FSIA-AK4642",
|
||||
.codec = "ak4642-codec.0-0012",
|
||||
.platform = "sh_fsi.0",
|
||||
.daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM,
|
||||
.daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBP_CFP,
|
||||
.cpu_dai = {
|
||||
.name = "fsia-dai",
|
||||
},
|
||||
|
@ -295,6 +295,7 @@ config TURRIS_MOX_RWTM
|
||||
|
||||
source "drivers/firmware/arm_ffa/Kconfig"
|
||||
source "drivers/firmware/broadcom/Kconfig"
|
||||
source "drivers/firmware/cirrus/Kconfig"
|
||||
source "drivers/firmware/google/Kconfig"
|
||||
source "drivers/firmware/efi/Kconfig"
|
||||
source "drivers/firmware/imx/Kconfig"
|
||||
|
@ -28,6 +28,7 @@ obj-$(CONFIG_TURRIS_MOX_RWTM) += turris-mox-rwtm.o
|
||||
obj-y += arm_ffa/
|
||||
obj-y += arm_scmi/
|
||||
obj-y += broadcom/
|
||||
obj-y += cirrus/
|
||||
obj-y += meson/
|
||||
obj-$(CONFIG_GOOGLE_FIRMWARE) += google/
|
||||
obj-$(CONFIG_EFI) += efi/
|
||||
|
5
drivers/firmware/cirrus/Kconfig
Normal file
5
drivers/firmware/cirrus/Kconfig
Normal file
@ -0,0 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
config CS_DSP
|
||||
tristate
|
||||
default n
|
3
drivers/firmware/cirrus/Makefile
Normal file
3
drivers/firmware/cirrus/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
obj-$(CONFIG_CS_DSP) += cs_dsp.o
|
3109
drivers/firmware/cirrus/cs_dsp.c
Normal file
3109
drivers/firmware/cirrus/cs_dsp.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -199,7 +199,7 @@ config QCOM_WCNSS_CTRL
|
||||
firmware to a newly booted WCNSS chip.
|
||||
|
||||
config QCOM_APR
|
||||
tristate "Qualcomm APR Bus (Asynchronous Packet Router)"
|
||||
tristate "Qualcomm APR/GPR Bus (Asynchronous/Generic Packet Router)"
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
depends on RPMSG
|
||||
depends on NET
|
||||
|
@ -15,13 +15,23 @@
|
||||
#include <linux/rpmsg.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
struct apr {
|
||||
enum {
|
||||
PR_TYPE_APR = 0,
|
||||
PR_TYPE_GPR,
|
||||
};
|
||||
|
||||
/* Some random values tbh which does not collide with static modules */
|
||||
#define GPR_DYNAMIC_PORT_START 0x10000000
|
||||
#define GPR_DYNAMIC_PORT_END 0x20000000
|
||||
|
||||
struct packet_router {
|
||||
struct rpmsg_endpoint *ch;
|
||||
struct device *dev;
|
||||
spinlock_t svcs_lock;
|
||||
spinlock_t rx_lock;
|
||||
struct idr svcs_idr;
|
||||
int dest_domain_id;
|
||||
int type;
|
||||
struct pdr_handle *pdr;
|
||||
struct workqueue_struct *rxwq;
|
||||
struct work_struct rx_work;
|
||||
@ -44,26 +54,103 @@ struct apr_rx_buf {
|
||||
*/
|
||||
int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt)
|
||||
{
|
||||
struct apr *apr = dev_get_drvdata(adev->dev.parent);
|
||||
struct packet_router *apr = dev_get_drvdata(adev->dev.parent);
|
||||
struct apr_hdr *hdr;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&adev->lock, flags);
|
||||
spin_lock_irqsave(&adev->svc.lock, flags);
|
||||
|
||||
hdr = &pkt->hdr;
|
||||
hdr->src_domain = APR_DOMAIN_APPS;
|
||||
hdr->src_svc = adev->svc_id;
|
||||
hdr->src_svc = adev->svc.id;
|
||||
hdr->dest_domain = adev->domain_id;
|
||||
hdr->dest_svc = adev->svc_id;
|
||||
hdr->dest_svc = adev->svc.id;
|
||||
|
||||
ret = rpmsg_trysend(apr->ch, pkt, hdr->pkt_size);
|
||||
spin_unlock_irqrestore(&adev->lock, flags);
|
||||
spin_unlock_irqrestore(&adev->svc.lock, flags);
|
||||
|
||||
return ret ? ret : hdr->pkt_size;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(apr_send_pkt);
|
||||
|
||||
void gpr_free_port(gpr_port_t *port)
|
||||
{
|
||||
struct packet_router *gpr = port->pr;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&gpr->svcs_lock, flags);
|
||||
idr_remove(&gpr->svcs_idr, port->id);
|
||||
spin_unlock_irqrestore(&gpr->svcs_lock, flags);
|
||||
|
||||
kfree(port);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpr_free_port);
|
||||
|
||||
gpr_port_t *gpr_alloc_port(struct apr_device *gdev, struct device *dev,
|
||||
gpr_port_cb cb, void *priv)
|
||||
{
|
||||
struct packet_router *pr = dev_get_drvdata(gdev->dev.parent);
|
||||
gpr_port_t *port;
|
||||
struct pkt_router_svc *svc;
|
||||
int id;
|
||||
|
||||
port = kzalloc(sizeof(*port), GFP_KERNEL);
|
||||
if (!port)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
svc = port;
|
||||
svc->callback = cb;
|
||||
svc->pr = pr;
|
||||
svc->priv = priv;
|
||||
svc->dev = dev;
|
||||
spin_lock_init(&svc->lock);
|
||||
|
||||
spin_lock(&pr->svcs_lock);
|
||||
id = idr_alloc_cyclic(&pr->svcs_idr, svc, GPR_DYNAMIC_PORT_START,
|
||||
GPR_DYNAMIC_PORT_END, GFP_ATOMIC);
|
||||
if (id < 0) {
|
||||
dev_err(dev, "Unable to allocate dynamic GPR src port\n");
|
||||
kfree(port);
|
||||
spin_unlock(&pr->svcs_lock);
|
||||
return ERR_PTR(id);
|
||||
}
|
||||
|
||||
svc->id = id;
|
||||
spin_unlock(&pr->svcs_lock);
|
||||
|
||||
return port;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpr_alloc_port);
|
||||
|
||||
static int pkt_router_send_svc_pkt(struct pkt_router_svc *svc, struct gpr_pkt *pkt)
|
||||
{
|
||||
struct packet_router *pr = svc->pr;
|
||||
struct gpr_hdr *hdr;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
hdr = &pkt->hdr;
|
||||
|
||||
spin_lock_irqsave(&svc->lock, flags);
|
||||
ret = rpmsg_trysend(pr->ch, pkt, hdr->pkt_size);
|
||||
spin_unlock_irqrestore(&svc->lock, flags);
|
||||
|
||||
return ret ? ret : hdr->pkt_size;
|
||||
}
|
||||
|
||||
int gpr_send_pkt(struct apr_device *gdev, struct gpr_pkt *pkt)
|
||||
{
|
||||
return pkt_router_send_svc_pkt(&gdev->svc, pkt);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpr_send_pkt);
|
||||
|
||||
int gpr_send_port_pkt(gpr_port_t *port, struct gpr_pkt *pkt)
|
||||
{
|
||||
return pkt_router_send_svc_pkt(port, pkt);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpr_send_port_pkt);
|
||||
|
||||
static void apr_dev_release(struct device *dev)
|
||||
{
|
||||
struct apr_device *adev = to_apr_device(dev);
|
||||
@ -74,7 +161,7 @@ static void apr_dev_release(struct device *dev)
|
||||
static int apr_callback(struct rpmsg_device *rpdev, void *buf,
|
||||
int len, void *priv, u32 addr)
|
||||
{
|
||||
struct apr *apr = dev_get_drvdata(&rpdev->dev);
|
||||
struct packet_router *apr = dev_get_drvdata(&rpdev->dev);
|
||||
struct apr_rx_buf *abuf;
|
||||
unsigned long flags;
|
||||
|
||||
@ -100,11 +187,11 @@ static int apr_callback(struct rpmsg_device *rpdev, void *buf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int apr_do_rx_callback(struct apr *apr, struct apr_rx_buf *abuf)
|
||||
static int apr_do_rx_callback(struct packet_router *apr, struct apr_rx_buf *abuf)
|
||||
{
|
||||
uint16_t hdr_size, msg_type, ver, svc_id;
|
||||
struct apr_device *svc = NULL;
|
||||
struct pkt_router_svc *svc;
|
||||
struct apr_device *adev;
|
||||
struct apr_driver *adrv = NULL;
|
||||
struct apr_resp_pkt resp;
|
||||
struct apr_hdr *hdr;
|
||||
@ -145,12 +232,15 @@ static int apr_do_rx_callback(struct apr *apr, struct apr_rx_buf *abuf)
|
||||
svc_id = hdr->dest_svc;
|
||||
spin_lock_irqsave(&apr->svcs_lock, flags);
|
||||
svc = idr_find(&apr->svcs_idr, svc_id);
|
||||
if (svc && svc->dev.driver)
|
||||
adrv = to_apr_driver(svc->dev.driver);
|
||||
if (svc && svc->dev->driver) {
|
||||
adev = svc_to_apr_device(svc);
|
||||
adrv = to_apr_driver(adev->dev.driver);
|
||||
}
|
||||
spin_unlock_irqrestore(&apr->svcs_lock, flags);
|
||||
|
||||
if (!adrv) {
|
||||
dev_err(apr->dev, "APR: service is not registered\n");
|
||||
if (!adrv || !adev) {
|
||||
dev_err(apr->dev, "APR: service is not registered (%d)\n",
|
||||
svc_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -164,20 +254,82 @@ static int apr_do_rx_callback(struct apr *apr, struct apr_rx_buf *abuf)
|
||||
if (resp.payload_size > 0)
|
||||
resp.payload = buf + hdr_size;
|
||||
|
||||
adrv->callback(svc, &resp);
|
||||
adrv->callback(adev, &resp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpr_do_rx_callback(struct packet_router *gpr, struct apr_rx_buf *abuf)
|
||||
{
|
||||
uint16_t hdr_size, ver;
|
||||
struct pkt_router_svc *svc = NULL;
|
||||
struct gpr_resp_pkt resp;
|
||||
struct gpr_hdr *hdr;
|
||||
unsigned long flags;
|
||||
void *buf = abuf->buf;
|
||||
int len = abuf->len;
|
||||
|
||||
hdr = buf;
|
||||
ver = hdr->version;
|
||||
if (ver > GPR_PKT_VER + 1)
|
||||
return -EINVAL;
|
||||
|
||||
hdr_size = hdr->hdr_size;
|
||||
if (hdr_size < GPR_PKT_HEADER_WORD_SIZE) {
|
||||
dev_err(gpr->dev, "GPR: Wrong hdr size:%d\n", hdr_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hdr->pkt_size < GPR_PKT_HEADER_BYTE_SIZE || hdr->pkt_size != len) {
|
||||
dev_err(gpr->dev, "GPR: Wrong packet size\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
resp.hdr = *hdr;
|
||||
resp.payload_size = hdr->pkt_size - (hdr_size * 4);
|
||||
|
||||
/*
|
||||
* NOTE: hdr_size is not same as GPR_HDR_SIZE as remote can include
|
||||
* optional headers in to gpr_hdr which should be ignored
|
||||
*/
|
||||
if (resp.payload_size > 0)
|
||||
resp.payload = buf + (hdr_size * 4);
|
||||
|
||||
|
||||
spin_lock_irqsave(&gpr->svcs_lock, flags);
|
||||
svc = idr_find(&gpr->svcs_idr, hdr->dest_port);
|
||||
spin_unlock_irqrestore(&gpr->svcs_lock, flags);
|
||||
|
||||
if (!svc) {
|
||||
dev_err(gpr->dev, "GPR: Port(%x) is not registered\n",
|
||||
hdr->dest_port);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (svc->callback)
|
||||
svc->callback(&resp, svc->priv, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apr_rxwq(struct work_struct *work)
|
||||
{
|
||||
struct apr *apr = container_of(work, struct apr, rx_work);
|
||||
struct packet_router *apr = container_of(work, struct packet_router, rx_work);
|
||||
struct apr_rx_buf *abuf, *b;
|
||||
unsigned long flags;
|
||||
|
||||
if (!list_empty(&apr->rx_list)) {
|
||||
list_for_each_entry_safe(abuf, b, &apr->rx_list, node) {
|
||||
apr_do_rx_callback(apr, abuf);
|
||||
switch (apr->type) {
|
||||
case PR_TYPE_APR:
|
||||
apr_do_rx_callback(apr, abuf);
|
||||
break;
|
||||
case PR_TYPE_GPR:
|
||||
gpr_do_rx_callback(apr, abuf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
spin_lock_irqsave(&apr->rx_lock, flags);
|
||||
list_del(&abuf->node);
|
||||
spin_unlock_irqrestore(&apr->rx_lock, flags);
|
||||
@ -201,7 +353,7 @@ static int apr_device_match(struct device *dev, struct device_driver *drv)
|
||||
|
||||
while (id->domain_id != 0 || id->svc_id != 0) {
|
||||
if (id->domain_id == adev->domain_id &&
|
||||
id->svc_id == adev->svc_id)
|
||||
id->svc_id == adev->svc.id)
|
||||
return 1;
|
||||
id++;
|
||||
}
|
||||
@ -213,22 +365,27 @@ static int apr_device_probe(struct device *dev)
|
||||
{
|
||||
struct apr_device *adev = to_apr_device(dev);
|
||||
struct apr_driver *adrv = to_apr_driver(dev->driver);
|
||||
int ret;
|
||||
|
||||
return adrv->probe(adev);
|
||||
ret = adrv->probe(adev);
|
||||
if (!ret)
|
||||
adev->svc.callback = adrv->gpr_callback;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void apr_device_remove(struct device *dev)
|
||||
{
|
||||
struct apr_device *adev = to_apr_device(dev);
|
||||
struct apr_driver *adrv;
|
||||
struct apr *apr = dev_get_drvdata(adev->dev.parent);
|
||||
struct packet_router *apr = dev_get_drvdata(adev->dev.parent);
|
||||
|
||||
if (dev->driver) {
|
||||
adrv = to_apr_driver(dev->driver);
|
||||
if (adrv->remove)
|
||||
adrv->remove(adev);
|
||||
spin_lock(&apr->svcs_lock);
|
||||
idr_remove(&apr->svcs_idr, adev->svc_id);
|
||||
idr_remove(&apr->svcs_idr, adev->svc.id);
|
||||
spin_unlock(&apr->svcs_lock);
|
||||
}
|
||||
}
|
||||
@ -255,28 +412,43 @@ struct bus_type aprbus = {
|
||||
EXPORT_SYMBOL_GPL(aprbus);
|
||||
|
||||
static int apr_add_device(struct device *dev, struct device_node *np,
|
||||
const struct apr_device_id *id)
|
||||
u32 svc_id, u32 domain_id)
|
||||
{
|
||||
struct apr *apr = dev_get_drvdata(dev);
|
||||
struct packet_router *apr = dev_get_drvdata(dev);
|
||||
struct apr_device *adev = NULL;
|
||||
struct pkt_router_svc *svc;
|
||||
int ret;
|
||||
|
||||
adev = kzalloc(sizeof(*adev), GFP_KERNEL);
|
||||
if (!adev)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&adev->lock);
|
||||
adev->svc_id = svc_id;
|
||||
svc = &adev->svc;
|
||||
|
||||
svc->id = svc_id;
|
||||
svc->pr = apr;
|
||||
svc->priv = adev;
|
||||
svc->dev = dev;
|
||||
spin_lock_init(&svc->lock);
|
||||
|
||||
adev->domain_id = domain_id;
|
||||
|
||||
adev->svc_id = id->svc_id;
|
||||
adev->domain_id = id->domain_id;
|
||||
adev->version = id->svc_version;
|
||||
if (np)
|
||||
snprintf(adev->name, APR_NAME_SIZE, "%pOFn", np);
|
||||
else
|
||||
strscpy(adev->name, id->name, APR_NAME_SIZE);
|
||||
|
||||
dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
|
||||
id->domain_id, id->svc_id);
|
||||
switch (apr->type) {
|
||||
case PR_TYPE_APR:
|
||||
dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
|
||||
domain_id, svc_id);
|
||||
break;
|
||||
case PR_TYPE_GPR:
|
||||
dev_set_name(&adev->dev, "gprsvc:%s:%x:%x", adev->name,
|
||||
domain_id, svc_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
adev->dev.bus = &aprbus;
|
||||
adev->dev.parent = dev;
|
||||
@ -285,14 +457,13 @@ static int apr_add_device(struct device *dev, struct device_node *np,
|
||||
adev->dev.driver = NULL;
|
||||
|
||||
spin_lock(&apr->svcs_lock);
|
||||
idr_alloc(&apr->svcs_idr, adev, id->svc_id,
|
||||
id->svc_id + 1, GFP_ATOMIC);
|
||||
idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC);
|
||||
spin_unlock(&apr->svcs_lock);
|
||||
|
||||
of_property_read_string_index(np, "qcom,protection-domain",
|
||||
1, &adev->service_path);
|
||||
|
||||
dev_info(dev, "Adding APR dev: %s\n", dev_name(&adev->dev));
|
||||
dev_info(dev, "Adding APR/GPR dev: %s\n", dev_name(&adev->dev));
|
||||
|
||||
ret = device_register(&adev->dev);
|
||||
if (ret) {
|
||||
@ -306,7 +477,7 @@ static int apr_add_device(struct device *dev, struct device_node *np,
|
||||
static int of_apr_add_pd_lookups(struct device *dev)
|
||||
{
|
||||
const char *service_name, *service_path;
|
||||
struct apr *apr = dev_get_drvdata(dev);
|
||||
struct packet_router *apr = dev_get_drvdata(dev);
|
||||
struct device_node *node;
|
||||
struct pdr_service *pds;
|
||||
int ret;
|
||||
@ -336,13 +507,14 @@ static int of_apr_add_pd_lookups(struct device *dev)
|
||||
|
||||
static void of_register_apr_devices(struct device *dev, const char *svc_path)
|
||||
{
|
||||
struct apr *apr = dev_get_drvdata(dev);
|
||||
struct packet_router *apr = dev_get_drvdata(dev);
|
||||
struct device_node *node;
|
||||
const char *service_path;
|
||||
int ret;
|
||||
|
||||
for_each_child_of_node(dev->of_node, node) {
|
||||
struct apr_device_id id = { {0} };
|
||||
u32 svc_id;
|
||||
u32 domain_id;
|
||||
|
||||
/*
|
||||
* This function is called with svc_path NULL during
|
||||
@ -372,13 +544,13 @@ static void of_register_apr_devices(struct device *dev, const char *svc_path)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (of_property_read_u32(node, "reg", &id.svc_id))
|
||||
if (of_property_read_u32(node, "reg", &svc_id))
|
||||
continue;
|
||||
|
||||
id.domain_id = apr->dest_domain_id;
|
||||
domain_id = apr->dest_domain_id;
|
||||
|
||||
if (apr_add_device(dev, node, &id))
|
||||
dev_err(dev, "Failed to add apr %d svc\n", id.svc_id);
|
||||
if (apr_add_device(dev, node, svc_id, domain_id))
|
||||
dev_err(dev, "Failed to add apr %d svc\n", svc_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -398,7 +570,7 @@ static int apr_remove_device(struct device *dev, void *svc_path)
|
||||
|
||||
static void apr_pd_status(int state, char *svc_path, void *priv)
|
||||
{
|
||||
struct apr *apr = (struct apr *)priv;
|
||||
struct packet_router *apr = (struct packet_router *)priv;
|
||||
|
||||
switch (state) {
|
||||
case SERVREG_SERVICE_STATE_UP:
|
||||
@ -413,16 +585,26 @@ static void apr_pd_status(int state, char *svc_path, void *priv)
|
||||
static int apr_probe(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct device *dev = &rpdev->dev;
|
||||
struct apr *apr;
|
||||
struct packet_router *apr;
|
||||
int ret;
|
||||
|
||||
apr = devm_kzalloc(dev, sizeof(*apr), GFP_KERNEL);
|
||||
if (!apr)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = of_property_read_u32(dev->of_node, "qcom,apr-domain", &apr->dest_domain_id);
|
||||
ret = of_property_read_u32(dev->of_node, "qcom,domain", &apr->dest_domain_id);
|
||||
|
||||
if (of_device_is_compatible(dev->of_node, "qcom,gpr")) {
|
||||
apr->type = PR_TYPE_GPR;
|
||||
} else {
|
||||
if (ret) /* try deprecated apr-domain property */
|
||||
ret = of_property_read_u32(dev->of_node, "qcom,apr-domain",
|
||||
&apr->dest_domain_id);
|
||||
apr->type = PR_TYPE_APR;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
dev_err(dev, "APR Domain ID not specified in DT\n");
|
||||
dev_err(dev, "Domain ID not specified in DT\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -465,7 +647,7 @@ destroy_wq:
|
||||
|
||||
static void apr_remove(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct apr *apr = dev_get_drvdata(&rpdev->dev);
|
||||
struct packet_router *apr = dev_get_drvdata(&rpdev->dev);
|
||||
|
||||
pdr_handle_release(apr->pdr);
|
||||
device_for_each_child(&rpdev->dev, NULL, apr_remove_device);
|
||||
@ -502,20 +684,21 @@ void apr_driver_unregister(struct apr_driver *drv)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(apr_driver_unregister);
|
||||
|
||||
static const struct of_device_id apr_of_match[] = {
|
||||
static const struct of_device_id pkt_router_of_match[] = {
|
||||
{ .compatible = "qcom,apr"},
|
||||
{ .compatible = "qcom,apr-v2"},
|
||||
{ .compatible = "qcom,gpr"},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, apr_of_match);
|
||||
MODULE_DEVICE_TABLE(of, pkt_router_of_match);
|
||||
|
||||
static struct rpmsg_driver apr_driver = {
|
||||
static struct rpmsg_driver packet_router_driver = {
|
||||
.probe = apr_probe,
|
||||
.remove = apr_remove,
|
||||
.callback = apr_callback,
|
||||
.drv = {
|
||||
.name = "qcom,apr",
|
||||
.of_match_table = apr_of_match,
|
||||
.of_match_table = pkt_router_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
@ -525,7 +708,7 @@ static int __init apr_init(void)
|
||||
|
||||
ret = bus_register(&aprbus);
|
||||
if (!ret)
|
||||
ret = register_rpmsg_driver(&apr_driver);
|
||||
ret = register_rpmsg_driver(&packet_router_driver);
|
||||
else
|
||||
bus_unregister(&aprbus);
|
||||
|
||||
@ -535,7 +718,7 @@ static int __init apr_init(void)
|
||||
static void __exit apr_exit(void)
|
||||
{
|
||||
bus_unregister(&aprbus);
|
||||
unregister_rpmsg_driver(&apr_driver);
|
||||
unregister_rpmsg_driver(&packet_router_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(apr_init);
|
||||
|
19
include/dt-bindings/soc/qcom,gpr.h
Normal file
19
include/dt-bindings/soc/qcom,gpr.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
|
||||
|
||||
#ifndef __DT_BINDINGS_QCOM_GPR_H
|
||||
#define __DT_BINDINGS_QCOM_GPR_H
|
||||
|
||||
/* DOMAINS */
|
||||
|
||||
#define GPR_DOMAIN_ID_MODEM 1
|
||||
#define GPR_DOMAIN_ID_ADSP 2
|
||||
#define GPR_DOMAIN_ID_APPS 3
|
||||
|
||||
/* Static Services */
|
||||
|
||||
#define GPR_APM_MODULE_IID 1
|
||||
#define GPR_PRM_MODULE_IID 2
|
||||
#define GPR_AMDB_MODULE_IID 3
|
||||
#define GPR_VCPM_MODULE_IID 4
|
||||
|
||||
#endif /* __DT_BINDINGS_QCOM_GPR_H */
|
@ -10,6 +10,37 @@
|
||||
|
||||
#define LPASS_DP_RX 5
|
||||
|
||||
#define LPASS_CDC_DMA_RX0 6
|
||||
#define LPASS_CDC_DMA_RX1 7
|
||||
#define LPASS_CDC_DMA_RX2 8
|
||||
#define LPASS_CDC_DMA_RX3 9
|
||||
#define LPASS_CDC_DMA_RX4 10
|
||||
#define LPASS_CDC_DMA_RX5 11
|
||||
#define LPASS_CDC_DMA_RX6 12
|
||||
#define LPASS_CDC_DMA_RX7 13
|
||||
#define LPASS_CDC_DMA_RX8 14
|
||||
#define LPASS_CDC_DMA_RX9 15
|
||||
|
||||
#define LPASS_CDC_DMA_TX0 16
|
||||
#define LPASS_CDC_DMA_TX1 17
|
||||
#define LPASS_CDC_DMA_TX2 18
|
||||
#define LPASS_CDC_DMA_TX3 19
|
||||
#define LPASS_CDC_DMA_TX4 20
|
||||
#define LPASS_CDC_DMA_TX5 21
|
||||
#define LPASS_CDC_DMA_TX6 22
|
||||
#define LPASS_CDC_DMA_TX7 23
|
||||
#define LPASS_CDC_DMA_TX8 24
|
||||
|
||||
#define LPASS_CDC_DMA_VA_TX0 25
|
||||
#define LPASS_CDC_DMA_VA_TX1 26
|
||||
#define LPASS_CDC_DMA_VA_TX2 27
|
||||
#define LPASS_CDC_DMA_VA_TX3 28
|
||||
#define LPASS_CDC_DMA_VA_TX4 29
|
||||
#define LPASS_CDC_DMA_VA_TX5 30
|
||||
#define LPASS_CDC_DMA_VA_TX6 31
|
||||
#define LPASS_CDC_DMA_VA_TX7 32
|
||||
#define LPASS_CDC_DMA_VA_TX8 33
|
||||
|
||||
#define LPASS_MCLK0 0
|
||||
|
||||
#endif /* __DT_QCOM_LPASS_H */
|
||||
|
@ -2,207 +2,8 @@
|
||||
#ifndef __DT_BINDINGS_Q6_AFE_H__
|
||||
#define __DT_BINDINGS_Q6_AFE_H__
|
||||
|
||||
/* Audio Front End (AFE) virtual ports IDs */
|
||||
#define HDMI_RX 1
|
||||
#define SLIMBUS_0_RX 2
|
||||
#define SLIMBUS_0_TX 3
|
||||
#define SLIMBUS_1_RX 4
|
||||
#define SLIMBUS_1_TX 5
|
||||
#define SLIMBUS_2_RX 6
|
||||
#define SLIMBUS_2_TX 7
|
||||
#define SLIMBUS_3_RX 8
|
||||
#define SLIMBUS_3_TX 9
|
||||
#define SLIMBUS_4_RX 10
|
||||
#define SLIMBUS_4_TX 11
|
||||
#define SLIMBUS_5_RX 12
|
||||
#define SLIMBUS_5_TX 13
|
||||
#define SLIMBUS_6_RX 14
|
||||
#define SLIMBUS_6_TX 15
|
||||
#define PRIMARY_MI2S_RX 16
|
||||
#define PRIMARY_MI2S_TX 17
|
||||
#define SECONDARY_MI2S_RX 18
|
||||
#define SECONDARY_MI2S_TX 19
|
||||
#define TERTIARY_MI2S_RX 20
|
||||
#define TERTIARY_MI2S_TX 21
|
||||
#define QUATERNARY_MI2S_RX 22
|
||||
#define QUATERNARY_MI2S_TX 23
|
||||
#define PRIMARY_TDM_RX_0 24
|
||||
#define PRIMARY_TDM_TX_0 25
|
||||
#define PRIMARY_TDM_RX_1 26
|
||||
#define PRIMARY_TDM_TX_1 27
|
||||
#define PRIMARY_TDM_RX_2 28
|
||||
#define PRIMARY_TDM_TX_2 29
|
||||
#define PRIMARY_TDM_RX_3 30
|
||||
#define PRIMARY_TDM_TX_3 31
|
||||
#define PRIMARY_TDM_RX_4 32
|
||||
#define PRIMARY_TDM_TX_4 33
|
||||
#define PRIMARY_TDM_RX_5 34
|
||||
#define PRIMARY_TDM_TX_5 35
|
||||
#define PRIMARY_TDM_RX_6 36
|
||||
#define PRIMARY_TDM_TX_6 37
|
||||
#define PRIMARY_TDM_RX_7 38
|
||||
#define PRIMARY_TDM_TX_7 39
|
||||
#define SECONDARY_TDM_RX_0 40
|
||||
#define SECONDARY_TDM_TX_0 41
|
||||
#define SECONDARY_TDM_RX_1 42
|
||||
#define SECONDARY_TDM_TX_1 43
|
||||
#define SECONDARY_TDM_RX_2 44
|
||||
#define SECONDARY_TDM_TX_2 45
|
||||
#define SECONDARY_TDM_RX_3 46
|
||||
#define SECONDARY_TDM_TX_3 47
|
||||
#define SECONDARY_TDM_RX_4 48
|
||||
#define SECONDARY_TDM_TX_4 49
|
||||
#define SECONDARY_TDM_RX_5 50
|
||||
#define SECONDARY_TDM_TX_5 51
|
||||
#define SECONDARY_TDM_RX_6 52
|
||||
#define SECONDARY_TDM_TX_6 53
|
||||
#define SECONDARY_TDM_RX_7 54
|
||||
#define SECONDARY_TDM_TX_7 55
|
||||
#define TERTIARY_TDM_RX_0 56
|
||||
#define TERTIARY_TDM_TX_0 57
|
||||
#define TERTIARY_TDM_RX_1 58
|
||||
#define TERTIARY_TDM_TX_1 59
|
||||
#define TERTIARY_TDM_RX_2 60
|
||||
#define TERTIARY_TDM_TX_2 61
|
||||
#define TERTIARY_TDM_RX_3 62
|
||||
#define TERTIARY_TDM_TX_3 63
|
||||
#define TERTIARY_TDM_RX_4 64
|
||||
#define TERTIARY_TDM_TX_4 65
|
||||
#define TERTIARY_TDM_RX_5 66
|
||||
#define TERTIARY_TDM_TX_5 67
|
||||
#define TERTIARY_TDM_RX_6 68
|
||||
#define TERTIARY_TDM_TX_6 69
|
||||
#define TERTIARY_TDM_RX_7 70
|
||||
#define TERTIARY_TDM_TX_7 71
|
||||
#define QUATERNARY_TDM_RX_0 72
|
||||
#define QUATERNARY_TDM_TX_0 73
|
||||
#define QUATERNARY_TDM_RX_1 74
|
||||
#define QUATERNARY_TDM_TX_1 75
|
||||
#define QUATERNARY_TDM_RX_2 76
|
||||
#define QUATERNARY_TDM_TX_2 77
|
||||
#define QUATERNARY_TDM_RX_3 78
|
||||
#define QUATERNARY_TDM_TX_3 79
|
||||
#define QUATERNARY_TDM_RX_4 80
|
||||
#define QUATERNARY_TDM_TX_4 81
|
||||
#define QUATERNARY_TDM_RX_5 82
|
||||
#define QUATERNARY_TDM_TX_5 83
|
||||
#define QUATERNARY_TDM_RX_6 84
|
||||
#define QUATERNARY_TDM_TX_6 85
|
||||
#define QUATERNARY_TDM_RX_7 86
|
||||
#define QUATERNARY_TDM_TX_7 87
|
||||
#define QUINARY_TDM_RX_0 88
|
||||
#define QUINARY_TDM_TX_0 89
|
||||
#define QUINARY_TDM_RX_1 90
|
||||
#define QUINARY_TDM_TX_1 91
|
||||
#define QUINARY_TDM_RX_2 92
|
||||
#define QUINARY_TDM_TX_2 93
|
||||
#define QUINARY_TDM_RX_3 94
|
||||
#define QUINARY_TDM_TX_3 95
|
||||
#define QUINARY_TDM_RX_4 96
|
||||
#define QUINARY_TDM_TX_4 97
|
||||
#define QUINARY_TDM_RX_5 98
|
||||
#define QUINARY_TDM_TX_5 99
|
||||
#define QUINARY_TDM_RX_6 100
|
||||
#define QUINARY_TDM_TX_6 101
|
||||
#define QUINARY_TDM_RX_7 102
|
||||
#define QUINARY_TDM_TX_7 103
|
||||
#define DISPLAY_PORT_RX 104
|
||||
#define WSA_CODEC_DMA_RX_0 105
|
||||
#define WSA_CODEC_DMA_TX_0 106
|
||||
#define WSA_CODEC_DMA_RX_1 107
|
||||
#define WSA_CODEC_DMA_TX_1 108
|
||||
#define WSA_CODEC_DMA_TX_2 109
|
||||
#define VA_CODEC_DMA_TX_0 110
|
||||
#define VA_CODEC_DMA_TX_1 111
|
||||
#define VA_CODEC_DMA_TX_2 112
|
||||
#define RX_CODEC_DMA_RX_0 113
|
||||
#define TX_CODEC_DMA_TX_0 114
|
||||
#define RX_CODEC_DMA_RX_1 115
|
||||
#define TX_CODEC_DMA_TX_1 116
|
||||
#define RX_CODEC_DMA_RX_2 117
|
||||
#define TX_CODEC_DMA_TX_2 118
|
||||
#define RX_CODEC_DMA_RX_3 119
|
||||
#define TX_CODEC_DMA_TX_3 120
|
||||
#define RX_CODEC_DMA_RX_4 121
|
||||
#define TX_CODEC_DMA_TX_4 122
|
||||
#define RX_CODEC_DMA_RX_5 123
|
||||
#define TX_CODEC_DMA_TX_5 124
|
||||
#define RX_CODEC_DMA_RX_6 125
|
||||
#define RX_CODEC_DMA_RX_7 126
|
||||
#define QUINARY_MI2S_RX 127
|
||||
#define QUINARY_MI2S_TX 128
|
||||
/* This file exists due to backward compatibility reasons, Please do not DELETE! */
|
||||
|
||||
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
|
||||
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2
|
||||
#define LPASS_CLK_ID_SEC_MI2S_IBIT 3
|
||||
#define LPASS_CLK_ID_SEC_MI2S_EBIT 4
|
||||
#define LPASS_CLK_ID_TER_MI2S_IBIT 5
|
||||
#define LPASS_CLK_ID_TER_MI2S_EBIT 6
|
||||
#define LPASS_CLK_ID_QUAD_MI2S_IBIT 7
|
||||
#define LPASS_CLK_ID_QUAD_MI2S_EBIT 8
|
||||
#define LPASS_CLK_ID_SPEAKER_I2S_IBIT 9
|
||||
#define LPASS_CLK_ID_SPEAKER_I2S_EBIT 10
|
||||
#define LPASS_CLK_ID_SPEAKER_I2S_OSR 11
|
||||
#define LPASS_CLK_ID_QUI_MI2S_IBIT 12
|
||||
#define LPASS_CLK_ID_QUI_MI2S_EBIT 13
|
||||
#define LPASS_CLK_ID_SEN_MI2S_IBIT 14
|
||||
#define LPASS_CLK_ID_SEN_MI2S_EBIT 15
|
||||
#define LPASS_CLK_ID_INT0_MI2S_IBIT 16
|
||||
#define LPASS_CLK_ID_INT1_MI2S_IBIT 17
|
||||
#define LPASS_CLK_ID_INT2_MI2S_IBIT 18
|
||||
#define LPASS_CLK_ID_INT3_MI2S_IBIT 19
|
||||
#define LPASS_CLK_ID_INT4_MI2S_IBIT 20
|
||||
#define LPASS_CLK_ID_INT5_MI2S_IBIT 21
|
||||
#define LPASS_CLK_ID_INT6_MI2S_IBIT 22
|
||||
#define LPASS_CLK_ID_QUI_MI2S_OSR 23
|
||||
#define LPASS_CLK_ID_PRI_PCM_IBIT 24
|
||||
#define LPASS_CLK_ID_PRI_PCM_EBIT 25
|
||||
#define LPASS_CLK_ID_SEC_PCM_IBIT 26
|
||||
#define LPASS_CLK_ID_SEC_PCM_EBIT 27
|
||||
#define LPASS_CLK_ID_TER_PCM_IBIT 28
|
||||
#define LPASS_CLK_ID_TER_PCM_EBIT 29
|
||||
#define LPASS_CLK_ID_QUAD_PCM_IBIT 30
|
||||
#define LPASS_CLK_ID_QUAD_PCM_EBIT 31
|
||||
#define LPASS_CLK_ID_QUIN_PCM_IBIT 32
|
||||
#define LPASS_CLK_ID_QUIN_PCM_EBIT 33
|
||||
#define LPASS_CLK_ID_QUI_PCM_OSR 34
|
||||
#define LPASS_CLK_ID_PRI_TDM_IBIT 35
|
||||
#define LPASS_CLK_ID_PRI_TDM_EBIT 36
|
||||
#define LPASS_CLK_ID_SEC_TDM_IBIT 37
|
||||
#define LPASS_CLK_ID_SEC_TDM_EBIT 38
|
||||
#define LPASS_CLK_ID_TER_TDM_IBIT 39
|
||||
#define LPASS_CLK_ID_TER_TDM_EBIT 40
|
||||
#define LPASS_CLK_ID_QUAD_TDM_IBIT 41
|
||||
#define LPASS_CLK_ID_QUAD_TDM_EBIT 42
|
||||
#define LPASS_CLK_ID_QUIN_TDM_IBIT 43
|
||||
#define LPASS_CLK_ID_QUIN_TDM_EBIT 44
|
||||
#define LPASS_CLK_ID_QUIN_TDM_OSR 45
|
||||
#define LPASS_CLK_ID_MCLK_1 46
|
||||
#define LPASS_CLK_ID_MCLK_2 47
|
||||
#define LPASS_CLK_ID_MCLK_3 48
|
||||
#define LPASS_CLK_ID_MCLK_4 49
|
||||
#define LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE 50
|
||||
#define LPASS_CLK_ID_INT_MCLK_0 51
|
||||
#define LPASS_CLK_ID_INT_MCLK_1 52
|
||||
#define LPASS_CLK_ID_MCLK_5 53
|
||||
#define LPASS_CLK_ID_WSA_CORE_MCLK 54
|
||||
#define LPASS_CLK_ID_WSA_CORE_NPL_MCLK 55
|
||||
#define LPASS_CLK_ID_VA_CORE_MCLK 56
|
||||
#define LPASS_CLK_ID_TX_CORE_MCLK 57
|
||||
#define LPASS_CLK_ID_TX_CORE_NPL_MCLK 58
|
||||
#define LPASS_CLK_ID_RX_CORE_MCLK 59
|
||||
#define LPASS_CLK_ID_RX_CORE_NPL_MCLK 60
|
||||
#define LPASS_CLK_ID_VA_CORE_2X_MCLK 61
|
||||
|
||||
#define LPASS_HW_AVTIMER_VOTE 101
|
||||
#define LPASS_HW_MACRO_VOTE 102
|
||||
#define LPASS_HW_DCODEC_VOTE 103
|
||||
|
||||
#define Q6AFE_MAX_CLK_ID 104
|
||||
|
||||
#define LPASS_CLK_ATTRIBUTE_INVALID 0x0
|
||||
#define LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1
|
||||
#define LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND 0x2
|
||||
#define LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR 0x3
|
||||
#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
|
||||
|
||||
#endif /* __DT_BINDINGS_Q6_AFE_H__ */
|
||||
|
208
include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
Normal file
208
include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
Normal file
@ -0,0 +1,208 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DT_BINDINGS_Q6_AUDIO_PORTS_H__
|
||||
#define __DT_BINDINGS_Q6_AUDIO_PORTS_H__
|
||||
|
||||
/* LPASS Audio virtual ports IDs */
|
||||
#define HDMI_RX 1
|
||||
#define SLIMBUS_0_RX 2
|
||||
#define SLIMBUS_0_TX 3
|
||||
#define SLIMBUS_1_RX 4
|
||||
#define SLIMBUS_1_TX 5
|
||||
#define SLIMBUS_2_RX 6
|
||||
#define SLIMBUS_2_TX 7
|
||||
#define SLIMBUS_3_RX 8
|
||||
#define SLIMBUS_3_TX 9
|
||||
#define SLIMBUS_4_RX 10
|
||||
#define SLIMBUS_4_TX 11
|
||||
#define SLIMBUS_5_RX 12
|
||||
#define SLIMBUS_5_TX 13
|
||||
#define SLIMBUS_6_RX 14
|
||||
#define SLIMBUS_6_TX 15
|
||||
#define PRIMARY_MI2S_RX 16
|
||||
#define PRIMARY_MI2S_TX 17
|
||||
#define SECONDARY_MI2S_RX 18
|
||||
#define SECONDARY_MI2S_TX 19
|
||||
#define TERTIARY_MI2S_RX 20
|
||||
#define TERTIARY_MI2S_TX 21
|
||||
#define QUATERNARY_MI2S_RX 22
|
||||
#define QUATERNARY_MI2S_TX 23
|
||||
#define PRIMARY_TDM_RX_0 24
|
||||
#define PRIMARY_TDM_TX_0 25
|
||||
#define PRIMARY_TDM_RX_1 26
|
||||
#define PRIMARY_TDM_TX_1 27
|
||||
#define PRIMARY_TDM_RX_2 28
|
||||
#define PRIMARY_TDM_TX_2 29
|
||||
#define PRIMARY_TDM_RX_3 30
|
||||
#define PRIMARY_TDM_TX_3 31
|
||||
#define PRIMARY_TDM_RX_4 32
|
||||
#define PRIMARY_TDM_TX_4 33
|
||||
#define PRIMARY_TDM_RX_5 34
|
||||
#define PRIMARY_TDM_TX_5 35
|
||||
#define PRIMARY_TDM_RX_6 36
|
||||
#define PRIMARY_TDM_TX_6 37
|
||||
#define PRIMARY_TDM_RX_7 38
|
||||
#define PRIMARY_TDM_TX_7 39
|
||||
#define SECONDARY_TDM_RX_0 40
|
||||
#define SECONDARY_TDM_TX_0 41
|
||||
#define SECONDARY_TDM_RX_1 42
|
||||
#define SECONDARY_TDM_TX_1 43
|
||||
#define SECONDARY_TDM_RX_2 44
|
||||
#define SECONDARY_TDM_TX_2 45
|
||||
#define SECONDARY_TDM_RX_3 46
|
||||
#define SECONDARY_TDM_TX_3 47
|
||||
#define SECONDARY_TDM_RX_4 48
|
||||
#define SECONDARY_TDM_TX_4 49
|
||||
#define SECONDARY_TDM_RX_5 50
|
||||
#define SECONDARY_TDM_TX_5 51
|
||||
#define SECONDARY_TDM_RX_6 52
|
||||
#define SECONDARY_TDM_TX_6 53
|
||||
#define SECONDARY_TDM_RX_7 54
|
||||
#define SECONDARY_TDM_TX_7 55
|
||||
#define TERTIARY_TDM_RX_0 56
|
||||
#define TERTIARY_TDM_TX_0 57
|
||||
#define TERTIARY_TDM_RX_1 58
|
||||
#define TERTIARY_TDM_TX_1 59
|
||||
#define TERTIARY_TDM_RX_2 60
|
||||
#define TERTIARY_TDM_TX_2 61
|
||||
#define TERTIARY_TDM_RX_3 62
|
||||
#define TERTIARY_TDM_TX_3 63
|
||||
#define TERTIARY_TDM_RX_4 64
|
||||
#define TERTIARY_TDM_TX_4 65
|
||||
#define TERTIARY_TDM_RX_5 66
|
||||
#define TERTIARY_TDM_TX_5 67
|
||||
#define TERTIARY_TDM_RX_6 68
|
||||
#define TERTIARY_TDM_TX_6 69
|
||||
#define TERTIARY_TDM_RX_7 70
|
||||
#define TERTIARY_TDM_TX_7 71
|
||||
#define QUATERNARY_TDM_RX_0 72
|
||||
#define QUATERNARY_TDM_TX_0 73
|
||||
#define QUATERNARY_TDM_RX_1 74
|
||||
#define QUATERNARY_TDM_TX_1 75
|
||||
#define QUATERNARY_TDM_RX_2 76
|
||||
#define QUATERNARY_TDM_TX_2 77
|
||||
#define QUATERNARY_TDM_RX_3 78
|
||||
#define QUATERNARY_TDM_TX_3 79
|
||||
#define QUATERNARY_TDM_RX_4 80
|
||||
#define QUATERNARY_TDM_TX_4 81
|
||||
#define QUATERNARY_TDM_RX_5 82
|
||||
#define QUATERNARY_TDM_TX_5 83
|
||||
#define QUATERNARY_TDM_RX_6 84
|
||||
#define QUATERNARY_TDM_TX_6 85
|
||||
#define QUATERNARY_TDM_RX_7 86
|
||||
#define QUATERNARY_TDM_TX_7 87
|
||||
#define QUINARY_TDM_RX_0 88
|
||||
#define QUINARY_TDM_TX_0 89
|
||||
#define QUINARY_TDM_RX_1 90
|
||||
#define QUINARY_TDM_TX_1 91
|
||||
#define QUINARY_TDM_RX_2 92
|
||||
#define QUINARY_TDM_TX_2 93
|
||||
#define QUINARY_TDM_RX_3 94
|
||||
#define QUINARY_TDM_TX_3 95
|
||||
#define QUINARY_TDM_RX_4 96
|
||||
#define QUINARY_TDM_TX_4 97
|
||||
#define QUINARY_TDM_RX_5 98
|
||||
#define QUINARY_TDM_TX_5 99
|
||||
#define QUINARY_TDM_RX_6 100
|
||||
#define QUINARY_TDM_TX_6 101
|
||||
#define QUINARY_TDM_RX_7 102
|
||||
#define QUINARY_TDM_TX_7 103
|
||||
#define DISPLAY_PORT_RX 104
|
||||
#define WSA_CODEC_DMA_RX_0 105
|
||||
#define WSA_CODEC_DMA_TX_0 106
|
||||
#define WSA_CODEC_DMA_RX_1 107
|
||||
#define WSA_CODEC_DMA_TX_1 108
|
||||
#define WSA_CODEC_DMA_TX_2 109
|
||||
#define VA_CODEC_DMA_TX_0 110
|
||||
#define VA_CODEC_DMA_TX_1 111
|
||||
#define VA_CODEC_DMA_TX_2 112
|
||||
#define RX_CODEC_DMA_RX_0 113
|
||||
#define TX_CODEC_DMA_TX_0 114
|
||||
#define RX_CODEC_DMA_RX_1 115
|
||||
#define TX_CODEC_DMA_TX_1 116
|
||||
#define RX_CODEC_DMA_RX_2 117
|
||||
#define TX_CODEC_DMA_TX_2 118
|
||||
#define RX_CODEC_DMA_RX_3 119
|
||||
#define TX_CODEC_DMA_TX_3 120
|
||||
#define RX_CODEC_DMA_RX_4 121
|
||||
#define TX_CODEC_DMA_TX_4 122
|
||||
#define RX_CODEC_DMA_RX_5 123
|
||||
#define TX_CODEC_DMA_TX_5 124
|
||||
#define RX_CODEC_DMA_RX_6 125
|
||||
#define RX_CODEC_DMA_RX_7 126
|
||||
#define QUINARY_MI2S_RX 127
|
||||
#define QUINARY_MI2S_TX 128
|
||||
|
||||
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
|
||||
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2
|
||||
#define LPASS_CLK_ID_SEC_MI2S_IBIT 3
|
||||
#define LPASS_CLK_ID_SEC_MI2S_EBIT 4
|
||||
#define LPASS_CLK_ID_TER_MI2S_IBIT 5
|
||||
#define LPASS_CLK_ID_TER_MI2S_EBIT 6
|
||||
#define LPASS_CLK_ID_QUAD_MI2S_IBIT 7
|
||||
#define LPASS_CLK_ID_QUAD_MI2S_EBIT 8
|
||||
#define LPASS_CLK_ID_SPEAKER_I2S_IBIT 9
|
||||
#define LPASS_CLK_ID_SPEAKER_I2S_EBIT 10
|
||||
#define LPASS_CLK_ID_SPEAKER_I2S_OSR 11
|
||||
#define LPASS_CLK_ID_QUI_MI2S_IBIT 12
|
||||
#define LPASS_CLK_ID_QUI_MI2S_EBIT 13
|
||||
#define LPASS_CLK_ID_SEN_MI2S_IBIT 14
|
||||
#define LPASS_CLK_ID_SEN_MI2S_EBIT 15
|
||||
#define LPASS_CLK_ID_INT0_MI2S_IBIT 16
|
||||
#define LPASS_CLK_ID_INT1_MI2S_IBIT 17
|
||||
#define LPASS_CLK_ID_INT2_MI2S_IBIT 18
|
||||
#define LPASS_CLK_ID_INT3_MI2S_IBIT 19
|
||||
#define LPASS_CLK_ID_INT4_MI2S_IBIT 20
|
||||
#define LPASS_CLK_ID_INT5_MI2S_IBIT 21
|
||||
#define LPASS_CLK_ID_INT6_MI2S_IBIT 22
|
||||
#define LPASS_CLK_ID_QUI_MI2S_OSR 23
|
||||
#define LPASS_CLK_ID_PRI_PCM_IBIT 24
|
||||
#define LPASS_CLK_ID_PRI_PCM_EBIT 25
|
||||
#define LPASS_CLK_ID_SEC_PCM_IBIT 26
|
||||
#define LPASS_CLK_ID_SEC_PCM_EBIT 27
|
||||
#define LPASS_CLK_ID_TER_PCM_IBIT 28
|
||||
#define LPASS_CLK_ID_TER_PCM_EBIT 29
|
||||
#define LPASS_CLK_ID_QUAD_PCM_IBIT 30
|
||||
#define LPASS_CLK_ID_QUAD_PCM_EBIT 31
|
||||
#define LPASS_CLK_ID_QUIN_PCM_IBIT 32
|
||||
#define LPASS_CLK_ID_QUIN_PCM_EBIT 33
|
||||
#define LPASS_CLK_ID_QUI_PCM_OSR 34
|
||||
#define LPASS_CLK_ID_PRI_TDM_IBIT 35
|
||||
#define LPASS_CLK_ID_PRI_TDM_EBIT 36
|
||||
#define LPASS_CLK_ID_SEC_TDM_IBIT 37
|
||||
#define LPASS_CLK_ID_SEC_TDM_EBIT 38
|
||||
#define LPASS_CLK_ID_TER_TDM_IBIT 39
|
||||
#define LPASS_CLK_ID_TER_TDM_EBIT 40
|
||||
#define LPASS_CLK_ID_QUAD_TDM_IBIT 41
|
||||
#define LPASS_CLK_ID_QUAD_TDM_EBIT 42
|
||||
#define LPASS_CLK_ID_QUIN_TDM_IBIT 43
|
||||
#define LPASS_CLK_ID_QUIN_TDM_EBIT 44
|
||||
#define LPASS_CLK_ID_QUIN_TDM_OSR 45
|
||||
#define LPASS_CLK_ID_MCLK_1 46
|
||||
#define LPASS_CLK_ID_MCLK_2 47
|
||||
#define LPASS_CLK_ID_MCLK_3 48
|
||||
#define LPASS_CLK_ID_MCLK_4 49
|
||||
#define LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE 50
|
||||
#define LPASS_CLK_ID_INT_MCLK_0 51
|
||||
#define LPASS_CLK_ID_INT_MCLK_1 52
|
||||
#define LPASS_CLK_ID_MCLK_5 53
|
||||
#define LPASS_CLK_ID_WSA_CORE_MCLK 54
|
||||
#define LPASS_CLK_ID_WSA_CORE_NPL_MCLK 55
|
||||
#define LPASS_CLK_ID_VA_CORE_MCLK 56
|
||||
#define LPASS_CLK_ID_TX_CORE_MCLK 57
|
||||
#define LPASS_CLK_ID_TX_CORE_NPL_MCLK 58
|
||||
#define LPASS_CLK_ID_RX_CORE_MCLK 59
|
||||
#define LPASS_CLK_ID_RX_CORE_NPL_MCLK 60
|
||||
#define LPASS_CLK_ID_VA_CORE_2X_MCLK 61
|
||||
|
||||
#define LPASS_HW_AVTIMER_VOTE 101
|
||||
#define LPASS_HW_MACRO_VOTE 102
|
||||
#define LPASS_HW_DCODEC_VOTE 103
|
||||
|
||||
#define Q6AFE_MAX_CLK_ID 104
|
||||
|
||||
#define LPASS_CLK_ATTRIBUTE_INVALID 0x0
|
||||
#define LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1
|
||||
#define LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND 0x2
|
||||
#define LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR 0x3
|
||||
|
||||
#endif /* __DT_BINDINGS_Q6_AUDIO_PORTS_H__ */
|
242
include/linux/firmware/cirrus/cs_dsp.h
Normal file
242
include/linux/firmware/cirrus/cs_dsp.h
Normal file
@ -0,0 +1,242 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* cs_dsp.h -- Cirrus Logic DSP firmware support
|
||||
*
|
||||
* Based on sound/soc/codecs/wm_adsp.h
|
||||
*
|
||||
* Copyright 2012 Wolfson Microelectronics plc
|
||||
* Copyright (C) 2015-2021 Cirrus Logic, Inc. and
|
||||
* Cirrus Logic International Semiconductor Ltd.
|
||||
*/
|
||||
#ifndef __CS_DSP_H
|
||||
#define __CS_DSP_H
|
||||
|
||||
#define CS_ADSP2_REGION_0 BIT(0)
|
||||
#define CS_ADSP2_REGION_1 BIT(1)
|
||||
#define CS_ADSP2_REGION_2 BIT(2)
|
||||
#define CS_ADSP2_REGION_3 BIT(3)
|
||||
#define CS_ADSP2_REGION_4 BIT(4)
|
||||
#define CS_ADSP2_REGION_5 BIT(5)
|
||||
#define CS_ADSP2_REGION_6 BIT(6)
|
||||
#define CS_ADSP2_REGION_7 BIT(7)
|
||||
#define CS_ADSP2_REGION_8 BIT(8)
|
||||
#define CS_ADSP2_REGION_9 BIT(9)
|
||||
#define CS_ADSP2_REGION_1_9 (CS_ADSP2_REGION_1 | \
|
||||
CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3 | \
|
||||
CS_ADSP2_REGION_4 | CS_ADSP2_REGION_5 | \
|
||||
CS_ADSP2_REGION_6 | CS_ADSP2_REGION_7 | \
|
||||
CS_ADSP2_REGION_8 | CS_ADSP2_REGION_9)
|
||||
#define CS_ADSP2_REGION_ALL (CS_ADSP2_REGION_0 | CS_ADSP2_REGION_1_9)
|
||||
|
||||
#define CS_DSP_DATA_WORD_SIZE 3
|
||||
|
||||
#define CS_DSP_ACKED_CTL_TIMEOUT_MS 100
|
||||
#define CS_DSP_ACKED_CTL_N_QUICKPOLLS 10
|
||||
#define CS_DSP_ACKED_CTL_MIN_VALUE 0
|
||||
#define CS_DSP_ACKED_CTL_MAX_VALUE 0xFFFFFF
|
||||
|
||||
/**
|
||||
* struct cs_dsp_region - Describes a logical memory region in DSP address space
|
||||
* @type: Memory region type
|
||||
* @base: Address of region
|
||||
*/
|
||||
struct cs_dsp_region {
|
||||
int type;
|
||||
unsigned int base;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cs_dsp_alg_region - Describes a logical algorithm region in DSP address space
|
||||
* @list: List node for internal use
|
||||
* @alg: Algorithm id
|
||||
* @type: Memory region type
|
||||
* @base: Address of region
|
||||
*/
|
||||
struct cs_dsp_alg_region {
|
||||
struct list_head list;
|
||||
unsigned int alg;
|
||||
int type;
|
||||
unsigned int base;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cs_dsp_coeff_ctl - Describes a coefficient control
|
||||
* @fw_name: Name of the firmware
|
||||
* @subname: Name of the control parsed from the WMFW
|
||||
* @subname_len: Length of subname
|
||||
* @alg_region: Logical region associated with this control
|
||||
* @dsp: DSP instance associated with this control
|
||||
* @enabled: Flag indicating whether control is enabled
|
||||
* @list: List node for internal use
|
||||
* @cache: Cached value of the control
|
||||
* @offset: Offset of control within alg_region
|
||||
* @len: Length of the cached value
|
||||
* @set: Flag indicating the value has been written by the user
|
||||
* @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h
|
||||
* @type: One of the WMFW_CTL_TYPE_ control types defined in wmfw.h
|
||||
* @priv: For use by the client
|
||||
*/
|
||||
struct cs_dsp_coeff_ctl {
|
||||
const char *fw_name;
|
||||
/* Subname is needed to match with firmware */
|
||||
const char *subname;
|
||||
unsigned int subname_len;
|
||||
struct cs_dsp_alg_region alg_region;
|
||||
struct cs_dsp *dsp;
|
||||
unsigned int enabled:1;
|
||||
struct list_head list;
|
||||
void *cache;
|
||||
unsigned int offset;
|
||||
size_t len;
|
||||
unsigned int set:1;
|
||||
unsigned int flags;
|
||||
unsigned int type;
|
||||
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct cs_dsp_ops;
|
||||
struct cs_dsp_client_ops;
|
||||
|
||||
/**
|
||||
* struct cs_dsp - Configuration and state of a Cirrus Logic DSP
|
||||
* @name: The name of the DSP instance
|
||||
* @rev: Revision of the DSP
|
||||
* @num: DSP instance number
|
||||
* @type: Type of DSP
|
||||
* @dev: Driver model representation of the device
|
||||
* @regmap: Register map of the device
|
||||
* @ops: Function pointers for internal callbacks
|
||||
* @client_ops: Function pointers for client callbacks
|
||||
* @base: Address of the DSP registers
|
||||
* @base_sysinfo: Address of the sysinfo register (Halo only)
|
||||
* @sysclk_reg: Address of the sysclk register (ADSP1 only)
|
||||
* @sysclk_mask: Mask of frequency bits within sysclk register (ADSP1 only)
|
||||
* @sysclk_shift: Shift of frequency bits within sysclk register (ADSP1 only)
|
||||
* @alg_regions: List of currently loaded algorithm regions
|
||||
* @fw_file_name: Filename of the current firmware
|
||||
* @fw_name: Name of the current firmware
|
||||
* @fw_id: ID of the current firmware, obtained from the wmfw
|
||||
* @fw_id_version: Version of the firmware, obtained from the wmfw
|
||||
* @fw_vendor_id: Vendor of the firmware, obtained from the wmfw
|
||||
* @mem: DSP memory region descriptions
|
||||
* @num_mems: Number of memory regions in this DSP
|
||||
* @fw_ver: Version of the wmfw file format
|
||||
* @booted: Flag indicating DSP has been configured
|
||||
* @running: Flag indicating DSP is executing firmware
|
||||
* @ctl_list: Controls defined within the loaded DSP firmware
|
||||
* @lock_regions: Enable MPU traps on specified memory regions
|
||||
* @pwr_lock: Lock used to serialize accesses
|
||||
* @debugfs_root: Debugfs directory for this DSP instance
|
||||
* @wmfw_file_name: Filename of the currently loaded firmware
|
||||
* @bin_file_name: Filename of the currently loaded coefficients
|
||||
*/
|
||||
struct cs_dsp {
|
||||
const char *name;
|
||||
int rev;
|
||||
int num;
|
||||
int type;
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
|
||||
const struct cs_dsp_ops *ops;
|
||||
const struct cs_dsp_client_ops *client_ops;
|
||||
|
||||
unsigned int base;
|
||||
unsigned int base_sysinfo;
|
||||
unsigned int sysclk_reg;
|
||||
unsigned int sysclk_mask;
|
||||
unsigned int sysclk_shift;
|
||||
|
||||
struct list_head alg_regions;
|
||||
|
||||
const char *fw_name;
|
||||
unsigned int fw_id;
|
||||
unsigned int fw_id_version;
|
||||
unsigned int fw_vendor_id;
|
||||
|
||||
const struct cs_dsp_region *mem;
|
||||
int num_mems;
|
||||
|
||||
int fw_ver;
|
||||
|
||||
bool booted;
|
||||
bool running;
|
||||
|
||||
struct list_head ctl_list;
|
||||
|
||||
struct mutex pwr_lock;
|
||||
|
||||
unsigned int lock_regions;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs_root;
|
||||
char *wmfw_file_name;
|
||||
char *bin_file_name;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cs_dsp_client_ops - client callbacks
|
||||
* @control_add: Called under the pwr_lock when a control is created
|
||||
* @control_remove: Called under the pwr_lock when a control is destroyed
|
||||
* @post_run: Called under the pwr_lock by cs_dsp_run()
|
||||
* @post_stop: Called under the pwr_lock by cs_dsp_stop()
|
||||
* @watchdog_expired: Called when a watchdog expiry is detected
|
||||
*
|
||||
* These callbacks give the cs_dsp client an opportunity to respond to events
|
||||
* or to perform actions atomically.
|
||||
*/
|
||||
struct cs_dsp_client_ops {
|
||||
int (*control_add)(struct cs_dsp_coeff_ctl *ctl);
|
||||
void (*control_remove)(struct cs_dsp_coeff_ctl *ctl);
|
||||
int (*post_run)(struct cs_dsp *dsp);
|
||||
void (*post_stop)(struct cs_dsp *dsp);
|
||||
void (*watchdog_expired)(struct cs_dsp *dsp);
|
||||
};
|
||||
|
||||
int cs_dsp_adsp1_init(struct cs_dsp *dsp);
|
||||
int cs_dsp_adsp2_init(struct cs_dsp *dsp);
|
||||
int cs_dsp_halo_init(struct cs_dsp *dsp);
|
||||
|
||||
int cs_dsp_adsp1_power_up(struct cs_dsp *dsp,
|
||||
const struct firmware *wmfw_firmware, char *wmfw_filename,
|
||||
const struct firmware *coeff_firmware, char *coeff_filename,
|
||||
const char *fw_name);
|
||||
void cs_dsp_adsp1_power_down(struct cs_dsp *dsp);
|
||||
int cs_dsp_power_up(struct cs_dsp *dsp,
|
||||
const struct firmware *wmfw_firmware, char *wmfw_filename,
|
||||
const struct firmware *coeff_firmware, char *coeff_filename,
|
||||
const char *fw_name);
|
||||
void cs_dsp_power_down(struct cs_dsp *dsp);
|
||||
int cs_dsp_run(struct cs_dsp *dsp);
|
||||
void cs_dsp_stop(struct cs_dsp *dsp);
|
||||
|
||||
void cs_dsp_remove(struct cs_dsp *dsp);
|
||||
|
||||
int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq);
|
||||
void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp);
|
||||
void cs_dsp_halo_bus_error(struct cs_dsp *dsp);
|
||||
void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp);
|
||||
|
||||
void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root);
|
||||
void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp);
|
||||
|
||||
int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id);
|
||||
int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, const void *buf, size_t len);
|
||||
int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, void *buf, size_t len);
|
||||
struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type,
|
||||
unsigned int alg);
|
||||
|
||||
int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr,
|
||||
unsigned int num_words, __be32 *data);
|
||||
int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 *data);
|
||||
int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data);
|
||||
void cs_dsp_remove_padding(u32 *buf, int nwords);
|
||||
|
||||
struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp,
|
||||
int type, unsigned int id);
|
||||
|
||||
const char *cs_dsp_mem_region_name(unsigned int type);
|
||||
|
||||
#endif
|
@ -23,10 +23,12 @@
|
||||
#define WMFW_CTL_FLAG_WRITEABLE 0x0002
|
||||
#define WMFW_CTL_FLAG_READABLE 0x0001
|
||||
|
||||
#define WMFW_CTL_TYPE_BYTES 0x0004 /* byte control */
|
||||
|
||||
/* Non-ALSA coefficient types start at 0x1000 */
|
||||
#define WMFW_CTL_TYPE_ACKED ((__force snd_ctl_elem_type_t)0x1000) /* acked control */
|
||||
#define WMFW_CTL_TYPE_HOSTEVENT ((__force snd_ctl_elem_type_t)0x1001) /* event control */
|
||||
#define WMFW_CTL_TYPE_HOST_BUFFER ((__force snd_ctl_elem_type_t)0x1002) /* host buffer pointer */
|
||||
#define WMFW_CTL_TYPE_ACKED 0x1000 /* acked control */
|
||||
#define WMFW_CTL_TYPE_HOSTEVENT 0x1001 /* event control */
|
||||
#define WMFW_CTL_TYPE_HOST_BUFFER 0x1002 /* host buffer pointer */
|
||||
|
||||
struct wmfw_header {
|
||||
char magic[4];
|
@ -7,6 +7,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <dt-bindings/soc/qcom,apr.h>
|
||||
#include <dt-bindings/soc/qcom,gpr.h>
|
||||
|
||||
extern struct bus_type aprbus;
|
||||
|
||||
@ -75,10 +76,65 @@ struct apr_resp_pkt {
|
||||
int payload_size;
|
||||
};
|
||||
|
||||
struct gpr_hdr {
|
||||
uint32_t version:4;
|
||||
uint32_t hdr_size:4;
|
||||
uint32_t pkt_size:24;
|
||||
uint32_t dest_domain:8;
|
||||
uint32_t src_domain:8;
|
||||
uint32_t reserved:16;
|
||||
uint32_t src_port;
|
||||
uint32_t dest_port;
|
||||
uint32_t token;
|
||||
uint32_t opcode;
|
||||
} __packed;
|
||||
|
||||
struct gpr_pkt {
|
||||
struct gpr_hdr hdr;
|
||||
uint32_t payload[];
|
||||
};
|
||||
|
||||
struct gpr_resp_pkt {
|
||||
struct gpr_hdr hdr;
|
||||
void *payload;
|
||||
int payload_size;
|
||||
};
|
||||
|
||||
#define GPR_HDR_SIZE sizeof(struct gpr_hdr)
|
||||
#define GPR_PKT_VER 0x0
|
||||
#define GPR_PKT_HEADER_WORD_SIZE ((sizeof(struct gpr_pkt) + 3) >> 2)
|
||||
#define GPR_PKT_HEADER_BYTE_SIZE (GPR_PKT_HEADER_WORD_SIZE << 2)
|
||||
|
||||
#define GPR_BASIC_RSP_RESULT 0x02001005
|
||||
|
||||
struct gpr_ibasic_rsp_result_t {
|
||||
uint32_t opcode;
|
||||
uint32_t status;
|
||||
};
|
||||
|
||||
#define GPR_BASIC_EVT_ACCEPTED 0x02001006
|
||||
|
||||
struct gpr_ibasic_rsp_accepted_t {
|
||||
uint32_t opcode;
|
||||
};
|
||||
|
||||
/* Bits 0 to 15 -- Minor version, Bits 16 to 31 -- Major version */
|
||||
#define APR_SVC_MAJOR_VERSION(v) ((v >> 16) & 0xFF)
|
||||
#define APR_SVC_MINOR_VERSION(v) (v & 0xFF)
|
||||
|
||||
typedef int (*gpr_port_cb) (struct gpr_resp_pkt *d, void *priv, int op);
|
||||
struct packet_router;
|
||||
struct pkt_router_svc {
|
||||
struct device *dev;
|
||||
gpr_port_cb callback;
|
||||
struct packet_router *pr;
|
||||
spinlock_t lock;
|
||||
int id;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
typedef struct pkt_router_svc gpr_port_t;
|
||||
|
||||
struct apr_device {
|
||||
struct device dev;
|
||||
uint16_t svc_id;
|
||||
@ -86,21 +142,26 @@ struct apr_device {
|
||||
uint32_t version;
|
||||
char name[APR_NAME_SIZE];
|
||||
const char *service_path;
|
||||
spinlock_t lock;
|
||||
struct pkt_router_svc svc;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
typedef struct apr_device gpr_device_t;
|
||||
|
||||
#define to_apr_device(d) container_of(d, struct apr_device, dev)
|
||||
#define svc_to_apr_device(d) container_of(d, struct apr_device, svc)
|
||||
|
||||
struct apr_driver {
|
||||
int (*probe)(struct apr_device *sl);
|
||||
int (*remove)(struct apr_device *sl);
|
||||
int (*callback)(struct apr_device *a,
|
||||
struct apr_resp_pkt *d);
|
||||
int (*gpr_callback)(struct gpr_resp_pkt *d, void *data, int op);
|
||||
struct device_driver driver;
|
||||
const struct apr_device_id *id_table;
|
||||
};
|
||||
|
||||
typedef struct apr_driver gpr_driver_t;
|
||||
#define to_apr_driver(d) container_of(d, struct apr_driver, driver)
|
||||
|
||||
/*
|
||||
@ -123,7 +184,14 @@ void apr_driver_unregister(struct apr_driver *drv);
|
||||
#define module_apr_driver(__apr_driver) \
|
||||
module_driver(__apr_driver, apr_driver_register, \
|
||||
apr_driver_unregister)
|
||||
#define module_gpr_driver(__gpr_driver) module_apr_driver(__gpr_driver)
|
||||
|
||||
int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt);
|
||||
|
||||
gpr_port_t *gpr_alloc_port(gpr_device_t *gdev, struct device *dev,
|
||||
gpr_port_cb cb, void *priv);
|
||||
void gpr_free_port(gpr_port_t *port);
|
||||
int gpr_send_port_pkt(gpr_port_t *port, struct gpr_pkt *pkt);
|
||||
int gpr_send_pkt(gpr_device_t *gdev, struct gpr_pkt *pkt);
|
||||
|
||||
#endif /* __QCOM_APR_H_ */
|
||||
|
34
include/sound/cs35l41.h
Normal file
34
include/sound/cs35l41.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* linux/sound/cs35l41.h -- Platform data for CS35L41
|
||||
*
|
||||
* Copyright (c) 2017-2021 Cirrus Logic Inc.
|
||||
*
|
||||
* Author: David Rhodes <david.rhodes@cirrus.com>
|
||||
*/
|
||||
|
||||
#ifndef __CS35L41_H
|
||||
#define __CS35L41_H
|
||||
|
||||
enum cs35l41_clk_ids {
|
||||
CS35L41_CLKID_SCLK = 0,
|
||||
CS35L41_CLKID_LRCLK = 1,
|
||||
CS35L41_CLKID_MCLK = 4,
|
||||
};
|
||||
|
||||
struct cs35l41_irq_cfg {
|
||||
bool irq_pol_inv;
|
||||
bool irq_out_en;
|
||||
int irq_src_sel;
|
||||
};
|
||||
|
||||
struct cs35l41_platform_data {
|
||||
int bst_ind;
|
||||
int bst_ipk;
|
||||
int bst_cap;
|
||||
int dout_hiz;
|
||||
struct cs35l41_irq_cfg irq_config1;
|
||||
struct cs35l41_irq_cfg irq_config2;
|
||||
};
|
||||
|
||||
#endif /* __CS35L41_H */
|
@ -9,6 +9,27 @@
|
||||
|
||||
#include <sound/simple_card_utils.h>
|
||||
|
||||
typedef int (*GRAPH2_CUSTOM)(struct asoc_simple_priv *priv,
|
||||
struct device_node *lnk,
|
||||
struct link_info *li);
|
||||
|
||||
struct graph2_custom_hooks {
|
||||
int (*hook_pre)(struct asoc_simple_priv *priv);
|
||||
int (*hook_post)(struct asoc_simple_priv *priv);
|
||||
GRAPH2_CUSTOM custom_normal;
|
||||
GRAPH2_CUSTOM custom_dpcm;
|
||||
GRAPH2_CUSTOM custom_c2c;
|
||||
};
|
||||
|
||||
int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev);
|
||||
int audio_graph2_parse_of(struct asoc_simple_priv *priv, struct device *dev,
|
||||
struct graph2_custom_hooks *hooks);
|
||||
|
||||
int audio_graph2_link_normal(struct asoc_simple_priv *priv,
|
||||
struct device_node *lnk, struct link_info *li);
|
||||
int audio_graph2_link_dpcm(struct asoc_simple_priv *priv,
|
||||
struct device_node *lnk, struct link_info *li);
|
||||
int audio_graph2_link_c2c(struct asoc_simple_priv *priv,
|
||||
struct device_node *lnk, struct link_info *li);
|
||||
|
||||
#endif /* __GRAPH_CARD_H */
|
||||
|
@ -88,6 +88,8 @@ struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus,
|
||||
struct snd_pcm_substream *substream,
|
||||
int type);
|
||||
void snd_hdac_ext_stream_release(struct hdac_ext_stream *azx_dev, int type);
|
||||
void snd_hdac_ext_stream_decouple_locked(struct hdac_bus *bus,
|
||||
struct hdac_ext_stream *azx_dev, bool decouple);
|
||||
void snd_hdac_ext_stream_decouple(struct hdac_bus *bus,
|
||||
struct hdac_ext_stream *azx_dev, bool decouple);
|
||||
void snd_hdac_ext_stop_streams(struct hdac_bus *bus);
|
||||
|
@ -9,16 +9,20 @@
|
||||
#ifndef __SOUND_MEMALLOC_H
|
||||
#define __SOUND_MEMALLOC_H
|
||||
|
||||
#include <linux/dma-direction.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
struct device;
|
||||
struct vm_area_struct;
|
||||
struct sg_table;
|
||||
|
||||
/*
|
||||
* buffer device info
|
||||
*/
|
||||
struct snd_dma_device {
|
||||
int type; /* SNDRV_DMA_TYPE_XXX */
|
||||
enum dma_data_direction dir; /* DMA direction */
|
||||
bool need_sync; /* explicit sync needed? */
|
||||
struct device *dev; /* generic device */
|
||||
};
|
||||
|
||||
@ -32,19 +36,21 @@ struct snd_dma_device {
|
||||
#define SNDRV_DMA_TYPE_CONTINUOUS 1 /* continuous no-DMA memory */
|
||||
#define SNDRV_DMA_TYPE_DEV 2 /* generic device continuous */
|
||||
#define SNDRV_DMA_TYPE_DEV_WC 5 /* continuous write-combined */
|
||||
#ifdef CONFIG_SND_DMA_SGBUF
|
||||
#define SNDRV_DMA_TYPE_DEV_SG 3 /* generic device SG-buffer */
|
||||
#define SNDRV_DMA_TYPE_DEV_WC_SG 6 /* SG write-combined */
|
||||
#else
|
||||
#define SNDRV_DMA_TYPE_DEV_SG SNDRV_DMA_TYPE_DEV /* no SG-buf support */
|
||||
#define SNDRV_DMA_TYPE_DEV_WC_SG SNDRV_DMA_TYPE_DEV_WC
|
||||
#endif
|
||||
#ifdef CONFIG_GENERIC_ALLOCATOR
|
||||
#define SNDRV_DMA_TYPE_DEV_IRAM 4 /* generic device iram-buffer */
|
||||
#else
|
||||
#define SNDRV_DMA_TYPE_DEV_IRAM SNDRV_DMA_TYPE_DEV
|
||||
#endif
|
||||
#define SNDRV_DMA_TYPE_VMALLOC 7 /* vmalloc'ed buffer */
|
||||
#define SNDRV_DMA_TYPE_NONCONTIG 8 /* non-coherent SG buffer */
|
||||
#define SNDRV_DMA_TYPE_NONCOHERENT 9 /* non-coherent buffer */
|
||||
#ifdef CONFIG_SND_DMA_SGBUF
|
||||
#define SNDRV_DMA_TYPE_DEV_SG SNDRV_DMA_TYPE_NONCONTIG
|
||||
#define SNDRV_DMA_TYPE_DEV_WC_SG 6 /* SG write-combined */
|
||||
#else
|
||||
#define SNDRV_DMA_TYPE_DEV_SG SNDRV_DMA_TYPE_DEV /* no SG-buf support */
|
||||
#define SNDRV_DMA_TYPE_DEV_WC_SG SNDRV_DMA_TYPE_DEV_WC
|
||||
#endif
|
||||
|
||||
/*
|
||||
* info for buffer allocation
|
||||
@ -66,22 +72,52 @@ static inline unsigned int snd_sgbuf_aligned_pages(size_t size)
|
||||
}
|
||||
|
||||
/* allocate/release a buffer */
|
||||
int snd_dma_alloc_pages(int type, struct device *dev, size_t size,
|
||||
struct snd_dma_buffer *dmab);
|
||||
int snd_dma_alloc_dir_pages(int type, struct device *dev,
|
||||
enum dma_data_direction dir, size_t size,
|
||||
struct snd_dma_buffer *dmab);
|
||||
|
||||
static inline int snd_dma_alloc_pages(int type, struct device *dev,
|
||||
size_t size, struct snd_dma_buffer *dmab)
|
||||
{
|
||||
return snd_dma_alloc_dir_pages(type, dev, DMA_BIDIRECTIONAL, size, dmab);
|
||||
}
|
||||
|
||||
int snd_dma_alloc_pages_fallback(int type, struct device *dev, size_t size,
|
||||
struct snd_dma_buffer *dmab);
|
||||
void snd_dma_free_pages(struct snd_dma_buffer *dmab);
|
||||
int snd_dma_buffer_mmap(struct snd_dma_buffer *dmab,
|
||||
struct vm_area_struct *area);
|
||||
|
||||
enum snd_dma_sync_mode { SNDRV_DMA_SYNC_CPU, SNDRV_DMA_SYNC_DEVICE };
|
||||
#ifdef CONFIG_HAS_DMA
|
||||
void snd_dma_buffer_sync(struct snd_dma_buffer *dmab,
|
||||
enum snd_dma_sync_mode mode);
|
||||
#else
|
||||
static inline void snd_dma_buffer_sync(struct snd_dma_buffer *dmab,
|
||||
enum snd_dma_sync_mode mode) {}
|
||||
#endif
|
||||
|
||||
dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab, size_t offset);
|
||||
struct page *snd_sgbuf_get_page(struct snd_dma_buffer *dmab, size_t offset);
|
||||
unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
|
||||
unsigned int ofs, unsigned int size);
|
||||
|
||||
/* device-managed memory allocator */
|
||||
struct snd_dma_buffer *snd_devm_alloc_pages(struct device *dev, int type,
|
||||
size_t size);
|
||||
struct snd_dma_buffer *snd_devm_alloc_dir_pages(struct device *dev, int type,
|
||||
enum dma_data_direction dir,
|
||||
size_t size);
|
||||
|
||||
static inline struct snd_dma_buffer *
|
||||
snd_devm_alloc_pages(struct device *dev, int type, size_t size)
|
||||
{
|
||||
return snd_devm_alloc_dir_pages(dev, type, DMA_BIDIRECTIONAL, size);
|
||||
}
|
||||
|
||||
static inline struct sg_table *
|
||||
snd_dma_noncontig_sg_table(struct snd_dma_buffer *dmab)
|
||||
{
|
||||
return dmab->private_data;
|
||||
}
|
||||
|
||||
#endif /* __SOUND_MEMALLOC_H */
|
||||
|
||||
|
48
include/sound/rt5682s.h
Normal file
48
include/sound/rt5682s.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* linux/sound/rt5682s.h -- Platform data for RT5682I-VS
|
||||
*
|
||||
* Copyright 2021 Realtek Microelectronics
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_SND_RT5682S_H
|
||||
#define __LINUX_SND_RT5682S_H
|
||||
|
||||
enum rt5682s_dmic1_data_pin {
|
||||
RT5682S_DMIC1_DATA_NULL,
|
||||
RT5682S_DMIC1_DATA_GPIO2,
|
||||
RT5682S_DMIC1_DATA_GPIO5,
|
||||
};
|
||||
|
||||
enum rt5682s_dmic1_clk_pin {
|
||||
RT5682S_DMIC1_CLK_NULL,
|
||||
RT5682S_DMIC1_CLK_GPIO1,
|
||||
RT5682S_DMIC1_CLK_GPIO3,
|
||||
};
|
||||
|
||||
enum rt5682s_jd_src {
|
||||
RT5682S_JD_NULL,
|
||||
RT5682S_JD1,
|
||||
};
|
||||
|
||||
enum rt5682s_dai_clks {
|
||||
RT5682S_DAI_WCLK_IDX,
|
||||
RT5682S_DAI_BCLK_IDX,
|
||||
RT5682S_DAI_NUM_CLKS,
|
||||
};
|
||||
|
||||
struct rt5682s_platform_data {
|
||||
|
||||
int ldo1_en; /* GPIO for LDO1_EN */
|
||||
|
||||
enum rt5682s_dmic1_data_pin dmic1_data_pin;
|
||||
enum rt5682s_dmic1_clk_pin dmic1_clk_pin;
|
||||
enum rt5682s_jd_src jd_src;
|
||||
unsigned int dmic_clk_rate;
|
||||
unsigned int dmic_delay;
|
||||
bool dmic_clk_driving_high;
|
||||
|
||||
const char *dai_clk_names[RT5682S_DAI_NUM_CLKS];
|
||||
};
|
||||
|
||||
#endif
|
@ -42,6 +42,7 @@ struct prop_nums {
|
||||
int cpus;
|
||||
int codecs;
|
||||
int platforms;
|
||||
int c2c;
|
||||
};
|
||||
|
||||
struct asoc_simple_priv {
|
||||
@ -54,6 +55,7 @@ struct asoc_simple_priv {
|
||||
struct snd_soc_dai_link_component *platforms;
|
||||
struct asoc_simple_data adata;
|
||||
struct snd_soc_codec_conf *codec_conf;
|
||||
struct snd_soc_pcm_stream *c2c_conf;
|
||||
struct prop_nums num;
|
||||
unsigned int mclk_fs;
|
||||
} *dai_props;
|
||||
@ -64,6 +66,7 @@ struct asoc_simple_priv {
|
||||
struct snd_soc_dai_link_component *dlcs;
|
||||
struct snd_soc_dai_link_component dummy;
|
||||
struct snd_soc_codec_conf *codec_conf;
|
||||
struct snd_soc_pcm_stream *c2c_conf;
|
||||
struct gpio_desc *pa_gpio;
|
||||
const struct snd_soc_ops *ops;
|
||||
unsigned int dpcm_selectable:1;
|
||||
@ -115,7 +118,7 @@ struct asoc_simple_priv {
|
||||
((codec) = simple_props_to_dai_codec(props, i)); \
|
||||
(i)++)
|
||||
|
||||
#define SNDRV_MAX_LINKS 128
|
||||
#define SNDRV_MAX_LINKS 512
|
||||
|
||||
struct link_info {
|
||||
int link; /* number of link */
|
||||
@ -180,6 +183,7 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
|
||||
int asoc_simple_remove(struct platform_device *pdev);
|
||||
|
||||
int asoc_graph_card_probe(struct snd_soc_card *card);
|
||||
int asoc_graph_is_ports0(struct device_node *port);
|
||||
|
||||
#ifdef DEBUG
|
||||
static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
|
||||
|
@ -129,6 +129,8 @@ struct snd_soc_acpi_link_adr {
|
||||
* all firmware/topology related fields.
|
||||
*
|
||||
* @id: ACPI ID (usually the codec's) used to find a matching machine driver.
|
||||
* @comp_ids: list of compatible audio codecs using the same machine driver,
|
||||
* firmware and topology
|
||||
* @link_mask: describes required board layout, e.g. for SoundWire.
|
||||
* @links: array of link _ADR descriptors, null terminated.
|
||||
* @drv_name: machine driver name
|
||||
@ -146,6 +148,7 @@ struct snd_soc_acpi_link_adr {
|
||||
/* Descriptor for SST ASoC machine driver */
|
||||
struct snd_soc_acpi_mach {
|
||||
const u8 id[ACPI_ID_LEN];
|
||||
const struct snd_soc_acpi_codecs *comp_ids;
|
||||
const u32 link_mask;
|
||||
const struct snd_soc_acpi_link_adr *links;
|
||||
const char *drv_name;
|
||||
|
@ -220,17 +220,15 @@ struct snd_soc_component {
|
||||
int (*init)(struct snd_soc_component *component);
|
||||
|
||||
/* function mark */
|
||||
struct snd_pcm_substream *mark_module;
|
||||
void *mark_module;
|
||||
struct snd_pcm_substream *mark_open;
|
||||
struct snd_pcm_substream *mark_hw_params;
|
||||
struct snd_pcm_substream *mark_trigger;
|
||||
struct snd_compr_stream *mark_compr_open;
|
||||
void *mark_pm;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs_root;
|
||||
const char *debugfs_prefix;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define for_each_component_dais(component, dai)\
|
||||
@ -335,6 +333,11 @@ static inline int snd_soc_component_cache_sync(
|
||||
return regcache_sync(component->regmap);
|
||||
}
|
||||
|
||||
static inline int snd_soc_component_is_codec(struct snd_soc_component *component)
|
||||
{
|
||||
return component->driver->non_legacy_dai_naming;
|
||||
}
|
||||
|
||||
void snd_soc_component_set_aux(struct snd_soc_component *component,
|
||||
struct snd_soc_aux_dev *aux);
|
||||
int snd_soc_component_init(struct snd_soc_component *component);
|
||||
@ -391,15 +394,13 @@ void snd_soc_component_exit_regmap(struct snd_soc_component *component);
|
||||
#define snd_soc_component_module_get_when_open(component, substream) \
|
||||
snd_soc_component_module_get(component, substream, 1)
|
||||
int snd_soc_component_module_get(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream,
|
||||
int upon_open);
|
||||
void *mark, int upon_open);
|
||||
#define snd_soc_component_module_put_when_remove(component) \
|
||||
snd_soc_component_module_put(component, NULL, 0, 0)
|
||||
#define snd_soc_component_module_put_when_close(component, substream, rollback) \
|
||||
snd_soc_component_module_put(component, substream, 1, rollback)
|
||||
void snd_soc_component_module_put(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream,
|
||||
int upon_open, int rollback);
|
||||
void *mark, int upon_open, int rollback);
|
||||
|
||||
static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c,
|
||||
void *data)
|
||||
@ -455,8 +456,10 @@ int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
|
||||
int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
|
||||
const struct of_phandle_args *args,
|
||||
const char **dai_name);
|
||||
int snd_soc_component_compr_open(struct snd_compr_stream *cstream);
|
||||
void snd_soc_component_compr_free(struct snd_compr_stream *cstream,
|
||||
int snd_soc_component_compr_open(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *cstream);
|
||||
void snd_soc_component_compr_free(struct snd_soc_component *component,
|
||||
struct snd_compr_stream *cstream,
|
||||
int rollback);
|
||||
int snd_soc_component_compr_trigger(struct snd_compr_stream *cstream, int cmd);
|
||||
int snd_soc_component_compr_set_params(struct snd_compr_stream *cstream,
|
||||
|
@ -159,6 +159,7 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd);
|
||||
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);
|
||||
|
||||
#define dpcm_be_dai_startup_rollback(fe, stream, last) \
|
||||
dpcm_be_dai_stop(fe, stream, 0, last)
|
||||
|
@ -151,7 +151,7 @@ struct snd_soc_tplg_ops {
|
||||
struct snd_soc_tplg_hdr *);
|
||||
|
||||
/* completion - called at completion of firmware loading */
|
||||
void (*complete)(struct snd_soc_component *);
|
||||
int (*complete)(struct snd_soc_component *comp);
|
||||
|
||||
/* manifest - optional to inform component of manifest */
|
||||
int (*manifest)(struct snd_soc_component *, int index,
|
||||
@ -188,8 +188,7 @@ int snd_soc_tplg_widget_bind_event(struct snd_soc_dapm_widget *w,
|
||||
|
||||
#else
|
||||
|
||||
static inline int snd_soc_tplg_component_remove(struct snd_soc_component *comp,
|
||||
u32 index)
|
||||
static inline int snd_soc_tplg_component_remove(struct snd_soc_component *comp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -74,11 +74,6 @@ struct sof_dev_desc {
|
||||
int resindex_pcicfg_base;
|
||||
int resindex_imr_base;
|
||||
int irqindex_host_ipc;
|
||||
int resindex_dma_base;
|
||||
|
||||
/* DMA only valid when resindex_dma_base != -1*/
|
||||
int dma_engine;
|
||||
int dma_size;
|
||||
|
||||
/* IPC timeouts in ms */
|
||||
int ipc_timeout;
|
||||
|
@ -48,6 +48,10 @@
|
||||
#define SOF_DAI_INTEL_SSP_CLKCTRL_FS_KA BIT(4)
|
||||
/* bclk idle */
|
||||
#define SOF_DAI_INTEL_SSP_CLKCTRL_BCLK_IDLE_HIGH BIT(5)
|
||||
/* mclk early start */
|
||||
#define SOF_DAI_INTEL_SSP_CLKCTRL_MCLK_ES BIT(6)
|
||||
/* bclk early start */
|
||||
#define SOF_DAI_INTEL_SSP_CLKCTRL_BCLK_ES BIT(7)
|
||||
|
||||
/* DMIC max. four controllers for eight microphone channels */
|
||||
#define SOF_DAI_INTEL_DMIC_NUM_CTRL 4
|
||||
|
@ -50,6 +50,13 @@
|
||||
#define SOF_DAI_FMT_INV_MASK 0x0f00
|
||||
#define SOF_DAI_FMT_CLOCK_PROVIDER_MASK 0xf000
|
||||
|
||||
/* DAI_CONFIG flags */
|
||||
#define SOF_DAI_CONFIG_FLAGS_MASK 0x3
|
||||
#define SOF_DAI_CONFIG_FLAGS_NONE (0 << 0) /**< DAI_CONFIG sent without stage information */
|
||||
#define SOF_DAI_CONFIG_FLAGS_HW_PARAMS (1 << 0) /**< DAI_CONFIG sent during hw_params stage */
|
||||
#define SOF_DAI_CONFIG_FLAGS_HW_FREE (2 << 0) /**< DAI_CONFIG sent during hw_free stage */
|
||||
#define SOF_DAI_CONFIG_FLAGS_RFU (3 << 0) /**< not used, reserved for future use */
|
||||
|
||||
/** \brief Types of DAI */
|
||||
enum sof_ipc_dai_type {
|
||||
SOF_DAI_INTEL_NONE = 0, /**< None */
|
||||
@ -69,7 +76,8 @@ struct sof_ipc_dai_config {
|
||||
|
||||
/* physical protocol and clocking */
|
||||
uint16_t format; /**< SOF_DAI_FMT_ */
|
||||
uint16_t reserved16; /**< alignment */
|
||||
uint8_t group_id; /**< group ID, 0 means no group (ABI 3.17) */
|
||||
uint8_t flags; /**< SOF_DAI_CONFIG_FLAGS_ (ABI 3.19) */
|
||||
|
||||
/* reserved for future use */
|
||||
uint32_t reserved[8];
|
||||
|
@ -1002,7 +1002,7 @@ typedef int __bitwise snd_ctl_elem_iface_t;
|
||||
#define SNDRV_CTL_ELEM_ACCESS_WRITE (1<<1)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE)
|
||||
#define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1<<2) /* control value may be changed without a notification */
|
||||
// (1 << 3) is unused.
|
||||
/* (1 << 3) is unused. */
|
||||
#define SNDRV_CTL_ELEM_ACCESS_TLV_READ (1<<4) /* TLV read is possible */
|
||||
#define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE (1<<5) /* TLV write is possible */
|
||||
#define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE (SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
|
||||
|
@ -13,6 +13,7 @@
|
||||
#define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE 0x746e736c
|
||||
#define SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION 0x64776479
|
||||
#define SNDRV_FIREWIRE_EVENT_TASCAM_CONTROL 0x7473636d
|
||||
#define SNDRV_FIREWIRE_EVENT_MOTU_REGISTER_DSP_CHANGE 0x4d545244
|
||||
|
||||
struct snd_firewire_event_common {
|
||||
unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */
|
||||
@ -65,6 +66,12 @@ struct snd_firewire_event_tascam_control {
|
||||
struct snd_firewire_tascam_change changes[0];
|
||||
};
|
||||
|
||||
struct snd_firewire_event_motu_register_dsp_change {
|
||||
unsigned int type;
|
||||
__u32 count; /* The number of changes. */
|
||||
__u32 changes[]; /* Encoded event for change of register DSP. */
|
||||
};
|
||||
|
||||
union snd_firewire_event {
|
||||
struct snd_firewire_event_common common;
|
||||
struct snd_firewire_event_lock_status lock_status;
|
||||
@ -73,6 +80,7 @@ union snd_firewire_event {
|
||||
struct snd_firewire_event_digi00x_message digi00x_message;
|
||||
struct snd_firewire_event_tascam_control tascam_control;
|
||||
struct snd_firewire_event_motu_notification motu_notification;
|
||||
struct snd_firewire_event_motu_register_dsp_change motu_register_dsp_change;
|
||||
};
|
||||
|
||||
|
||||
@ -80,6 +88,9 @@ union snd_firewire_event {
|
||||
#define SNDRV_FIREWIRE_IOCTL_LOCK _IO('H', 0xf9)
|
||||
#define SNDRV_FIREWIRE_IOCTL_UNLOCK _IO('H', 0xfa)
|
||||
#define SNDRV_FIREWIRE_IOCTL_TASCAM_STATE _IOR('H', 0xfb, struct snd_firewire_tascam_state)
|
||||
#define SNDRV_FIREWIRE_IOCTL_MOTU_REGISTER_DSP_METER _IOR('H', 0xfc, struct snd_firewire_motu_register_dsp_meter)
|
||||
#define SNDRV_FIREWIRE_IOCTL_MOTU_COMMAND_DSP_METER _IOR('H', 0xfd, struct snd_firewire_motu_command_dsp_meter)
|
||||
#define SNDRV_FIREWIRE_IOCTL_MOTU_REGISTER_DSP_PARAMETER _IOR('H', 0xfe, struct snd_firewire_motu_register_dsp_parameter)
|
||||
|
||||
#define SNDRV_FIREWIRE_TYPE_DICE 1
|
||||
#define SNDRV_FIREWIRE_TYPE_FIREWORKS 2
|
||||
@ -108,4 +119,143 @@ struct snd_firewire_tascam_state {
|
||||
__be32 data[SNDRV_FIREWIRE_TASCAM_STATE_COUNT];
|
||||
};
|
||||
|
||||
/*
|
||||
* In below MOTU models, software is allowed to control their DSP by accessing to registers.
|
||||
* - 828mk2
|
||||
* - 896hd
|
||||
* - Traveler
|
||||
* - 8 pre
|
||||
* - Ultralite
|
||||
* - 4 pre
|
||||
* - Audio Express
|
||||
*
|
||||
* On the other hand, the status of DSP is split into specific messages included in the sequence of
|
||||
* isochronous packet. ALSA firewire-motu driver gathers the messages and allow userspace applications
|
||||
* to read it via ioctl. In 828mk2, 896hd, and Traveler, hardware meter for all of physical inputs
|
||||
* are put into the message, while one pair of physical outputs is selected. The selection is done by
|
||||
* LSB one byte in asynchronous write quadlet transaction to 0x'ffff'f000'0b2c.
|
||||
*
|
||||
* I note that V3HD/V4HD uses asynchronous transaction for the purpose. The destination address is
|
||||
* registered to 0x'ffff'f000'0b38 and '0b3c by asynchronous write quadlet request. The size of
|
||||
* message differs between 23 and 51 quadlets. For the case, the number of mixer bus can be extended
|
||||
* up to 12.
|
||||
*/
|
||||
|
||||
#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_INPUT_COUNT 24
|
||||
#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_OUTPUT_COUNT 24
|
||||
#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_COUNT \
|
||||
(SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_INPUT_COUNT + SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_OUTPUT_COUNT)
|
||||
|
||||
/**
|
||||
* struct snd_firewire_motu_register_dsp_meter - the container for meter information in DSP
|
||||
* controlled by register access
|
||||
* @data: Signal level meters. The mapping between position and input/output channel is
|
||||
* model-dependent.
|
||||
*
|
||||
* The structure expresses the part of DSP status for hardware meter. The u8 storage includes linear
|
||||
* value for audio signal level between 0x00 and 0x7f.
|
||||
*/
|
||||
struct snd_firewire_motu_register_dsp_meter {
|
||||
__u8 data[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_METER_COUNT];
|
||||
};
|
||||
|
||||
#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_COUNT 4
|
||||
#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT 20
|
||||
#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_INPUT_COUNT 10
|
||||
#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_ALIGNED_INPUT_COUNT (SNDRV_FIREWIRE_MOTU_REGISTER_DSP_INPUT_COUNT + 2)
|
||||
|
||||
/**
|
||||
* snd_firewire_motu_register_dsp_parameter - the container for parameters of DSP controlled
|
||||
* by register access.
|
||||
* @mixer.source.gain: The gain of source to mixer.
|
||||
* @mixer.source.pan: The L/R balance of source to mixer.
|
||||
* @mixer.source.flag: The flag of source to mixer, including mute, solo.
|
||||
* @mixer.source.paired_balance: The L/R balance of paired source to mixer, only for 4 pre and
|
||||
* Audio Express.
|
||||
* @mixer.source.paired_width: The width of paired source to mixer, only for 4 pre and
|
||||
* Audio Express.
|
||||
* @mixer.output.paired_volume: The volume of paired output from mixer.
|
||||
* @mixer.output.paired_flag: The flag of paired output from mixer.
|
||||
* @output.main_paired_volume: The volume of paired main output.
|
||||
* @output.hp_paired_volume: The volume of paired hp output.
|
||||
* @output.hp_paired_assignment: The source assigned to paired hp output.
|
||||
* @output.reserved: Padding for 32 bit alignment for future extension.
|
||||
* @line_input.boost_flag: The flags of boost for line inputs, only for 828mk2 and Traveler.
|
||||
* @line_input.nominal_level_flag: The flags of nominal level for line inputs, only for 828mk2 and
|
||||
* Traveler.
|
||||
* @line_input.reserved: Padding for 32 bit alignment for future extension.
|
||||
* @input.gain_and_invert: The value including gain and invert for input, only for Ultralite, 4 pre
|
||||
* and Audio Express.
|
||||
* @input.flag: The flag of input; e.g. jack detection, phantom power, and pad, only for Ultralite,
|
||||
* 4 pre and Audio express.
|
||||
* @reserved: Padding so that the size of structure is kept to 512 byte, but for future extension.
|
||||
*
|
||||
* The structure expresses the set of parameters for DSP controlled by register access.
|
||||
*/
|
||||
struct snd_firewire_motu_register_dsp_parameter {
|
||||
struct {
|
||||
struct {
|
||||
__u8 gain[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT];
|
||||
__u8 pan[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT];
|
||||
__u8 flag[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT];
|
||||
__u8 paired_balance[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT];
|
||||
__u8 paired_width[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_SRC_COUNT];
|
||||
} source[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_COUNT];
|
||||
struct {
|
||||
__u8 paired_volume[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_COUNT];
|
||||
__u8 paired_flag[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_MIXER_COUNT];
|
||||
} output;
|
||||
} mixer;
|
||||
struct {
|
||||
__u8 main_paired_volume;
|
||||
__u8 hp_paired_volume;
|
||||
__u8 hp_paired_assignment;
|
||||
__u8 reserved[5];
|
||||
} output;
|
||||
struct {
|
||||
__u8 boost_flag;
|
||||
__u8 nominal_level_flag;
|
||||
__u8 reserved[6];
|
||||
} line_input;
|
||||
struct {
|
||||
__u8 gain_and_invert[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_ALIGNED_INPUT_COUNT];
|
||||
__u8 flag[SNDRV_FIREWIRE_MOTU_REGISTER_DSP_ALIGNED_INPUT_COUNT];
|
||||
} input;
|
||||
__u8 reserved[64];
|
||||
};
|
||||
|
||||
/*
|
||||
* In below MOTU models, software is allowed to control their DSP by command in frame of
|
||||
* asynchronous transaction to 0x'ffff'0001'0000:
|
||||
*
|
||||
* - 828 mk3 (FireWire only and Hybrid)
|
||||
* - 896 mk3 (FireWire only and Hybrid)
|
||||
* - Ultralite mk3 (FireWire only and Hybrid)
|
||||
* - Traveler mk3
|
||||
* - Track 16
|
||||
*
|
||||
* On the other hand, the states of hardware meter is split into specific messages included in the
|
||||
* sequence of isochronous packet. ALSA firewire-motu driver gathers the message and allow userspace
|
||||
* application to read it via ioctl.
|
||||
*/
|
||||
|
||||
#define SNDRV_FIREWIRE_MOTU_COMMAND_DSP_METER_COUNT 400
|
||||
|
||||
/**
|
||||
* struct snd_firewire_motu_command_dsp_meter - the container for meter information in DSP
|
||||
* controlled by command
|
||||
* @data: Signal level meters. The mapping between position and signal channel is model-dependent.
|
||||
*
|
||||
* The structure expresses the part of DSP status for hardware meter. The 32 bit storage is
|
||||
* estimated to include IEEE 764 32 bit single precision floating point (binary32) value. It is
|
||||
* expected to be linear value (not logarithm) for audio signal level between 0.0 and +1.0.
|
||||
*/
|
||||
struct snd_firewire_motu_command_dsp_meter {
|
||||
#ifdef __KERNEL__
|
||||
__u32 data[SNDRV_FIREWIRE_MOTU_COMMAND_DSP_METER_COUNT];
|
||||
#else
|
||||
float data[SNDRV_FIREWIRE_MOTU_COMMAND_DSP_METER_COUNT];
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* _UAPI_SOUND_FIREWIRE_H_INCLUDED */
|
||||
|
208
include/uapi/sound/snd_ar_tokens.h
Normal file
208
include/uapi/sound/snd_ar_tokens.h
Normal file
@ -0,0 +1,208 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
|
||||
#ifndef __SND_AR_TOKENS_H__
|
||||
#define __SND_AR_TOKENS_H__
|
||||
|
||||
#define APM_SUB_GRAPH_PERF_MODE_LOW_POWER 0x1
|
||||
#define APM_SUB_GRAPH_PERF_MODE_LOW_LATENCY 0x2
|
||||
|
||||
#define APM_SUB_GRAPH_DIRECTION_TX 0x1
|
||||
#define APM_SUB_GRAPH_DIRECTION_RX 0x2
|
||||
|
||||
/** Scenario ID Audio Playback */
|
||||
#define APM_SUB_GRAPH_SID_AUDIO_PLAYBACK 0x1
|
||||
/* Scenario ID Audio Record */
|
||||
#define APM_SUB_GRAPH_SID_AUDIO_RECORD 0x2
|
||||
/* Scenario ID Voice call. */
|
||||
#define APM_SUB_GRAPH_SID_VOICE_CALL 0x3
|
||||
|
||||
/* container capability ID Pre/Post Processing (PP) */
|
||||
#define APM_CONTAINER_CAP_ID_PP 0x1
|
||||
/* container capability ID Compression/Decompression (CD) */
|
||||
#define APM_CONTAINER_CAP_ID_CD 0x2
|
||||
/* container capability ID End Point(EP) */
|
||||
#define APM_CONTAINER_CAP_ID_EP 0x3
|
||||
/* container capability ID Offload (OLC) */
|
||||
#define APM_CONTAINER_CAP_ID_OLC 0x4
|
||||
|
||||
/* container graph position Stream */
|
||||
#define APM_CONT_GRAPH_POS_STREAM 0x1
|
||||
/* container graph position Per Stream Per Device*/
|
||||
#define APM_CONT_GRAPH_POS_PER_STR_PER_DEV 0x2
|
||||
/* container graph position Stream-Device */
|
||||
#define APM_CONT_GRAPH_POS_STR_DEV 0x3
|
||||
/* container graph position Global Device */
|
||||
#define APM_CONT_GRAPH_POS_GLOBAL_DEV 0x4
|
||||
|
||||
#define APM_PROC_DOMAIN_ID_MDSP 0x1
|
||||
#define APM_PROC_DOMAIN_ID_ADSP 0x2
|
||||
#define APM_PROC_DOMAIN_ID_SDSP 0x4
|
||||
#define APM_PROC_DOMAIN_ID_CDSP 0x5
|
||||
|
||||
#define PCM_INTERLEAVED 1
|
||||
#define PCM_DEINTERLEAVED_PACKED 2
|
||||
#define PCM_DEINTERLEAVED_UNPACKED 3
|
||||
#define AR_I2S_WS_SRC_EXTERNAL 0
|
||||
#define AR_I2S_WS_SRC_INTERNAL 1
|
||||
|
||||
enum ar_event_types {
|
||||
AR_EVENT_NONE = 0,
|
||||
AR_PGA_DAPM_EVENT
|
||||
};
|
||||
|
||||
/*
|
||||
* Kcontrol IDs
|
||||
*/
|
||||
#define SND_SOC_AR_TPLG_FE_BE_GRAPH_CTL_MIX 256
|
||||
#define SND_SOC_AR_TPLG_VOL_CTL 257
|
||||
|
||||
/**
|
||||
* %AR_TKN_U32_SUB_GRAPH_INSTANCE_ID: Sub Graph Instance Id
|
||||
*
|
||||
* %AR_TKN_U32_SUB_GRAPH_PERF_MODE: Performance mode of subgraph
|
||||
* APM_SUB_GRAPH_PERF_MODE_LOW_POWER = 1,
|
||||
* APM_SUB_GRAPH_PERF_MODE_LOW_LATENCY = 2
|
||||
*
|
||||
* %AR_TKN_U32_SUB_GRAPH_DIRECTION: Direction of subgraph
|
||||
* APM_SUB_GRAPH_DIRECTION_TX = 1,
|
||||
* APM_SUB_GRAPH_DIRECTION_RX = 2
|
||||
*
|
||||
* %AR_TKN_U32_SUB_GRAPH_SCENARIO_ID: Scenario ID for subgraph
|
||||
* APM_SUB_GRAPH_SID_AUDIO_PLAYBACK = 1,
|
||||
* APM_SUB_GRAPH_SID_AUDIO_RECORD = 2,
|
||||
* APM_SUB_GRAPH_SID_VOICE_CALL = 3
|
||||
*
|
||||
* %AR_TKN_U32_CONTAINER_INSTANCE_ID: Container Instance ID
|
||||
*
|
||||
* %AR_TKN_U32_CONTAINER_CAPABILITY_ID: Container capability ID
|
||||
* APM_CONTAINER_CAP_ID_PP = 1,
|
||||
* APM_CONTAINER_CAP_ID_CD = 2,
|
||||
* APM_CONTAINER_CAP_ID_EP = 3,
|
||||
* APM_CONTAINER_CAP_ID_OLC = 4
|
||||
*
|
||||
* %AR_TKN_U32_CONTAINER_STACK_SIZE: Stack size in the container.
|
||||
*
|
||||
* %AR_TKN_U32_CONTAINER_GRAPH_POS: Graph Position
|
||||
* APM_CONT_GRAPH_POS_STREAM = 1,
|
||||
* APM_CONT_GRAPH_POS_PER_STR_PER_DEV = 2,
|
||||
* APM_CONT_GRAPH_POS_STR_DEV = 3,
|
||||
* APM_CONT_GRAPH_POS_GLOBAL_DEV = 4
|
||||
*
|
||||
* %AR_TKN_U32_CONTAINER_PROC_DOMAIN: Processor domain of container
|
||||
* APM_PROC_DOMAIN_ID_MDSP = 1,
|
||||
* APM_PROC_DOMAIN_ID_ADSP = 2,
|
||||
* APM_PROC_DOMAIN_ID_SDSP = 4,
|
||||
* APM_PROC_DOMAIN_ID_CDSP = 5
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_ID: Module ID
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_INSTANCE_ID: Module Instance ID.
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_MAX_IP_PORTS: Module maximum input ports
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_MAX_OP_PORTS: Module maximum output ports.
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_IN_PORTS: Number of in ports
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_OUT_PORTS: Number of out ports.
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_SRC_OP_PORT_ID: Source module output port ID
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_DST_IN_PORT_ID: Destination module input port ID
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_HW_IF_IDX: Interface index types for I2S/LPAIF
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_HW_IF_TYPE: Interface type
|
||||
* LPAIF = 0,
|
||||
* LPAIF_RXTX = 1,
|
||||
* LPAIF_WSA = 2,
|
||||
* LPAIF_VA = 3,
|
||||
* LPAIF_AXI = 4
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_FMT_INTERLEAVE: PCM Interleaving
|
||||
* PCM_INTERLEAVED = 1,
|
||||
* PCM_DEINTERLEAVED_PACKED = 2,
|
||||
* PCM_DEINTERLEAVED_UNPACKED = 3
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_FMT_DATA: data format
|
||||
* FIXED POINT = 1,
|
||||
* IEC60958 PACKETIZED = 3,
|
||||
* IEC60958 PACKETIZED NON LINEAR = 8,
|
||||
* COMPR OVER PCM PACKETIZED = 7,
|
||||
* IEC61937 PACKETIZED = 2,
|
||||
* GENERIC COMPRESSED = 5
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_FMT_SAMPLE_RATE: sample rate
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_FMT_BIT_DEPTH: bit depth
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_SD_LINE_IDX: I2S serial data line idx
|
||||
* I2S_SD0 = 1,
|
||||
* I2S_SD1 = 2,
|
||||
* I2S_SD2 = 3,
|
||||
* I2S_SD3 = 4,
|
||||
* I2S_QUAD01 = 5,
|
||||
* I2S_QUAD23 = 6,
|
||||
* I2S_6CHS = 7,
|
||||
* I2S_8CHS = 8
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_WS_SRC: Word Select Source
|
||||
* AR_I2S_WS_SRC_EXTERNAL = 0,
|
||||
* AR_I2S_WS_SRC_INTERNAL = 1,
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_FRAME_SZ_FACTOR: Frame size factor
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_LOG_CODE: Log Module Code
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_LOG_TAP_POINT_ID: logging tap point of this module
|
||||
*
|
||||
* %AR_TKN_U32_MODULE_LOG_MODE: logging mode
|
||||
* LOG_WAIT = 0,
|
||||
* LOG_IMMEDIATELY = 1
|
||||
*
|
||||
* %AR_TKN_DAI_INDEX: dai index
|
||||
*
|
||||
*/
|
||||
|
||||
/* DAI Tokens */
|
||||
#define AR_TKN_DAI_INDEX 1
|
||||
/* SUB GRAPH Tokens */
|
||||
#define AR_TKN_U32_SUB_GRAPH_INSTANCE_ID 2
|
||||
#define AR_TKN_U32_SUB_GRAPH_PERF_MODE 3
|
||||
#define AR_TKN_U32_SUB_GRAPH_DIRECTION 4
|
||||
#define AR_TKN_U32_SUB_GRAPH_SCENARIO_ID 5
|
||||
|
||||
/* Container Tokens */
|
||||
#define AR_TKN_U32_CONTAINER_INSTANCE_ID 100
|
||||
#define AR_TKN_U32_CONTAINER_CAPABILITY_ID 101
|
||||
#define AR_TKN_U32_CONTAINER_STACK_SIZE 102
|
||||
#define AR_TKN_U32_CONTAINER_GRAPH_POS 103
|
||||
#define AR_TKN_U32_CONTAINER_PROC_DOMAIN 104
|
||||
|
||||
/* Module Tokens */
|
||||
#define AR_TKN_U32_MODULE_ID 200
|
||||
#define AR_TKN_U32_MODULE_INSTANCE_ID 201
|
||||
#define AR_TKN_U32_MODULE_MAX_IP_PORTS 202
|
||||
#define AR_TKN_U32_MODULE_MAX_OP_PORTS 203
|
||||
#define AR_TKN_U32_MODULE_IN_PORTS 204
|
||||
#define AR_TKN_U32_MODULE_OUT_PORTS 205
|
||||
#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID 206
|
||||
#define AR_TKN_U32_MODULE_DST_IN_PORT_ID 207
|
||||
#define AR_TKN_U32_MODULE_SRC_INSTANCE_ID 208
|
||||
#define AR_TKN_U32_MODULE_DST_INSTANCE_ID 209
|
||||
|
||||
|
||||
#define AR_TKN_U32_MODULE_HW_IF_IDX 250
|
||||
#define AR_TKN_U32_MODULE_HW_IF_TYPE 251
|
||||
#define AR_TKN_U32_MODULE_FMT_INTERLEAVE 252
|
||||
#define AR_TKN_U32_MODULE_FMT_DATA 253
|
||||
#define AR_TKN_U32_MODULE_FMT_SAMPLE_RATE 254
|
||||
#define AR_TKN_U32_MODULE_FMT_BIT_DEPTH 255
|
||||
#define AR_TKN_U32_MODULE_SD_LINE_IDX 256
|
||||
#define AR_TKN_U32_MODULE_WS_SRC 257
|
||||
#define AR_TKN_U32_MODULE_FRAME_SZ_FACTOR 258
|
||||
#define AR_TKN_U32_MODULE_LOG_CODE 259
|
||||
#define AR_TKN_U32_MODULE_LOG_TAP_POINT_ID 260
|
||||
#define AR_TKN_U32_MODULE_LOG_MODE 261
|
||||
|
||||
#endif /* __SND_AR_TOKENS_H__ */
|
@ -51,6 +51,7 @@
|
||||
#define SOF_TKN_SCHED_CORE 203
|
||||
#define SOF_TKN_SCHED_FRAMES 204
|
||||
#define SOF_TKN_SCHED_TIME_DOMAIN 205
|
||||
#define SOF_TKN_SCHED_DYNAMIC_PIPELINE 206
|
||||
|
||||
/* volume */
|
||||
#define SOF_TKN_VOLUME_RAMP_STEP_TYPE 250
|
||||
|
@ -9,7 +9,9 @@ ifneq ($(CONFIG_SND_PROC_FS),)
|
||||
snd-y += info.o
|
||||
snd-$(CONFIG_SND_OSSEMUL) += info_oss.o
|
||||
endif
|
||||
ifneq ($(CONFIG_M68K),y)
|
||||
snd-$(CONFIG_ISA_DMA_API) += isadma.o
|
||||
endif
|
||||
snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o
|
||||
snd-$(CONFIG_SND_VMASTER) += vmaster.o
|
||||
snd-$(CONFIG_SND_JACK) += ctljack.o jack.o
|
||||
@ -17,7 +19,6 @@ snd-$(CONFIG_SND_JACK) += ctljack.o jack.o
|
||||
snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_misc.o \
|
||||
pcm_memory.o memalloc.o
|
||||
snd-pcm-$(CONFIG_SND_PCM_TIMER) += pcm_timer.o
|
||||
snd-pcm-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o
|
||||
snd-pcm-$(CONFIG_SND_PCM_ELD) += pcm_drm_eld.o
|
||||
snd-pcm-$(CONFIG_SND_PCM_IEC958) += pcm_iec958.o
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/genalloc.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#ifdef CONFIG_X86
|
||||
#include <asm/set_memory.h>
|
||||
@ -39,9 +40,11 @@ static void *__snd_dma_alloc_pages(struct snd_dma_buffer *dmab, size_t size)
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_dma_alloc_pages - allocate the buffer area according to the given type
|
||||
* snd_dma_alloc_dir_pages - allocate the buffer area according to the given
|
||||
* type and direction
|
||||
* @type: the DMA buffer type
|
||||
* @device: the device pointer
|
||||
* @dir: DMA direction
|
||||
* @size: the buffer size to allocate
|
||||
* @dmab: buffer allocation record to store the allocated data
|
||||
*
|
||||
@ -51,8 +54,9 @@ static void *__snd_dma_alloc_pages(struct snd_dma_buffer *dmab, size_t size)
|
||||
* Return: Zero if the buffer with the given size is allocated successfully,
|
||||
* otherwise a negative value on error.
|
||||
*/
|
||||
int snd_dma_alloc_pages(int type, struct device *device, size_t size,
|
||||
struct snd_dma_buffer *dmab)
|
||||
int snd_dma_alloc_dir_pages(int type, struct device *device,
|
||||
enum dma_data_direction dir, size_t size,
|
||||
struct snd_dma_buffer *dmab)
|
||||
{
|
||||
if (WARN_ON(!size))
|
||||
return -ENXIO;
|
||||
@ -62,6 +66,7 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
|
||||
size = PAGE_ALIGN(size);
|
||||
dmab->dev.type = type;
|
||||
dmab->dev.dev = device;
|
||||
dmab->dev.dir = dir;
|
||||
dmab->bytes = 0;
|
||||
dmab->addr = 0;
|
||||
dmab->private_data = NULL;
|
||||
@ -71,7 +76,7 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
|
||||
dmab->bytes = size;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_dma_alloc_pages);
|
||||
EXPORT_SYMBOL(snd_dma_alloc_dir_pages);
|
||||
|
||||
/**
|
||||
* snd_dma_alloc_pages_fallback - allocate the buffer area according to the given type with fallback
|
||||
@ -129,9 +134,10 @@ static void __snd_release_pages(struct device *dev, void *res)
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_devm_alloc_pages - allocate the buffer and manage with devres
|
||||
* snd_devm_alloc_dir_pages - allocate the buffer and manage with devres
|
||||
* @dev: the device pointer
|
||||
* @type: the DMA buffer type
|
||||
* @dir: DMA direction
|
||||
* @size: the buffer size to allocate
|
||||
*
|
||||
* Allocate buffer pages depending on the given type and manage using devres.
|
||||
@ -144,7 +150,8 @@ static void __snd_release_pages(struct device *dev, void *res)
|
||||
* The function returns the snd_dma_buffer object at success, or NULL if failed.
|
||||
*/
|
||||
struct snd_dma_buffer *
|
||||
snd_devm_alloc_pages(struct device *dev, int type, size_t size)
|
||||
snd_devm_alloc_dir_pages(struct device *dev, int type,
|
||||
enum dma_data_direction dir, size_t size)
|
||||
{
|
||||
struct snd_dma_buffer *dmab;
|
||||
int err;
|
||||
@ -157,7 +164,7 @@ snd_devm_alloc_pages(struct device *dev, int type, size_t size)
|
||||
if (!dmab)
|
||||
return NULL;
|
||||
|
||||
err = snd_dma_alloc_pages(type, dev, size, dmab);
|
||||
err = snd_dma_alloc_dir_pages(type, dev, dir, size, dmab);
|
||||
if (err < 0) {
|
||||
devres_free(dmab);
|
||||
return NULL;
|
||||
@ -166,7 +173,7 @@ snd_devm_alloc_pages(struct device *dev, int type, size_t size)
|
||||
devres_add(dev, dmab);
|
||||
return dmab;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_devm_alloc_pages);
|
||||
EXPORT_SYMBOL_GPL(snd_devm_alloc_dir_pages);
|
||||
|
||||
/**
|
||||
* snd_dma_buffer_mmap - perform mmap of the given DMA buffer
|
||||
@ -185,6 +192,26 @@ int snd_dma_buffer_mmap(struct snd_dma_buffer *dmab,
|
||||
}
|
||||
EXPORT_SYMBOL(snd_dma_buffer_mmap);
|
||||
|
||||
#ifdef CONFIG_HAS_DMA
|
||||
/**
|
||||
* snd_dma_buffer_sync - sync DMA buffer between CPU and device
|
||||
* @dmab: buffer allocation information
|
||||
* @mode: sync mode
|
||||
*/
|
||||
void snd_dma_buffer_sync(struct snd_dma_buffer *dmab,
|
||||
enum snd_dma_sync_mode mode)
|
||||
{
|
||||
const struct snd_malloc_ops *ops;
|
||||
|
||||
if (!dmab || !dmab->dev.need_sync)
|
||||
return;
|
||||
ops = snd_dma_get_ops(dmab);
|
||||
if (ops && ops->sync)
|
||||
ops->sync(dmab, mode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_dma_buffer_sync);
|
||||
#endif /* CONFIG_HAS_DMA */
|
||||
|
||||
/**
|
||||
* snd_sgbuf_get_addr - return the physical address at the corresponding offset
|
||||
* @dmab: buffer allocation information
|
||||
@ -468,6 +495,161 @@ static const struct snd_malloc_ops snd_dma_wc_ops = {
|
||||
.mmap = snd_dma_wc_mmap,
|
||||
};
|
||||
#endif /* CONFIG_X86 */
|
||||
|
||||
/*
|
||||
* Non-contiguous pages allocator
|
||||
*/
|
||||
static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size)
|
||||
{
|
||||
struct sg_table *sgt;
|
||||
void *p;
|
||||
|
||||
sgt = dma_alloc_noncontiguous(dmab->dev.dev, size, dmab->dev.dir,
|
||||
DEFAULT_GFP, 0);
|
||||
if (!sgt)
|
||||
return NULL;
|
||||
dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, dmab->dev.dir);
|
||||
p = dma_vmap_noncontiguous(dmab->dev.dev, size, sgt);
|
||||
if (p)
|
||||
dmab->private_data = sgt;
|
||||
else
|
||||
dma_free_noncontiguous(dmab->dev.dev, size, sgt, dmab->dev.dir);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void snd_dma_noncontig_free(struct snd_dma_buffer *dmab)
|
||||
{
|
||||
dma_vunmap_noncontiguous(dmab->dev.dev, dmab->area);
|
||||
dma_free_noncontiguous(dmab->dev.dev, dmab->bytes, dmab->private_data,
|
||||
dmab->dev.dir);
|
||||
}
|
||||
|
||||
static int snd_dma_noncontig_mmap(struct snd_dma_buffer *dmab,
|
||||
struct vm_area_struct *area)
|
||||
{
|
||||
return dma_mmap_noncontiguous(dmab->dev.dev, area,
|
||||
dmab->bytes, dmab->private_data);
|
||||
}
|
||||
|
||||
static void snd_dma_noncontig_sync(struct snd_dma_buffer *dmab,
|
||||
enum snd_dma_sync_mode mode)
|
||||
{
|
||||
if (mode == SNDRV_DMA_SYNC_CPU) {
|
||||
if (dmab->dev.dir == DMA_TO_DEVICE)
|
||||
return;
|
||||
dma_sync_sgtable_for_cpu(dmab->dev.dev, dmab->private_data,
|
||||
dmab->dev.dir);
|
||||
invalidate_kernel_vmap_range(dmab->area, dmab->bytes);
|
||||
} else {
|
||||
if (dmab->dev.dir == DMA_FROM_DEVICE)
|
||||
return;
|
||||
flush_kernel_vmap_range(dmab->area, dmab->bytes);
|
||||
dma_sync_sgtable_for_device(dmab->dev.dev, dmab->private_data,
|
||||
dmab->dev.dir);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct snd_malloc_ops snd_dma_noncontig_ops = {
|
||||
.alloc = snd_dma_noncontig_alloc,
|
||||
.free = snd_dma_noncontig_free,
|
||||
.mmap = snd_dma_noncontig_mmap,
|
||||
.sync = snd_dma_noncontig_sync,
|
||||
/* re-use vmalloc helpers for get_* ops */
|
||||
.get_addr = snd_dma_vmalloc_get_addr,
|
||||
.get_page = snd_dma_vmalloc_get_page,
|
||||
.get_chunk_size = snd_dma_vmalloc_get_chunk_size,
|
||||
};
|
||||
|
||||
/* x86-specific SG-buffer with WC pages */
|
||||
#ifdef CONFIG_SND_DMA_SGBUF
|
||||
#define vmalloc_to_virt(v) (unsigned long)page_to_virt(vmalloc_to_page(v))
|
||||
|
||||
static void *snd_dma_sg_wc_alloc(struct snd_dma_buffer *dmab, size_t size)
|
||||
{
|
||||
void *p = snd_dma_noncontig_alloc(dmab, size);
|
||||
size_t ofs;
|
||||
|
||||
if (!p)
|
||||
return NULL;
|
||||
for (ofs = 0; ofs < size; ofs += PAGE_SIZE)
|
||||
set_memory_uc(vmalloc_to_virt(p + ofs), 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void snd_dma_sg_wc_free(struct snd_dma_buffer *dmab)
|
||||
{
|
||||
size_t ofs;
|
||||
|
||||
for (ofs = 0; ofs < dmab->bytes; ofs += PAGE_SIZE)
|
||||
set_memory_wb(vmalloc_to_virt(dmab->area + ofs), 1);
|
||||
snd_dma_noncontig_free(dmab);
|
||||
}
|
||||
|
||||
static int snd_dma_sg_wc_mmap(struct snd_dma_buffer *dmab,
|
||||
struct vm_area_struct *area)
|
||||
{
|
||||
area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
|
||||
/* FIXME: dma_mmap_noncontiguous() works? */
|
||||
return -ENOENT; /* continue with the default mmap handler */
|
||||
}
|
||||
|
||||
const struct snd_malloc_ops snd_dma_sg_wc_ops = {
|
||||
.alloc = snd_dma_sg_wc_alloc,
|
||||
.free = snd_dma_sg_wc_free,
|
||||
.mmap = snd_dma_sg_wc_mmap,
|
||||
.sync = snd_dma_noncontig_sync,
|
||||
.get_addr = snd_dma_vmalloc_get_addr,
|
||||
.get_page = snd_dma_vmalloc_get_page,
|
||||
.get_chunk_size = snd_dma_vmalloc_get_chunk_size,
|
||||
};
|
||||
#endif /* CONFIG_SND_DMA_SGBUF */
|
||||
|
||||
/*
|
||||
* Non-coherent pages allocator
|
||||
*/
|
||||
static void *snd_dma_noncoherent_alloc(struct snd_dma_buffer *dmab, size_t size)
|
||||
{
|
||||
dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, dmab->dev.dir);
|
||||
return dma_alloc_noncoherent(dmab->dev.dev, size, &dmab->addr,
|
||||
dmab->dev.dir, DEFAULT_GFP);
|
||||
}
|
||||
|
||||
static void snd_dma_noncoherent_free(struct snd_dma_buffer *dmab)
|
||||
{
|
||||
dma_free_noncoherent(dmab->dev.dev, dmab->bytes, dmab->area,
|
||||
dmab->addr, dmab->dev.dir);
|
||||
}
|
||||
|
||||
static int snd_dma_noncoherent_mmap(struct snd_dma_buffer *dmab,
|
||||
struct vm_area_struct *area)
|
||||
{
|
||||
area->vm_page_prot = vm_get_page_prot(area->vm_flags);
|
||||
return dma_mmap_pages(dmab->dev.dev, area,
|
||||
area->vm_end - area->vm_start,
|
||||
virt_to_page(dmab->area));
|
||||
}
|
||||
|
||||
static void snd_dma_noncoherent_sync(struct snd_dma_buffer *dmab,
|
||||
enum snd_dma_sync_mode mode)
|
||||
{
|
||||
if (mode == SNDRV_DMA_SYNC_CPU) {
|
||||
if (dmab->dev.dir != DMA_TO_DEVICE)
|
||||
dma_sync_single_for_cpu(dmab->dev.dev, dmab->addr,
|
||||
dmab->bytes, dmab->dev.dir);
|
||||
} else {
|
||||
if (dmab->dev.dir != DMA_FROM_DEVICE)
|
||||
dma_sync_single_for_device(dmab->dev.dev, dmab->addr,
|
||||
dmab->bytes, dmab->dev.dir);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct snd_malloc_ops snd_dma_noncoherent_ops = {
|
||||
.alloc = snd_dma_noncoherent_alloc,
|
||||
.free = snd_dma_noncoherent_free,
|
||||
.mmap = snd_dma_noncoherent_mmap,
|
||||
.sync = snd_dma_noncoherent_sync,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_HAS_DMA */
|
||||
|
||||
/*
|
||||
@ -479,14 +661,15 @@ static const struct snd_malloc_ops *dma_ops[] = {
|
||||
#ifdef CONFIG_HAS_DMA
|
||||
[SNDRV_DMA_TYPE_DEV] = &snd_dma_dev_ops,
|
||||
[SNDRV_DMA_TYPE_DEV_WC] = &snd_dma_wc_ops,
|
||||
[SNDRV_DMA_TYPE_NONCONTIG] = &snd_dma_noncontig_ops,
|
||||
[SNDRV_DMA_TYPE_NONCOHERENT] = &snd_dma_noncoherent_ops,
|
||||
#ifdef CONFIG_SND_DMA_SGBUF
|
||||
[SNDRV_DMA_TYPE_DEV_WC_SG] = &snd_dma_sg_wc_ops,
|
||||
#endif
|
||||
#ifdef CONFIG_GENERIC_ALLOCATOR
|
||||
[SNDRV_DMA_TYPE_DEV_IRAM] = &snd_dma_iram_ops,
|
||||
#endif /* CONFIG_GENERIC_ALLOCATOR */
|
||||
#endif /* CONFIG_HAS_DMA */
|
||||
#ifdef CONFIG_SND_DMA_SGBUF
|
||||
[SNDRV_DMA_TYPE_DEV_SG] = &snd_dma_sg_ops,
|
||||
[SNDRV_DMA_TYPE_DEV_WC_SG] = &snd_dma_sg_ops,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct snd_malloc_ops *snd_dma_get_ops(struct snd_dma_buffer *dmab)
|
||||
|
@ -10,6 +10,7 @@ struct snd_malloc_ops {
|
||||
unsigned int (*get_chunk_size)(struct snd_dma_buffer *dmab,
|
||||
unsigned int ofs, unsigned int size);
|
||||
int (*mmap)(struct snd_dma_buffer *dmab, struct vm_area_struct *area);
|
||||
void (*sync)(struct snd_dma_buffer *dmab, enum snd_dma_sync_mode mode);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SND_DMA_SGBUF
|
||||
|
@ -130,11 +130,13 @@ static int snd_mixer_oss_devmask(struct snd_mixer_oss_file *fmixer)
|
||||
|
||||
if (mixer == NULL)
|
||||
return -EIO;
|
||||
mutex_lock(&mixer->reg_mutex);
|
||||
for (chn = 0; chn < 31; chn++) {
|
||||
pslot = &mixer->slots[chn];
|
||||
if (pslot->put_volume || pslot->put_recsrc)
|
||||
result |= 1 << chn;
|
||||
}
|
||||
mutex_unlock(&mixer->reg_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -146,11 +148,13 @@ static int snd_mixer_oss_stereodevs(struct snd_mixer_oss_file *fmixer)
|
||||
|
||||
if (mixer == NULL)
|
||||
return -EIO;
|
||||
mutex_lock(&mixer->reg_mutex);
|
||||
for (chn = 0; chn < 31; chn++) {
|
||||
pslot = &mixer->slots[chn];
|
||||
if (pslot->put_volume && pslot->stereo)
|
||||
result |= 1 << chn;
|
||||
}
|
||||
mutex_unlock(&mixer->reg_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -161,6 +165,7 @@ static int snd_mixer_oss_recmask(struct snd_mixer_oss_file *fmixer)
|
||||
|
||||
if (mixer == NULL)
|
||||
return -EIO;
|
||||
mutex_lock(&mixer->reg_mutex);
|
||||
if (mixer->put_recsrc && mixer->get_recsrc) { /* exclusive */
|
||||
result = mixer->mask_recsrc;
|
||||
} else {
|
||||
@ -172,6 +177,7 @@ static int snd_mixer_oss_recmask(struct snd_mixer_oss_file *fmixer)
|
||||
result |= 1 << chn;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&mixer->reg_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -182,12 +188,12 @@ static int snd_mixer_oss_get_recsrc(struct snd_mixer_oss_file *fmixer)
|
||||
|
||||
if (mixer == NULL)
|
||||
return -EIO;
|
||||
mutex_lock(&mixer->reg_mutex);
|
||||
if (mixer->put_recsrc && mixer->get_recsrc) { /* exclusive */
|
||||
int err;
|
||||
unsigned int index;
|
||||
err = mixer->get_recsrc(fmixer, &index);
|
||||
if (err < 0)
|
||||
return err;
|
||||
result = mixer->get_recsrc(fmixer, &index);
|
||||
if (result < 0)
|
||||
goto unlock;
|
||||
result = 1 << index;
|
||||
} else {
|
||||
struct snd_mixer_oss_slot *pslot;
|
||||
@ -202,7 +208,10 @@ static int snd_mixer_oss_get_recsrc(struct snd_mixer_oss_file *fmixer)
|
||||
}
|
||||
}
|
||||
}
|
||||
return mixer->oss_recsrc = result;
|
||||
mixer->oss_recsrc = result;
|
||||
unlock:
|
||||
mutex_unlock(&mixer->reg_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int snd_mixer_oss_set_recsrc(struct snd_mixer_oss_file *fmixer, int recsrc)
|
||||
@ -215,6 +224,7 @@ static int snd_mixer_oss_set_recsrc(struct snd_mixer_oss_file *fmixer, int recsr
|
||||
|
||||
if (mixer == NULL)
|
||||
return -EIO;
|
||||
mutex_lock(&mixer->reg_mutex);
|
||||
if (mixer->get_recsrc && mixer->put_recsrc) { /* exclusive input */
|
||||
if (recsrc & ~mixer->oss_recsrc)
|
||||
recsrc &= ~mixer->oss_recsrc;
|
||||
@ -240,6 +250,7 @@ static int snd_mixer_oss_set_recsrc(struct snd_mixer_oss_file *fmixer, int recsr
|
||||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&mixer->reg_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -251,6 +262,7 @@ static int snd_mixer_oss_get_volume(struct snd_mixer_oss_file *fmixer, int slot)
|
||||
|
||||
if (mixer == NULL || slot > 30)
|
||||
return -EIO;
|
||||
mutex_lock(&mixer->reg_mutex);
|
||||
pslot = &mixer->slots[slot];
|
||||
left = pslot->volume[0];
|
||||
right = pslot->volume[1];
|
||||
@ -258,15 +270,21 @@ static int snd_mixer_oss_get_volume(struct snd_mixer_oss_file *fmixer, int slot)
|
||||
result = pslot->get_volume(fmixer, pslot, &left, &right);
|
||||
if (!pslot->stereo)
|
||||
right = left;
|
||||
if (snd_BUG_ON(left < 0 || left > 100))
|
||||
return -EIO;
|
||||
if (snd_BUG_ON(right < 0 || right > 100))
|
||||
return -EIO;
|
||||
if (snd_BUG_ON(left < 0 || left > 100)) {
|
||||
result = -EIO;
|
||||
goto unlock;
|
||||
}
|
||||
if (snd_BUG_ON(right < 0 || right > 100)) {
|
||||
result = -EIO;
|
||||
goto unlock;
|
||||
}
|
||||
if (result >= 0) {
|
||||
pslot->volume[0] = left;
|
||||
pslot->volume[1] = right;
|
||||
result = (left & 0xff) | ((right & 0xff) << 8);
|
||||
}
|
||||
unlock:
|
||||
mutex_unlock(&mixer->reg_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -279,6 +297,7 @@ static int snd_mixer_oss_set_volume(struct snd_mixer_oss_file *fmixer,
|
||||
|
||||
if (mixer == NULL || slot > 30)
|
||||
return -EIO;
|
||||
mutex_lock(&mixer->reg_mutex);
|
||||
pslot = &mixer->slots[slot];
|
||||
if (left > 100)
|
||||
left = 100;
|
||||
@ -289,10 +308,13 @@ static int snd_mixer_oss_set_volume(struct snd_mixer_oss_file *fmixer,
|
||||
if (pslot->put_volume)
|
||||
result = pslot->put_volume(fmixer, pslot, left, right);
|
||||
if (result < 0)
|
||||
return result;
|
||||
goto unlock;
|
||||
pslot->volume[0] = left;
|
||||
pslot->volume[1] = right;
|
||||
return (left & 0xff) | ((right & 0xff) << 8);
|
||||
result = (left & 0xff) | ((right & 0xff) << 8);
|
||||
unlock:
|
||||
mutex_unlock(&mixer->reg_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int snd_mixer_oss_ioctl1(struct snd_mixer_oss_file *fmixer, unsigned int cmd, unsigned long arg)
|
||||
|
@ -453,6 +453,8 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
|
||||
sstatus.suspended_state = status->suspended_state;
|
||||
sstatus.audio_tstamp = status->audio_tstamp;
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
if (put_user(sstatus.state, &src->s.status.state) ||
|
||||
put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
|
||||
put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp_sec) ||
|
||||
@ -533,6 +535,8 @@ static int snd_pcm_ioctl_sync_ptr_buggy(struct snd_pcm_substream *substream,
|
||||
sync_ptr.s.status.suspended_state = status->suspended_state;
|
||||
sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL))
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
@ -106,6 +106,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
|
||||
frames -= transfer;
|
||||
ofs = 0;
|
||||
}
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
@ -2256,8 +2257,12 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
|
||||
goto _end_unlock;
|
||||
}
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
if (!is_playback)
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_CPU);
|
||||
err = writer(substream, appl_ofs, data, offset, frames,
|
||||
transfer);
|
||||
if (is_playback)
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
if (err < 0)
|
||||
goto _end_unlock;
|
||||
|
@ -73,4 +73,11 @@ void snd_pcm_sync_stop(struct snd_pcm_substream *substream, bool sync_irq);
|
||||
for ((subs) = (pcm)->streams[str].substream; (subs); \
|
||||
(subs) = (subs)->next)
|
||||
|
||||
static inline void snd_pcm_dma_buffer_sync(struct snd_pcm_substream *substream,
|
||||
enum snd_dma_sync_mode mode)
|
||||
{
|
||||
if (substream->runtime->info & SNDRV_PCM_INFO_EXPLICIT_SYNC)
|
||||
snd_dma_buffer_sync(snd_pcm_get_dma_buf(substream), mode);
|
||||
}
|
||||
|
||||
#endif /* __SOUND_CORE_PCM_LOCAL_H */
|
||||
|
@ -32,15 +32,20 @@ module_param(max_alloc_per_card, ulong, 0644);
|
||||
MODULE_PARM_DESC(max_alloc_per_card, "Max total allocation bytes per card.");
|
||||
|
||||
static int do_alloc_pages(struct snd_card *card, int type, struct device *dev,
|
||||
size_t size, struct snd_dma_buffer *dmab)
|
||||
int str, size_t size, struct snd_dma_buffer *dmab)
|
||||
{
|
||||
enum dma_data_direction dir;
|
||||
int err;
|
||||
|
||||
if (max_alloc_per_card &&
|
||||
card->total_pcm_alloc_bytes + size > max_alloc_per_card)
|
||||
return -ENOMEM;
|
||||
|
||||
err = snd_dma_alloc_pages(type, dev, size, dmab);
|
||||
if (str == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
dir = DMA_TO_DEVICE;
|
||||
else
|
||||
dir = DMA_FROM_DEVICE;
|
||||
err = snd_dma_alloc_dir_pages(type, dev, dir, size, dmab);
|
||||
if (!err) {
|
||||
mutex_lock(&card->memory_mutex);
|
||||
card->total_pcm_alloc_bytes += dmab->bytes;
|
||||
@ -77,7 +82,7 @@ static int preallocate_pcm_pages(struct snd_pcm_substream *substream,
|
||||
|
||||
do {
|
||||
err = do_alloc_pages(card, dmab->dev.type, dmab->dev.dev,
|
||||
size, dmab);
|
||||
substream->stream, size, dmab);
|
||||
if (err != -ENOMEM)
|
||||
return err;
|
||||
if (no_fallback)
|
||||
@ -177,6 +182,7 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
|
||||
if (do_alloc_pages(card,
|
||||
substream->dma_buffer.dev.type,
|
||||
substream->dma_buffer.dev.dev,
|
||||
substream->stream,
|
||||
size, &new_dmab) < 0) {
|
||||
buffer->error = -ENOMEM;
|
||||
pr_debug("ALSA pcmC%dD%d%c,%d:%s: cannot preallocate for size %zu\n",
|
||||
@ -418,6 +424,7 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
|
||||
if (do_alloc_pages(card,
|
||||
substream->dma_buffer.dev.type,
|
||||
substream->dma_buffer.dev.dev,
|
||||
substream->stream,
|
||||
size, dmab) < 0) {
|
||||
kfree(dmab);
|
||||
pr_debug("ALSA pcmC%dD%d%c,%d:%s: cannot preallocate for size %zu\n",
|
||||
|
@ -2685,6 +2685,13 @@ int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* automatically set EXPLICIT_SYNC flag in the managed mode whenever
|
||||
* the DMA buffer requires it
|
||||
*/
|
||||
if (substream->managed_buffer_alloc &&
|
||||
substream->dma_buffer.dev.need_sync)
|
||||
substream->runtime->hw.info |= SNDRV_PCM_INFO_EXPLICIT_SYNC;
|
||||
|
||||
*rsubstream = substream;
|
||||
return 0;
|
||||
|
||||
@ -2912,6 +2919,8 @@ static snd_pcm_sframes_t snd_pcm_rewind(struct snd_pcm_substream *substream,
|
||||
ret = rewind_appl_ptr(substream, frames,
|
||||
snd_pcm_hw_avail(substream));
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
if (ret >= 0)
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2929,35 +2938,31 @@ static snd_pcm_sframes_t snd_pcm_forward(struct snd_pcm_substream *substream,
|
||||
ret = forward_appl_ptr(substream, frames,
|
||||
snd_pcm_avail(substream));
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
if (ret >= 0)
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int snd_pcm_hwsync(struct snd_pcm_substream *substream)
|
||||
{
|
||||
int err;
|
||||
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
err = do_pcm_hwsync(substream);
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int snd_pcm_delay(struct snd_pcm_substream *substream,
|
||||
snd_pcm_sframes_t *delay)
|
||||
{
|
||||
int err;
|
||||
snd_pcm_sframes_t n = 0;
|
||||
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
err = do_pcm_hwsync(substream);
|
||||
if (!err)
|
||||
n = snd_pcm_calc_delay(substream);
|
||||
if (delay && !err)
|
||||
*delay = snd_pcm_calc_delay(substream);
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
if (!err)
|
||||
*delay = n;
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_CPU);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline int snd_pcm_hwsync(struct snd_pcm_substream *substream)
|
||||
{
|
||||
return snd_pcm_delay(substream, NULL);
|
||||
}
|
||||
|
||||
static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_sync_ptr __user *_sync_ptr)
|
||||
{
|
||||
@ -3000,6 +3005,8 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
|
||||
sync_ptr.s.status.suspended_state = status->suspended_state;
|
||||
sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL))
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
@ -3096,6 +3103,8 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
|
||||
sstatus.suspended_state = status->suspended_state;
|
||||
sstatus.audio_tstamp = status->audio_tstamp;
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
if (put_user(sstatus.state, &src->s.status.state) ||
|
||||
put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
|
||||
put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp_sec) ||
|
||||
@ -3218,6 +3227,9 @@ static int snd_pcm_common_ioctl(struct file *file,
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
|
||||
if (substream->runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
|
||||
return -EBADFD;
|
||||
|
||||
res = snd_power_wait(substream->pcm->card);
|
||||
if (res < 0)
|
||||
return res;
|
||||
@ -3272,7 +3284,7 @@ static int snd_pcm_common_ioctl(struct file *file,
|
||||
return snd_pcm_hwsync(substream);
|
||||
case SNDRV_PCM_IOCTL_DELAY:
|
||||
{
|
||||
snd_pcm_sframes_t delay;
|
||||
snd_pcm_sframes_t delay = 0;
|
||||
snd_pcm_sframes_t __user *res = arg;
|
||||
int err;
|
||||
|
||||
@ -3344,6 +3356,9 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
|
||||
snd_pcm_uframes_t *frames = arg;
|
||||
snd_pcm_sframes_t result;
|
||||
|
||||
if (substream->runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
|
||||
return -EBADFD;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_IOCTL_FORWARD:
|
||||
{
|
||||
@ -3386,7 +3401,8 @@ static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
|
||||
runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
|
||||
return -EBADFD;
|
||||
if (!frame_aligned(runtime, count))
|
||||
return -EINVAL;
|
||||
@ -3410,7 +3426,8 @@ static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
|
||||
runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
|
||||
return -EBADFD;
|
||||
if (!frame_aligned(runtime, count))
|
||||
return -EINVAL;
|
||||
@ -3436,7 +3453,8 @@ static ssize_t snd_pcm_readv(struct kiocb *iocb, struct iov_iter *to)
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
|
||||
runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
|
||||
return -EBADFD;
|
||||
if (!iter_is_iovec(to))
|
||||
return -EINVAL;
|
||||
@ -3472,7 +3490,8 @@ static ssize_t snd_pcm_writev(struct kiocb *iocb, struct iov_iter *from)
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
|
||||
runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
|
||||
return -EBADFD;
|
||||
if (!iter_is_iovec(from))
|
||||
return -EINVAL;
|
||||
@ -3511,6 +3530,9 @@ static __poll_t snd_pcm_poll(struct file *file, poll_table *wait)
|
||||
return ok | EPOLLERR;
|
||||
|
||||
runtime = substream->runtime;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
|
||||
return ok | EPOLLERR;
|
||||
|
||||
poll_wait(file, &runtime->sleep, wait);
|
||||
|
||||
mask = 0;
|
||||
@ -3820,6 +3842,8 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
|
||||
substream = pcm_file->substream;
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
if (substream->runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
|
||||
return -EBADFD;
|
||||
|
||||
offset = area->vm_pgoff << PAGE_SHIFT;
|
||||
switch (offset) {
|
||||
@ -3856,6 +3880,8 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
|
||||
return -EBADFD;
|
||||
return fasync_helper(fd, file, on, &runtime->fasync);
|
||||
}
|
||||
|
||||
|
@ -1,201 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Scatter-Gather buffer
|
||||
*
|
||||
* Copyright (c) by Takashi Iwai <tiwai@suse.de>
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/export.h>
|
||||
#include <sound/memalloc.h>
|
||||
#include "memalloc_local.h"
|
||||
|
||||
struct snd_sg_page {
|
||||
void *buf;
|
||||
dma_addr_t addr;
|
||||
};
|
||||
|
||||
struct snd_sg_buf {
|
||||
int size; /* allocated byte size */
|
||||
int pages; /* allocated pages */
|
||||
int tblsize; /* allocated table size */
|
||||
struct snd_sg_page *table; /* address table */
|
||||
struct page **page_table; /* page table (for vmap/vunmap) */
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
/* table entries are align to 32 */
|
||||
#define SGBUF_TBL_ALIGN 32
|
||||
#define sgbuf_align_table(tbl) ALIGN((tbl), SGBUF_TBL_ALIGN)
|
||||
|
||||
static void snd_dma_sg_free(struct snd_dma_buffer *dmab)
|
||||
{
|
||||
struct snd_sg_buf *sgbuf = dmab->private_data;
|
||||
struct snd_dma_buffer tmpb;
|
||||
int i;
|
||||
|
||||
if (!sgbuf)
|
||||
return;
|
||||
|
||||
vunmap(dmab->area);
|
||||
dmab->area = NULL;
|
||||
|
||||
tmpb.dev.type = SNDRV_DMA_TYPE_DEV;
|
||||
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG)
|
||||
tmpb.dev.type = SNDRV_DMA_TYPE_DEV_WC;
|
||||
tmpb.dev.dev = sgbuf->dev;
|
||||
for (i = 0; i < sgbuf->pages; i++) {
|
||||
if (!(sgbuf->table[i].addr & ~PAGE_MASK))
|
||||
continue; /* continuous pages */
|
||||
tmpb.area = sgbuf->table[i].buf;
|
||||
tmpb.addr = sgbuf->table[i].addr & PAGE_MASK;
|
||||
tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT;
|
||||
snd_dma_free_pages(&tmpb);
|
||||
}
|
||||
|
||||
kfree(sgbuf->table);
|
||||
kfree(sgbuf->page_table);
|
||||
kfree(sgbuf);
|
||||
dmab->private_data = NULL;
|
||||
}
|
||||
|
||||
#define MAX_ALLOC_PAGES 32
|
||||
|
||||
static void *snd_dma_sg_alloc(struct snd_dma_buffer *dmab, size_t size)
|
||||
{
|
||||
struct snd_sg_buf *sgbuf;
|
||||
unsigned int i, pages, chunk, maxpages;
|
||||
struct snd_dma_buffer tmpb;
|
||||
struct snd_sg_page *table;
|
||||
struct page **pgtable;
|
||||
int type = SNDRV_DMA_TYPE_DEV;
|
||||
pgprot_t prot = PAGE_KERNEL;
|
||||
void *area;
|
||||
|
||||
dmab->private_data = sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL);
|
||||
if (!sgbuf)
|
||||
return NULL;
|
||||
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG) {
|
||||
type = SNDRV_DMA_TYPE_DEV_WC;
|
||||
#ifdef pgprot_noncached
|
||||
prot = pgprot_noncached(PAGE_KERNEL);
|
||||
#endif
|
||||
}
|
||||
sgbuf->dev = dmab->dev.dev;
|
||||
pages = snd_sgbuf_aligned_pages(size);
|
||||
sgbuf->tblsize = sgbuf_align_table(pages);
|
||||
table = kcalloc(sgbuf->tblsize, sizeof(*table), GFP_KERNEL);
|
||||
if (!table)
|
||||
goto _failed;
|
||||
sgbuf->table = table;
|
||||
pgtable = kcalloc(sgbuf->tblsize, sizeof(*pgtable), GFP_KERNEL);
|
||||
if (!pgtable)
|
||||
goto _failed;
|
||||
sgbuf->page_table = pgtable;
|
||||
|
||||
/* allocate pages */
|
||||
maxpages = MAX_ALLOC_PAGES;
|
||||
while (pages > 0) {
|
||||
chunk = pages;
|
||||
/* don't be too eager to take a huge chunk */
|
||||
if (chunk > maxpages)
|
||||
chunk = maxpages;
|
||||
chunk <<= PAGE_SHIFT;
|
||||
if (snd_dma_alloc_pages_fallback(type, dmab->dev.dev,
|
||||
chunk, &tmpb) < 0) {
|
||||
if (!sgbuf->pages)
|
||||
goto _failed;
|
||||
size = sgbuf->pages * PAGE_SIZE;
|
||||
break;
|
||||
}
|
||||
chunk = tmpb.bytes >> PAGE_SHIFT;
|
||||
for (i = 0; i < chunk; i++) {
|
||||
table->buf = tmpb.area;
|
||||
table->addr = tmpb.addr;
|
||||
if (!i)
|
||||
table->addr |= chunk; /* mark head */
|
||||
table++;
|
||||
*pgtable++ = virt_to_page(tmpb.area);
|
||||
tmpb.area += PAGE_SIZE;
|
||||
tmpb.addr += PAGE_SIZE;
|
||||
}
|
||||
sgbuf->pages += chunk;
|
||||
pages -= chunk;
|
||||
if (chunk < maxpages)
|
||||
maxpages = chunk;
|
||||
}
|
||||
|
||||
sgbuf->size = size;
|
||||
area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, prot);
|
||||
if (!area)
|
||||
goto _failed;
|
||||
return area;
|
||||
|
||||
_failed:
|
||||
snd_dma_sg_free(dmab); /* free the table */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static dma_addr_t snd_dma_sg_get_addr(struct snd_dma_buffer *dmab,
|
||||
size_t offset)
|
||||
{
|
||||
struct snd_sg_buf *sgbuf = dmab->private_data;
|
||||
dma_addr_t addr;
|
||||
|
||||
addr = sgbuf->table[offset >> PAGE_SHIFT].addr;
|
||||
addr &= ~((dma_addr_t)PAGE_SIZE - 1);
|
||||
return addr + offset % PAGE_SIZE;
|
||||
}
|
||||
|
||||
static struct page *snd_dma_sg_get_page(struct snd_dma_buffer *dmab,
|
||||
size_t offset)
|
||||
{
|
||||
struct snd_sg_buf *sgbuf = dmab->private_data;
|
||||
unsigned int idx = offset >> PAGE_SHIFT;
|
||||
|
||||
if (idx >= (unsigned int)sgbuf->pages)
|
||||
return NULL;
|
||||
return sgbuf->page_table[idx];
|
||||
}
|
||||
|
||||
static unsigned int snd_dma_sg_get_chunk_size(struct snd_dma_buffer *dmab,
|
||||
unsigned int ofs,
|
||||
unsigned int size)
|
||||
{
|
||||
struct snd_sg_buf *sg = dmab->private_data;
|
||||
unsigned int start, end, pg;
|
||||
|
||||
start = ofs >> PAGE_SHIFT;
|
||||
end = (ofs + size - 1) >> PAGE_SHIFT;
|
||||
/* check page continuity */
|
||||
pg = sg->table[start].addr >> PAGE_SHIFT;
|
||||
for (;;) {
|
||||
start++;
|
||||
if (start > end)
|
||||
break;
|
||||
pg++;
|
||||
if ((sg->table[start].addr >> PAGE_SHIFT) != pg)
|
||||
return (start << PAGE_SHIFT) - ofs;
|
||||
}
|
||||
/* ok, all on continuous pages */
|
||||
return size;
|
||||
}
|
||||
|
||||
static int snd_dma_sg_mmap(struct snd_dma_buffer *dmab,
|
||||
struct vm_area_struct *area)
|
||||
{
|
||||
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG)
|
||||
area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
|
||||
return -ENOENT; /* continue with the default mmap handler */
|
||||
}
|
||||
|
||||
const struct snd_malloc_ops snd_dma_sg_ops = {
|
||||
.alloc = snd_dma_sg_alloc,
|
||||
.free = snd_dma_sg_free,
|
||||
.get_addr = snd_dma_sg_get_addr,
|
||||
.get_page = snd_dma_sg_get_page,
|
||||
.get_chunk_size = snd_dma_sg_get_chunk_size,
|
||||
.mmap = snd_dma_sg_mmap,
|
||||
};
|
@ -4,5 +4,6 @@ CFLAGS_amdtp-motu.o := -I$(src)
|
||||
snd-firewire-motu-objs := motu.o amdtp-motu.o motu-transaction.o motu-stream.o \
|
||||
motu-proc.o motu-pcm.o motu-midi.o motu-hwdep.o \
|
||||
motu-protocol-v2.o motu-protocol-v3.o \
|
||||
motu-protocol-v1.o
|
||||
motu-protocol-v1.o motu-register-dsp-message-parser.o \
|
||||
motu-command-dsp-message-parser.o
|
||||
obj-$(CONFIG_SND_FIREWIRE_MOTU) += snd-firewire-motu.o
|
||||
|
@ -333,6 +333,7 @@ static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
|
||||
unsigned int packets,
|
||||
struct snd_pcm_substream *pcm)
|
||||
{
|
||||
struct snd_motu *motu = container_of(s, struct snd_motu, tx_stream);
|
||||
struct amdtp_motu *p = s->protocol;
|
||||
unsigned int pcm_frames = 0;
|
||||
int i;
|
||||
@ -357,6 +358,14 @@ static unsigned int process_ir_ctx_payloads(struct amdtp_stream *s,
|
||||
read_midi_messages(s, buf, data_blocks);
|
||||
}
|
||||
|
||||
if (motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP) {
|
||||
snd_motu_register_dsp_message_parser_parse(motu, descs, packets,
|
||||
s->data_block_quadlets);
|
||||
} else if (motu->spec->flags & SND_MOTU_SPEC_COMMAND_DSP) {
|
||||
snd_motu_command_dsp_message_parser_parse(motu, descs, packets,
|
||||
s->data_block_quadlets);
|
||||
}
|
||||
|
||||
// For tracepoints.
|
||||
if (trace_data_block_sph_enabled() ||
|
||||
trace_data_block_message_enabled())
|
||||
@ -415,8 +424,6 @@ static unsigned int process_it_ctx_payloads(struct amdtp_stream *s,
|
||||
if (p->midi_ports)
|
||||
write_midi_messages(s, buf, data_blocks);
|
||||
|
||||
// TODO: how to interact control messages between userspace?
|
||||
|
||||
write_sph(p->cache, buf, data_blocks, s->data_block_quadlets);
|
||||
}
|
||||
|
||||
|
181
sound/firewire/motu/motu-command-dsp-message-parser.c
Normal file
181
sound/firewire/motu/motu-command-dsp-message-parser.c
Normal file
@ -0,0 +1,181 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
// motu-command-dsp-message-parser.c - a part of driver for MOTU FireWire series
|
||||
//
|
||||
// Copyright (c) 2021 Takashi Sakamoto <o-takashi@sakamocchi.jp>
|
||||
|
||||
// Below models allow software to configure their DSP function by command transferred in
|
||||
// asynchronous transaction:
|
||||
// * 828 mk3 (FireWire only and Hybrid)
|
||||
// * 896 mk3 (FireWire only and Hybrid)
|
||||
// * Ultralite mk3 (FireWire only and Hybrid)
|
||||
// * Traveler mk3
|
||||
// * Track 16
|
||||
//
|
||||
// Isochronous packets from the above models includes messages to report state of hardware meter.
|
||||
|
||||
#include "motu.h"
|
||||
|
||||
enum msg_parser_state {
|
||||
INITIALIZED,
|
||||
FRAGMENT_DETECTED,
|
||||
AVAILABLE,
|
||||
};
|
||||
|
||||
struct msg_parser {
|
||||
spinlock_t lock;
|
||||
enum msg_parser_state state;
|
||||
unsigned int interval;
|
||||
unsigned int message_count;
|
||||
unsigned int fragment_pos;
|
||||
unsigned int value_index;
|
||||
u64 value;
|
||||
struct snd_firewire_motu_command_dsp_meter meter;
|
||||
};
|
||||
|
||||
int snd_motu_command_dsp_message_parser_new(struct snd_motu *motu)
|
||||
{
|
||||
struct msg_parser *parser;
|
||||
|
||||
parser = devm_kzalloc(&motu->card->card_dev, sizeof(*parser), GFP_KERNEL);
|
||||
if (!parser)
|
||||
return -ENOMEM;
|
||||
spin_lock_init(&parser->lock);
|
||||
motu->message_parser = parser;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int snd_motu_command_dsp_message_parser_init(struct snd_motu *motu, enum cip_sfc sfc)
|
||||
{
|
||||
struct msg_parser *parser = motu->message_parser;
|
||||
|
||||
parser->state = INITIALIZED;
|
||||
|
||||
// All of data blocks don't have messages with meaningful information.
|
||||
switch (sfc) {
|
||||
case CIP_SFC_176400:
|
||||
case CIP_SFC_192000:
|
||||
parser->interval = 4;
|
||||
break;
|
||||
case CIP_SFC_88200:
|
||||
case CIP_SFC_96000:
|
||||
parser->interval = 2;
|
||||
break;
|
||||
case CIP_SFC_32000:
|
||||
case CIP_SFC_44100:
|
||||
case CIP_SFC_48000:
|
||||
default:
|
||||
parser->interval = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define FRAGMENT_POS 6
|
||||
#define MIDI_BYTE_POS 7
|
||||
#define MIDI_FLAG_POS 8
|
||||
// One value of hardware meter consists of 4 messages.
|
||||
#define FRAGMENTS_PER_VALUE 4
|
||||
#define VALUES_AT_IMAGE_END 0xffffffffffffffff
|
||||
|
||||
void snd_motu_command_dsp_message_parser_parse(struct snd_motu *motu, const struct pkt_desc *descs,
|
||||
unsigned int desc_count, unsigned int data_block_quadlets)
|
||||
{
|
||||
struct msg_parser *parser = motu->message_parser;
|
||||
unsigned int interval = parser->interval;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
spin_lock_irqsave(&parser->lock, flags);
|
||||
|
||||
for (i = 0; i < desc_count; ++i) {
|
||||
const struct pkt_desc *desc = descs + i;
|
||||
__be32 *buffer = desc->ctx_payload;
|
||||
unsigned int data_blocks = desc->data_blocks;
|
||||
int j;
|
||||
|
||||
for (j = 0; j < data_blocks; ++j) {
|
||||
u8 *b = (u8 *)buffer;
|
||||
buffer += data_block_quadlets;
|
||||
|
||||
switch (parser->state) {
|
||||
case INITIALIZED:
|
||||
{
|
||||
u8 fragment = b[FRAGMENT_POS];
|
||||
|
||||
if (fragment > 0) {
|
||||
parser->value = fragment;
|
||||
parser->message_count = 1;
|
||||
parser->state = FRAGMENT_DETECTED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FRAGMENT_DETECTED:
|
||||
{
|
||||
if (parser->message_count % interval == 0) {
|
||||
u8 fragment = b[FRAGMENT_POS];
|
||||
|
||||
parser->value >>= 8;
|
||||
parser->value |= (u64)fragment << 56;
|
||||
|
||||
if (parser->value == VALUES_AT_IMAGE_END) {
|
||||
parser->state = AVAILABLE;
|
||||
parser->fragment_pos = 0;
|
||||
parser->value_index = 0;
|
||||
parser->message_count = 0;
|
||||
}
|
||||
}
|
||||
++parser->message_count;
|
||||
break;
|
||||
}
|
||||
case AVAILABLE:
|
||||
default:
|
||||
{
|
||||
if (parser->message_count % interval == 0) {
|
||||
u8 fragment = b[FRAGMENT_POS];
|
||||
|
||||
parser->value >>= 8;
|
||||
parser->value |= (u64)fragment << 56;
|
||||
++parser->fragment_pos;
|
||||
|
||||
if (parser->fragment_pos == 4) {
|
||||
// Skip the last two quadlets since they could be
|
||||
// invalid value (0xffffffff) as floating point
|
||||
// number.
|
||||
if (parser->value_index <
|
||||
SNDRV_FIREWIRE_MOTU_COMMAND_DSP_METER_COUNT - 2) {
|
||||
u32 val = (u32)(parser->value >> 32);
|
||||
parser->meter.data[parser->value_index] = val;
|
||||
}
|
||||
++parser->value_index;
|
||||
parser->fragment_pos = 0;
|
||||
}
|
||||
|
||||
if (parser->value == VALUES_AT_IMAGE_END) {
|
||||
parser->value_index = 0;
|
||||
parser->fragment_pos = 0;
|
||||
parser->message_count = 0;
|
||||
}
|
||||
}
|
||||
++parser->message_count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&parser->lock, flags);
|
||||
}
|
||||
|
||||
void snd_motu_command_dsp_message_parser_copy_meter(struct snd_motu *motu,
|
||||
struct snd_firewire_motu_command_dsp_meter *meter)
|
||||
{
|
||||
struct msg_parser *parser = motu->message_parser;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&parser->lock, flags);
|
||||
memcpy(meter, &parser->meter, sizeof(*meter));
|
||||
spin_unlock_irqrestore(&parser->lock, flags);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user