mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-10-26 10:57:38 +08:00
Merge tag 'sound-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"The AI flood continues, which brought us a fairly busy development
cycle again with changes spread across the subsystem, ranging from
(lots of) core hardening to new platforms and codecs.
Here are some highlights.
ALSA core:
- PCM: race fixes around channel-map controls, draining/unlink, drop
sync-stop handling, and DMA buffer delay sync
- Compress-offload: state and geometry validations, buffer leak fix,
and stream/card lifetime management
- Jack: module pinning during debugfs access, control removal race
fix, and early injection exposure
- Timer & sequencer: module pinning for user timers, RCU grace period
wait on port deletion, UMP bounds fixes
- Mark OSS sequencer emulation as deprecated
- RawMIDI: proper disconnect handling and input work drain cleanup
- Control: fixes for vmaster racy setups and control callback
serialization, UAF fix on card disconnect
ASoC core:
- Continued framework refactoring, deployment of
auto_selectable_formats across codecs and platform DAIs
- Generic card cleanup: free jack GPIOs on card remove for
simple-card and audio-graph-card variants
- SDCA improvements: SimpleJack function type support, library
helpers, and non-ACPI build support
- Conversion of deprecated DMA API calls
ASoC SOF:
- Support for compressed audio playback on SOF IPC4 with Intel TGL+
- AMD ACP 7.B / 7.F SoundWire and PDM controller support, ASP
carveout firmware loading
- Function topology support for Intel I2S machines
ASoC platforms & codecs:
- Qualcomm: New QAIF driver for Shikra platform, WCD9378 SDCA codec,
Nord Ride/RRD and Motorola Edge 30 boards, LPASS macro cache
converted to maple tree
- New codec drivers: ESS ES9039Q2M, Nuvoton NAU83G60 amplifier,
Senary SN624x SoundWire SDCA codec
- MediaTek / Airoha: New Airoha AN7581 AFE and WM8960 machine
drivers, extensive clock and error-handling cleanups across
MediaTek SoCs
- NVIDIA Tegra: WM8994 machine driver and CS35L45 MDSYNC support
- Realtek: RT766/RT767, RT721_U, RT718 variants, RT712 GPIO LED
control
- Cirrus Logic: CS35L45 MDSYNC support, CS35L56 regmap default tests
- TI: TAS2573 DSP support in TAS2781, TAS2783 SoundWire fixes
- Everest Semi: ES8326 standby / HPF controls, ES8389 / ES8375 resume
fixes
- Removal of obsolete ST-Ericsson Ux500 MOP500 machine driver
HD-audio:
- ACPI controller runtime PM suspend/resume support
- Controller shutdown and unbind race fixes for unsol events and jack
polling
- HDMI: High Bit Rate (HBR) audio capability enabled, ELD proc and
converter bounds checks
- AW88399 side codec SSID-specific firmware naming and Lenovo Legion
R9000P enablement
- Realtek / Conexant / Cirrus / TI quirks for numerous laptops
(Lenovo, ASUS, HP, Acer, HONOR, Minisforum, MSI, etc.)
- Creative CA0132 Sound BlasterX AE-5 external RGB LED strip support
USB-audio:
- Dedicated mixer driver for Audient EVO4
- Native Instruments Kore controller LCD support and keymap fix
- Pioneer DJ DDJ-SZ and Roland (OCTA-CAPTURE / QUAD-CAPTURE
multirate, TD-11) support
- UAC2/3 mixer unit matrix evaluation and bounds checking
- Hardening for LINE6 and caiaq drivers against malformed packets and
races
- Device-specific quirks for PreSonus, TASCAM, Logitech, Mayflower,
MOONDROP, Yamaha, etc.
Misc:
- Auto-cleanup conversion for snd_card_free() and devres migration
across dozens of legacy PCI, ISA, and Sparc drivers
- ALSA loopback (aloop) timer lifecycle fixes and new aloop selftest
- pcmtest driver fixes and kselftest updates"
* tag 'sound-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (924 commits)
ALSA: hda/realtek: Add mute and mic-mute LEDs for HP ENVY 16 (103c:8be5)
selftests: ALSA: pcmtest: Compare all captured bytes in ni_capture
ALSA: usb-audio: Use strscpy() in append_ctl_name()
ALSA: caiaq: Use strscpy() in snd_usb_caiaq_input_init()
ALSA: hiface: Use scnprintf() in hiface_chip_create()
selftests/alsa: Check the aloop PCM Slave controls for a matching playback
ALSA: aloop: Update the PCM Slave controls for a matching playback
selftests: ALSA: pcmtest: Make room for the longest fill pattern
selftests: ALSA: pcmtest: Check the frame count of each transfer
ALSA: hda/realtek: Fix speakers on COLORFUL L1 Plus
ALSA: hda/realtek: enable AW88399 on Lenovo Legion R9000P AFR10
ALSA: line6: Handle period elapsed calls outside the locks
ALSA: emux: Stop voices before freeing zones in all cases
ALSA: emux: Fix UAF of soundfont zones at note-on
ALSA: mtpav: restore negation dropped in guard() conversion
ALSA: compress: reject restarting an ACTIVE task via origin_seqno
ALSA: compress: add missing OPEN-state gate to SET_METADATA
ALSA: compress: reject buffer geometry change on gapless next_track
ALSA: compress: fix buffer leak on failed SET_PARAMS
ALSA: hda/realtek: Enable jack detection on Minisforum AI X1
...
This commit is contained in:
commit
75c1cb8178
832 files changed
+37044
-6793
No files matched your search
@@ -52,11 +52,11 @@ examples:
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
audio-codec@3c {
|
||||
compatible = "adi,adau1372";
|
||||
reg = <0x3c>;
|
||||
#sound-dai-cells = <0>;
|
||||
clock-names = "mclk";
|
||||
clocks = <&adau1372z_xtal>;
|
||||
compatible = "adi,adau1372";
|
||||
reg = <0x3c>;
|
||||
#sound-dai-cells = <0>;
|
||||
clock-names = "mclk";
|
||||
clocks = <&adau1372z_xtal>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -68,20 +68,20 @@ examples:
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
adau7118_codec: audio-codec@14 {
|
||||
compatible = "adi,adau7118";
|
||||
reg = <0x14>;
|
||||
#sound-dai-cells = <0>;
|
||||
iovdd-supply = <&supply>;
|
||||
dvdd-supply = <&supply>;
|
||||
adi,pdm-clk-map = <1 1 0 0>;
|
||||
adi,decimation-ratio = <16>;
|
||||
compatible = "adi,adau7118";
|
||||
reg = <0x14>;
|
||||
#sound-dai-cells = <0>;
|
||||
iovdd-supply = <&supply>;
|
||||
dvdd-supply = <&supply>;
|
||||
adi,pdm-clk-map = <1 1 0 0>;
|
||||
adi,decimation-ratio = <16>;
|
||||
};
|
||||
};
|
||||
|
||||
/* example with hw standalone mode */
|
||||
adau7118_codec_hw: adau7118-codec-hw {
|
||||
compatible = "adi,adau7118";
|
||||
#sound-dai-cells = <0>;
|
||||
iovdd-supply = <&supply>;
|
||||
dvdd-supply = <&supply>;
|
||||
compatible = "adi,adau7118";
|
||||
#sound-dai-cells = <0>;
|
||||
iovdd-supply = <&supply>;
|
||||
dvdd-supply = <&supply>;
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/airoha,an7581-afe.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Airoha AFE PCM controller for AN7581
|
||||
|
||||
maintainers:
|
||||
- Christian Marangi <ansuelsmth@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: airoha,an7581-afe
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
afe@1fbe2200 {
|
||||
compatible = "airoha,an7581-afe";
|
||||
reg = <0x1fbe2200 0x9000>;
|
||||
|
||||
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
...
|
||||
@@ -0,0 +1,71 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/airoha,an7581-wm8960.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Airoha AN7581 sound card with WM8960 codec
|
||||
|
||||
maintainers:
|
||||
- Christian Marangi <ansuelsmth@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: sound-card-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: airoha,an7581-wm8960-sound
|
||||
|
||||
platform:
|
||||
type: object
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
sound-dai:
|
||||
items:
|
||||
- description: The phandle of AN7581 platform.
|
||||
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
codec:
|
||||
type: object
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
sound-dai:
|
||||
items:
|
||||
- description: The phandle of WM8960 i2c codec.
|
||||
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- audio-routing
|
||||
- platform
|
||||
- codec
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sound {
|
||||
compatible = "airoha,an7581-wm8960-sound";
|
||||
model = "an7581-wm8960";
|
||||
audio-routing =
|
||||
"Headphone", "HP_L",
|
||||
"Headphone", "HP_R",
|
||||
"LINPUT1", "AMIC",
|
||||
"RINPUT1", "AMIC";
|
||||
|
||||
platform {
|
||||
sound-dai = <&afe>;
|
||||
};
|
||||
|
||||
codec {
|
||||
sound-dai = <&wm8960>;
|
||||
};
|
||||
};
|
||||
@@ -94,20 +94,20 @@ examples:
|
||||
audio-routing = "I2S ENCODER I2S IN", "I2S FIFO Playback";
|
||||
|
||||
dai-link-0 {
|
||||
sound-dai = <&i2s_fifo>;
|
||||
sound-dai = <&i2s_fifo>;
|
||||
};
|
||||
|
||||
dai-link-1 {
|
||||
sound-dai = <&i2s_encoder>;
|
||||
dai-format = "i2s";
|
||||
mclk-fs = <256>;
|
||||
sound-dai = <&i2s_encoder>;
|
||||
dai-format = "i2s";
|
||||
mclk-fs = <256>;
|
||||
|
||||
codec-0 {
|
||||
sound-dai = <&codec0>;
|
||||
};
|
||||
codec-0 {
|
||||
sound-dai = <&codec0>;
|
||||
};
|
||||
|
||||
codec-1 {
|
||||
sound-dai = <&codec1>;
|
||||
};
|
||||
codec-1 {
|
||||
sound-dai = <&codec1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -34,6 +34,12 @@ properties:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
powerdown-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
GPIO connected to the 'PDN' pin, if any. Needs to be set low to
|
||||
power down the codec, hence the GPIO must be GPIO_ACTIVE_LOW.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@@ -42,6 +48,8 @@ unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@@ -49,14 +57,16 @@ examples:
|
||||
compatible = "asahi-kasei,ak4619";
|
||||
reg = <0x10>;
|
||||
|
||||
powerdown-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
|
||||
|
||||
clocks = <&rcar_sound>;
|
||||
clock-names = "mclk";
|
||||
|
||||
#sound-dai-cells = <0>;
|
||||
port {
|
||||
ak4619_endpoint: endpoint {
|
||||
remote-endpoint = <&rsnd_endpoint>;
|
||||
};
|
||||
ak4619_endpoint: endpoint {
|
||||
remote-endpoint = <&rsnd_endpoint>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -39,6 +39,7 @@ definitions:
|
||||
allOf:
|
||||
- $ref: /schemas/graph.yaml#/$defs/endpoint-base
|
||||
- $ref: /schemas/sound/dai-params.yaml#
|
||||
- $ref: /schemas/sound/tdm-slot.yaml#
|
||||
properties:
|
||||
mclk-fs:
|
||||
$ref: simple-card.yaml#/definitions/mclk-fs
|
||||
@@ -48,6 +49,9 @@ definitions:
|
||||
bitclock-inversion:
|
||||
description: dai-link uses bit clock inversion
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
continuous-clock:
|
||||
description: dai-link bit clock runs continuously rather than gated
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
frame-master:
|
||||
description: Indicates dai-link frame master.
|
||||
oneOf:
|
||||
@@ -82,12 +86,6 @@ definitions:
|
||||
- msb
|
||||
- lsb
|
||||
|
||||
dai-tdm-slot-num:
|
||||
description: Number of slots in use.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
dai-tdm-slot-width:
|
||||
description: Width in bits for each slot.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
dai-tdm-slot-width-map:
|
||||
description: Mapping of sample widths to slot widths. For hardware
|
||||
that cannot support a fixed slot width or a slot width always
|
||||
|
||||
@@ -53,6 +53,76 @@ properties:
|
||||
maximum: 3
|
||||
default: 2
|
||||
|
||||
cirrus,sync-lsw-txid:
|
||||
description:
|
||||
Transmitter ID to use for long software (LSW) data packets
|
||||
on the SYNC bus.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
default: 0
|
||||
|
||||
cirrus,sync-sw-txid:
|
||||
description:
|
||||
Transmitter ID to use for short software (SW) data packets
|
||||
on the SYNC bus.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
default: 0
|
||||
|
||||
cirrus,ldpm-group1-boost-select:
|
||||
type: boolean
|
||||
description:
|
||||
When in a valid group 1 level dependent power management (LDPM) state
|
||||
the integrated boost converter will enter the configured low power mode.
|
||||
|
||||
cirrus,boost-low-power-mode:
|
||||
description:
|
||||
Configures the integrated boost converter reaction to a low power mode
|
||||
request.
|
||||
0 = No reaction
|
||||
1 = Force boost DCM low power mode
|
||||
2 = Force boost static bypass
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
default: 2
|
||||
enum:
|
||||
- 0
|
||||
- 1
|
||||
- 2
|
||||
|
||||
cirrus,ldpm-group1-amp-select:
|
||||
type: boolean
|
||||
description:
|
||||
When in a valid group 1 level dependent power management (LDPM) state
|
||||
the amplifier will enter the configured low power mode.
|
||||
|
||||
cirrus,amplifier-low-power-mode:
|
||||
description:
|
||||
Configures the amplifier output stage reaction to a low power mode
|
||||
request.
|
||||
0 = Stop output switching (noise gate mode)
|
||||
1 = Noise floor reduction mode
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
default: 1
|
||||
enum:
|
||||
- 0
|
||||
- 1
|
||||
|
||||
cirrus,ldpm-group2-vmon-select:
|
||||
type: boolean
|
||||
description:
|
||||
When in a valid group 2 level dependent power management (LDPM) state
|
||||
the voltage monitor (VMON) circuit is put into a low power operational
|
||||
state.
|
||||
|
||||
cirrus,ldpm-group2-imon-select:
|
||||
type: boolean
|
||||
description:
|
||||
When in a valid group 2 level dependent power management (LDPM) state
|
||||
the current monitor (IMON) circuit is put into a low power operational
|
||||
state.
|
||||
|
||||
patternProperties:
|
||||
"^cirrus,gpio-ctrl[1-3]$":
|
||||
description:
|
||||
@@ -121,6 +191,30 @@ patternProperties:
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
default: 0
|
||||
|
||||
"^cirrus,ldpm-group[1-2]-pcm-threshold-db$":
|
||||
description:
|
||||
Amplifier level dependent power management (LDPM) threshold. Input
|
||||
referred threshold of the PCM audio signal in which the level is low
|
||||
enough for the LDPM group to engage after entry delay. A value of dB
|
||||
-2147483648 is assumed to mean true zero data with an LSB dither.
|
||||
$ref: /schemas/types.yaml#/definitions/int32-array
|
||||
minItems: 1
|
||||
maxItems: 1
|
||||
items:
|
||||
enum: [-2147483648, -102, -96, -90, -84, -78, -72, -66]
|
||||
|
||||
"^cirrus,ldpm-group[1-2]-delay-ms$":
|
||||
description:
|
||||
Amplifier level dependent power management (LDPM) state entry delay.
|
||||
Time that the incoming audio signal must be below the PCM threshold
|
||||
before the LDPM group engages.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 1
|
||||
items:
|
||||
enum: [5, 10, 25, 50, 100, 250, 500, 1000]
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@@ -135,25 +229,37 @@ examples:
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cs35l45: cs35l45@2 {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "cirrus,cs35l45";
|
||||
reg = <2>;
|
||||
spi-max-frequency = <5000000>;
|
||||
vdd-a-supply = <&dummy_vreg>;
|
||||
vdd-batt-supply = <&dummy_vreg>;
|
||||
reset-gpios = <&gpio 110 0>;
|
||||
cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED |
|
||||
CS35L45_ASP_TX_HIZ_DISABLED)>;
|
||||
cirrus,gpio-ctrl1 {
|
||||
gpio-ctrl = <0x2>;
|
||||
};
|
||||
cirrus,gpio-ctrl2 {
|
||||
gpio-ctrl = <0x2>;
|
||||
};
|
||||
cirrus,gpio-ctrl3 {
|
||||
gpio-ctrl = <0x1>;
|
||||
gpio-dir = <0x1>;
|
||||
};
|
||||
cs35l45: audio-codec@2 {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "cirrus,cs35l45";
|
||||
reg = <2>;
|
||||
spi-max-frequency = <5000000>;
|
||||
vdd-a-supply = <&dummy_vreg>;
|
||||
vdd-batt-supply = <&dummy_vreg>;
|
||||
reset-gpios = <&gpio 110 0>;
|
||||
cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED |
|
||||
CS35L45_ASP_TX_HIZ_DISABLED)>;
|
||||
cirrus,sync-lsw-txid = <0x1>;
|
||||
cirrus,sync-sw-txid = <0x1>;
|
||||
cirrus,ldpm-group1-pcm-threshold-db = <(-66)>;
|
||||
cirrus,ldpm-group1-delay-ms = <500>;
|
||||
cirrus,ldpm-group1-boost-select;
|
||||
cirrus,boost-low-power-mode = <CS35L45_BST_LPMODE_DCM_MODE>;
|
||||
cirrus,ldpm-group1-amp-select;
|
||||
cirrus,amplifier-low-power-mode = <CS35L45_AMP_LPMODE_NFR_MODE>;
|
||||
cirrus,ldpm-group2-pcm-threshold-db = <(-102)>;
|
||||
cirrus,ldpm-group2-delay-ms = <1000>;
|
||||
cirrus,ldpm-group2-vmon-select;
|
||||
cirrus,ldpm-group2-imon-select;
|
||||
cirrus,gpio-ctrl1 {
|
||||
gpio-ctrl = <0x2>;
|
||||
};
|
||||
cirrus,gpio-ctrl2 {
|
||||
gpio-ctrl = <0x2>;
|
||||
};
|
||||
cirrus,gpio-ctrl3 {
|
||||
gpio-ctrl = <0x1>;
|
||||
gpio-dir = <0x1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -49,11 +49,11 @@ unevaluatedProperties: false
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
codec@48 {
|
||||
compatible = "cirrus,cs4270";
|
||||
reg = <0x48>;
|
||||
};
|
||||
codec@48 {
|
||||
compatible = "cirrus,cs4270";
|
||||
reg = <0x48>;
|
||||
};
|
||||
};
|
||||
@@ -199,28 +199,28 @@ examples:
|
||||
- |
|
||||
#include <dt-bindings/sound/cs42l42.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cs42l42: cs42l42@48 {
|
||||
compatible = "cirrus,cs42l42";
|
||||
reg = <0x48>;
|
||||
VA-supply = <&dummy_vreg>;
|
||||
VP-supply = <&dummy_vreg>;
|
||||
VCP-supply = <&dummy_vreg>;
|
||||
VD_FILT-supply = <&dummy_vreg>;
|
||||
VL-supply = <&dummy_vreg>;
|
||||
audio-codec@48 {
|
||||
compatible = "cirrus,cs42l42";
|
||||
reg = <0x48>;
|
||||
VA-supply = <&dummy_vreg>;
|
||||
VP-supply = <&dummy_vreg>;
|
||||
VCP-supply = <&dummy_vreg>;
|
||||
VD_FILT-supply = <&dummy_vreg>;
|
||||
VL-supply = <&dummy_vreg>;
|
||||
|
||||
reset-gpios = <&axi_gpio_0 1 0>;
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <55 8>;
|
||||
reset-gpios = <&axi_gpio_0 1 0>;
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <55 8>;
|
||||
|
||||
cirrus,ts-inv = <CS42L42_TS_INV_DIS>;
|
||||
cirrus,ts-dbnc-rise = <CS42L42_TS_DBNCE_1000>;
|
||||
cirrus,ts-dbnc-fall = <CS42L42_TS_DBNCE_0>;
|
||||
cirrus,btn-det-init-dbnce = <100>;
|
||||
cirrus,btn-det-event-dbnce = <10>;
|
||||
cirrus,bias-lvls = <0x0F 0x08 0x04 0x01>;
|
||||
cirrus,hs-bias-ramp-rate = <CS42L42_HSBIAS_RAMP_SLOW>;
|
||||
};
|
||||
cirrus,ts-inv = <CS42L42_TS_INV_DIS>;
|
||||
cirrus,ts-dbnc-rise = <CS42L42_TS_DBNCE_1000>;
|
||||
cirrus,ts-dbnc-fall = <CS42L42_TS_DBNCE_0>;
|
||||
cirrus,btn-det-init-dbnce = <100>;
|
||||
cirrus,btn-det-event-dbnce = <10>;
|
||||
cirrus,bias-lvls = <0x0F 0x08 0x04 0x01>;
|
||||
cirrus,hs-bias-ramp-rate = <CS42L42_HSBIAS_RAMP_SLOW>;
|
||||
};
|
||||
};
|
||||
@@ -43,14 +43,14 @@ examples:
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
jack_codec: codec@4b {
|
||||
compatible = "cirrus,cs42l84";
|
||||
reg = <0x4b>;
|
||||
reset-gpios = <&pinctrl_nub 4 GPIO_ACTIVE_LOW>;
|
||||
interrupts-extended = <&pinctrl_ap 180 IRQ_TYPE_LEVEL_LOW>;
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
jack_codec: codec@4b {
|
||||
compatible = "cirrus,cs42l84";
|
||||
reg = <0x4b>;
|
||||
reset-gpios = <&pinctrl_nub 4 GPIO_ACTIVE_LOW>;
|
||||
interrupts-extended = <&pinctrl_ap 180 IRQ_TYPE_LEVEL_LOW>;
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
};
|
||||
@@ -75,37 +75,37 @@ unevaluatedProperties: false
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
codec@48 {
|
||||
compatible = "cirrus,cs42888";
|
||||
reg = <0x48>;
|
||||
clocks = <&codec_mclk 0>;
|
||||
clock-names = "mclk";
|
||||
VA-supply = <®_audio>;
|
||||
VD-supply = <®_audio>;
|
||||
VLS-supply = <®_audio>;
|
||||
VLC-supply = <®_audio>;
|
||||
reset-gpios = <&gpio 1>;
|
||||
};
|
||||
codec@48 {
|
||||
compatible = "cirrus,cs42888";
|
||||
reg = <0x48>;
|
||||
clocks = <&codec_mclk 0>;
|
||||
clock-names = "mclk";
|
||||
VA-supply = <®_audio>;
|
||||
VD-supply = <®_audio>;
|
||||
VLS-supply = <®_audio>;
|
||||
VLC-supply = <®_audio>;
|
||||
reset-gpios = <&gpio 1>;
|
||||
};
|
||||
};
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
cs-gpios = <&gpio 8 0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
cs-gpios = <&gpio 8 0>;
|
||||
|
||||
codec@0 {
|
||||
compatible = "cirrus,cs42888";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <6000000>;
|
||||
clocks = <&codec_mclk 0>;
|
||||
clock-names = "mclk";
|
||||
VA-supply = <®_audio>;
|
||||
VD-supply = <®_audio>;
|
||||
VLS-supply = <®_audio>;
|
||||
VLC-supply = <®_audio>;
|
||||
reset-gpios = <&gpio 1>;
|
||||
};
|
||||
codec@0 {
|
||||
compatible = "cirrus,cs42888";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <6000000>;
|
||||
clocks = <&codec_mclk 0>;
|
||||
clock-names = "mclk";
|
||||
VA-supply = <®_audio>;
|
||||
VD-supply = <®_audio>;
|
||||
VLS-supply = <®_audio>;
|
||||
VLC-supply = <®_audio>;
|
||||
reset-gpios = <&gpio 1>;
|
||||
};
|
||||
};
|
||||
@@ -1,49 +0,0 @@
|
||||
* Texas Instruments SoC audio setups with TLV320AIC3X Codec
|
||||
|
||||
Required properties:
|
||||
- compatible : "ti,da830-evm-audio" : forDM365/DA8xx/OMAPL1x/AM33xx
|
||||
- ti,model : The user-visible name of this sound complex.
|
||||
- ti,audio-codec : The phandle of the TLV320AIC3x audio codec
|
||||
- ti,mcasp-controller : The phandle of the McASP controller
|
||||
- ti,audio-routing : A list of the connections between audio components.
|
||||
Each entry is a pair of strings, the first being the connection's sink,
|
||||
the second being the connection's source. Valid names for sources and
|
||||
sinks are the codec's pins, and the jacks on the board:
|
||||
|
||||
Optional properties:
|
||||
- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec.
|
||||
- clocks : Reference to the master clock
|
||||
- clock-names : The clock should be named "mclk"
|
||||
- Either codec-clock-rate or the codec-clock reference has to be defined. If
|
||||
the both are defined the driver attempts to set referenced clock to the
|
||||
defined rate and takes the rate from the clock reference.
|
||||
|
||||
Board connectors:
|
||||
|
||||
* Headphone Jack
|
||||
* Line Out
|
||||
* Mic Jack
|
||||
* Line In
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "ti,da830-evm-audio";
|
||||
ti,model = "DA830 EVM";
|
||||
ti,audio-codec = <&tlv320aic3x>;
|
||||
ti,mcasp-controller = <&mcasp1>;
|
||||
ti,codec-clock-rate = <12000000>;
|
||||
ti,audio-routing =
|
||||
"Headphone Jack", "HPLOUT",
|
||||
"Headphone Jack", "HPROUT",
|
||||
"Line Out", "LLOUT",
|
||||
"Line Out", "RLOUT",
|
||||
"MIC3L", "Mic Bias 2V",
|
||||
"MIC3R", "Mic Bias 2V",
|
||||
"Mic Bias 2V", "Mic Jack",
|
||||
"LINE1L", "Line In",
|
||||
"LINE2L", "Line In",
|
||||
"LINE1R", "Line In",
|
||||
"LINE2R", "Line In";
|
||||
};
|
||||
@@ -195,44 +195,44 @@ examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
codec: da7219@1a {
|
||||
compatible = "dlg,da7219";
|
||||
reg = <0x1a>;
|
||||
codec: audio-codec@1a {
|
||||
compatible = "dlg,da7219";
|
||||
reg = <0x1a>;
|
||||
|
||||
interrupt-parent = <&gpio6>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&gpio6>;
|
||||
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
VDD-supply = <&vdd_reg>;
|
||||
VDDMIC-supply = <&vddmic_reg>;
|
||||
VDDIO-supply = <&vddio_reg>;
|
||||
VDD-supply = <&vdd_reg>;
|
||||
VDDMIC-supply = <&vddmic_reg>;
|
||||
VDDIO-supply = <&vddio_reg>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
clock-output-names = "da7219-dai-wclk", "da7219-dai-bclk";
|
||||
#clock-cells = <1>;
|
||||
clock-output-names = "da7219-dai-wclk", "da7219-dai-bclk";
|
||||
|
||||
clocks = <&clks 201>;
|
||||
clock-names = "mclk";
|
||||
clocks = <&clks 201>;
|
||||
clock-names = "mclk";
|
||||
|
||||
dlg,micbias-lvl = <2600>;
|
||||
dlg,mic-amp-in-sel = "diff";
|
||||
dlg,micbias-lvl = <2600>;
|
||||
dlg,mic-amp-in-sel = "diff";
|
||||
|
||||
da7219_aad {
|
||||
dlg,btn-cfg = <50>;
|
||||
dlg,mic-det-thr = <500>;
|
||||
dlg,jack-ins-deb = <20>;
|
||||
dlg,jack-ins-det-pty = "low";
|
||||
dlg,jack-det-rate = "32_64";
|
||||
dlg,jack-rem-deb = <1>;
|
||||
da7219_aad {
|
||||
dlg,btn-cfg = <50>;
|
||||
dlg,mic-det-thr = <500>;
|
||||
dlg,jack-ins-deb = <20>;
|
||||
dlg,jack-ins-det-pty = "low";
|
||||
dlg,jack-det-rate = "32_64";
|
||||
dlg,jack-rem-deb = <1>;
|
||||
|
||||
dlg,a-d-btn-thr = <0xa>;
|
||||
dlg,d-b-btn-thr = <0x16>;
|
||||
dlg,b-c-btn-thr = <0x21>;
|
||||
dlg,c-mic-btn-thr = <0x3E>;
|
||||
dlg,a-d-btn-thr = <0xa>;
|
||||
dlg,d-b-btn-thr = <0x16>;
|
||||
dlg,b-c-btn-thr = <0x21>;
|
||||
dlg,c-mic-btn-thr = <0x3E>;
|
||||
|
||||
dlg,btn-avg = <4>;
|
||||
dlg,adc-1bit-rpt = <1>;
|
||||
};
|
||||
};
|
||||
dlg,btn-avg = <4>;
|
||||
dlg,adc-1bit-rpt = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,94 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/esstech,es9039q2m.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ESS Technology ES9039Q2M audio DAC
|
||||
|
||||
maintainers:
|
||||
- Karl Asseily <karl@asseily.com>
|
||||
|
||||
description:
|
||||
The ES9039Q2M is a 32-bit two-channel audio DAC supporting PCM to 768 kHz,
|
||||
DSD64 to DSD1024, DoP and S/PDIF. It is controlled over I2C or SPI when the
|
||||
MODE pin selects software mode; this binding covers the I2C interface. The
|
||||
part contains an asynchronous sample rate converter, so the system clock need
|
||||
not be synchronous with the audio bit or frame clocks.
|
||||
|
||||
The four supplies are all nominally 3.3V and the datasheet requires a set
|
||||
order - AVDD first, then VCCA about 200us later, then AVCC_DAC1 and
|
||||
AVCC_DAC2, and the reverse on the way down. DVDD, the part's 1.2V rail, is
|
||||
on-chip and needs only its decoupling capacitor - it is not a supply input
|
||||
and has no property here.
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: esstech,es9039q2m
|
||||
|
||||
reg:
|
||||
description:
|
||||
I2C address, selected by the ADDR0 and ADDR1 pins - 0x48, 0x49, 0x4a or
|
||||
0x4b for GND/GND, GND/AVDD, AVDD/GND and AVDD/AVDD respectively.
|
||||
enum: [ 0x48, 0x49, 0x4a, 0x4b ]
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: mclk
|
||||
|
||||
avdd-supply:
|
||||
description:
|
||||
3.3V supply for the part's internal digital regulator, pin AVDD. It is
|
||||
the first rail up and the last down, per the ordering described above.
|
||||
|
||||
vcca-supply:
|
||||
description: 3.3V analogue supply, pin VCCA.
|
||||
|
||||
avcc-dac1-supply:
|
||||
description:
|
||||
3.3V reference supply for the channel 1 analogue output stage, pin
|
||||
AVCC_DAC1. The datasheet allows this rail to move by up to 15% where a
|
||||
calibrating regulator tracks the DAC's output impedance.
|
||||
|
||||
avcc-dac2-supply:
|
||||
description:
|
||||
3.3V reference supply for the channel 2 analogue output stage, pin
|
||||
AVCC_DAC2, with the same 15% allowance as channel 1.
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- avdd-supply
|
||||
- vcca-supply
|
||||
- avcc-dac1-supply
|
||||
- avcc-dac2-supply
|
||||
- "#sound-dai-cells"
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
audio-codec@48 {
|
||||
compatible = "esstech,es9039q2m";
|
||||
reg = <0x48>;
|
||||
#sound-dai-cells = <0>;
|
||||
clocks = <&dac_mclk>;
|
||||
clock-names = "mclk";
|
||||
avdd-supply = <&dac_3v3>;
|
||||
vcca-supply = <&dac_3v3>;
|
||||
avcc-dac1-supply = <&dac_avcc1>;
|
||||
avcc-dac2-supply = <&dac_avcc2>;
|
||||
};
|
||||
};
|
||||
@@ -84,6 +84,11 @@ properties:
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
everest,jack-detect-inverted:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
Defined to invert the jack detection.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -63,7 +63,7 @@ properties:
|
||||
a. Register initialization settings
|
||||
b. DSP effect parameters
|
||||
c. Multi-scene sound effect configurations(optional)
|
||||
It's gernerated by FourSemi's tuning tool.
|
||||
It's generated by FourSemi's tuning tool.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
@@ -55,6 +55,14 @@ properties:
|
||||
- const: imx/easrc/easrc-imx8mn.bin
|
||||
description: The coefficient table for the filters
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
patternProperties:
|
||||
"^port@[0-3]$":
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: port for an independent conversion path
|
||||
|
||||
fsl,asrc-rate:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 8000
|
||||
@@ -106,4 +114,41 @@ examples:
|
||||
firmware-name = "imx/easrc/easrc-imx8mn.bin";
|
||||
fsl,asrc-rate = <8000>;
|
||||
fsl,asrc-format = <2>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
playback-only;
|
||||
endpoint {
|
||||
remote-endpoint = <&fe00_ep>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
playback-only;
|
||||
endpoint {
|
||||
remote-endpoint = <&fe01_ep>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
capture-only;
|
||||
endpoint {
|
||||
remote-endpoint = <&fe02_ep>;
|
||||
};
|
||||
};
|
||||
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
capture-only;
|
||||
endpoint {
|
||||
remote-endpoint = <&fe03_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -78,9 +78,19 @@ properties:
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
patternProperties:
|
||||
"^port@[0-2]$":
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: port for an independent conversion path
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
deprecated: true
|
||||
description: deprecated, use ports instead
|
||||
|
||||
fsl,asrc-rate:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
@@ -125,6 +135,10 @@ required:
|
||||
- fsl,asrc-width
|
||||
|
||||
allOf:
|
||||
- not:
|
||||
required:
|
||||
- port
|
||||
- ports
|
||||
- $ref: dai-common.yaml#
|
||||
- if:
|
||||
properties:
|
||||
@@ -180,11 +194,32 @@ examples:
|
||||
fsl,asrc-rate = <48000>;
|
||||
fsl,asrc-width = <16>;
|
||||
|
||||
port {
|
||||
playback-only;
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
asrc_endpoint: endpoint {
|
||||
remote-endpoint = <&fe00_ep>;
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
playback-only;
|
||||
endpoint {
|
||||
remote-endpoint = <&fe00_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
capture-only;
|
||||
endpoint {
|
||||
remote-endpoint = <&fe01_ep>;
|
||||
};
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
capture-only;
|
||||
endpoint {
|
||||
remote-endpoint = <&fe02_ep>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -260,13 +260,13 @@ examples:
|
||||
playback-only;
|
||||
|
||||
sai1_endpoint0: endpoint {
|
||||
dai-tdm-slot-num = <8>;
|
||||
dai-tdm-slot-width = <32>;
|
||||
dai-tdm-slot-width-map = <32 8 32>;
|
||||
dai-format = "dsp_a";
|
||||
bitclock-master;
|
||||
frame-master;
|
||||
remote-endpoint = <&mcodec01_ep>;
|
||||
dai-tdm-slot-num = <8>;
|
||||
dai-tdm-slot-width = <32>;
|
||||
dai-tdm-slot-width-map = <32 8 32>;
|
||||
dai-format = "dsp_a";
|
||||
bitclock-master;
|
||||
frame-master;
|
||||
remote-endpoint = <&mcodec01_ep>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -48,6 +48,10 @@ properties:
|
||||
The dai cell indexes reference the following interfaces:
|
||||
0: S2 interface
|
||||
|
||||
ports:
|
||||
$ref: audio-graph-port.yaml#/definitions/ports
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -105,10 +105,10 @@ examples:
|
||||
format = "i2s";
|
||||
fsl,mclk-equal-bclk;
|
||||
cpu {
|
||||
sound-dai = <&sai1>;
|
||||
sound-dai = <&sai1>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&ak4458_1>, <&ak4458_2>;
|
||||
sound-dai = <&ak4458_1>, <&ak4458_2>;
|
||||
};
|
||||
};
|
||||
fe-dai-link {
|
||||
|
||||
@@ -101,10 +101,10 @@ examples:
|
||||
mux-ssi1 {
|
||||
fsl,audmux-port = <0>;
|
||||
fsl,port-config = <
|
||||
IMX_AUDMUX_V2_PTCR_SYN 0
|
||||
IMX_AUDMUX_V2_PTCR_TFSEL(2) 0
|
||||
IMX_AUDMUX_V2_PTCR_TCSEL(2) 0
|
||||
IMX_AUDMUX_V2_PTCR_TFSDIR 0
|
||||
IMX_AUDMUX_V2_PTCR_SYN 0
|
||||
IMX_AUDMUX_V2_PTCR_TFSEL(2) 0
|
||||
IMX_AUDMUX_V2_PTCR_TCSEL(2) 0
|
||||
IMX_AUDMUX_V2_PTCR_TFSDIR 0
|
||||
IMX_AUDMUX_V2_PTCR_TCLKDIR IMX_AUDMUX_V2_PDCR_RXDSEL(2)
|
||||
>;
|
||||
};
|
||||
|
||||
@@ -42,10 +42,10 @@ examples:
|
||||
compatible = "invensense,ics43432";
|
||||
|
||||
port {
|
||||
endpoint {
|
||||
remote-endpoint = <&i2s1_endpoint>;
|
||||
dai-format = "i2s";
|
||||
};
|
||||
endpoint {
|
||||
remote-endpoint = <&i2s1_endpoint>;
|
||||
dai-format = "i2s";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
@@ -79,7 +79,7 @@ examples:
|
||||
sound-dai = <&i2s>;
|
||||
};
|
||||
codec {
|
||||
sound-dai = <&es8323>;
|
||||
sound-dai = <&es8323>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -104,6 +104,6 @@ examples:
|
||||
};
|
||||
|
||||
codec {
|
||||
sound-dai = <&es8388>;
|
||||
sound-dai = <&es8388>;
|
||||
};
|
||||
};
|
||||
@@ -32,7 +32,7 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 34
|
||||
minItems: 33
|
||||
items:
|
||||
- description: audio infra sys clock
|
||||
- description: top audio mux 1
|
||||
@@ -74,7 +74,7 @@ properties:
|
||||
- description: audio APLL root pd
|
||||
|
||||
clock-names:
|
||||
minItems: 34
|
||||
minItems: 33
|
||||
items:
|
||||
- const: infra_sys_audio_clk
|
||||
- const: top_audio_mux1_sel
|
||||
@@ -132,8 +132,10 @@ allOf:
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 34
|
||||
minItems: 33
|
||||
maxItems: 33
|
||||
clock-names:
|
||||
maxItems: 34
|
||||
minItems: 33
|
||||
maxItems: 33
|
||||
|
||||
additionalProperties: false
|
||||
@@ -84,15 +84,15 @@ examples:
|
||||
<&topckgen CLK_TOP_I2S2_M_SEL>,
|
||||
<&topckgen CLK_TOP_I2S3_M_SEL>,
|
||||
<&topckgen CLK_TOP_I2S3_B_SEL>;
|
||||
clock-names = "infra_sys_audio_clk",
|
||||
"top_pdn_audio",
|
||||
"top_pdn_aud_intbus",
|
||||
"bck0",
|
||||
"bck1",
|
||||
"i2s0_m",
|
||||
"i2s1_m",
|
||||
"i2s2_m",
|
||||
"i2s3_m",
|
||||
"i2s3_b";
|
||||
memory-region = <&afe_dma_mem>;
|
||||
clock-names = "infra_sys_audio_clk",
|
||||
"top_pdn_audio",
|
||||
"top_pdn_aud_intbus",
|
||||
"bck0",
|
||||
"bck1",
|
||||
"i2s0_m",
|
||||
"i2s1_m",
|
||||
"i2s2_m",
|
||||
"i2s3_m",
|
||||
"i2s3_b";
|
||||
memory-region = <&afe_dma_mem>;
|
||||
};
|
||||
@@ -182,47 +182,47 @@ examples:
|
||||
<&topckgen CLK_TOP_APLL12_DIV4>,
|
||||
<&topckgen CLK_TOP_APLL12_DIVB>,
|
||||
<&clk26m>;
|
||||
clock-names = "aud_afe_clk",
|
||||
"aud_dac_clk",
|
||||
"aud_dac_predis_clk",
|
||||
"aud_adc_clk",
|
||||
"aud_adc_adda6_clk",
|
||||
"aud_apll22m_clk",
|
||||
"aud_apll24m_clk",
|
||||
"aud_apll1_tuner_clk",
|
||||
"aud_apll2_tuner_clk",
|
||||
"aud_i2s1_bclk_sw",
|
||||
"aud_i2s2_bclk_sw",
|
||||
"aud_i2s3_bclk_sw",
|
||||
"aud_i2s4_bclk_sw",
|
||||
"aud_tdm_clk",
|
||||
"aud_tml_clk",
|
||||
"aud_infra_clk",
|
||||
"mtkaif_26m_clk",
|
||||
"top_mux_audio",
|
||||
"top_mux_aud_intbus",
|
||||
"top_syspll_d2_d4",
|
||||
"top_mux_aud_1",
|
||||
"top_apll1_ck",
|
||||
"top_mux_aud_2",
|
||||
"top_apll2_ck",
|
||||
"top_mux_aud_eng1",
|
||||
"top_apll1_d8",
|
||||
"top_mux_aud_eng2",
|
||||
"top_apll2_d8",
|
||||
"top_i2s0_m_sel",
|
||||
"top_i2s1_m_sel",
|
||||
"top_i2s2_m_sel",
|
||||
"top_i2s3_m_sel",
|
||||
"top_i2s4_m_sel",
|
||||
"top_i2s5_m_sel",
|
||||
"top_apll12_div0",
|
||||
"top_apll12_div1",
|
||||
"top_apll12_div2",
|
||||
"top_apll12_div3",
|
||||
"top_apll12_div4",
|
||||
"top_apll12_divb",
|
||||
"top_clk26m_clk";
|
||||
clock-names = "aud_afe_clk",
|
||||
"aud_dac_clk",
|
||||
"aud_dac_predis_clk",
|
||||
"aud_adc_clk",
|
||||
"aud_adc_adda6_clk",
|
||||
"aud_apll22m_clk",
|
||||
"aud_apll24m_clk",
|
||||
"aud_apll1_tuner_clk",
|
||||
"aud_apll2_tuner_clk",
|
||||
"aud_i2s1_bclk_sw",
|
||||
"aud_i2s2_bclk_sw",
|
||||
"aud_i2s3_bclk_sw",
|
||||
"aud_i2s4_bclk_sw",
|
||||
"aud_tdm_clk",
|
||||
"aud_tml_clk",
|
||||
"aud_infra_clk",
|
||||
"mtkaif_26m_clk",
|
||||
"top_mux_audio",
|
||||
"top_mux_aud_intbus",
|
||||
"top_syspll_d2_d4",
|
||||
"top_mux_aud_1",
|
||||
"top_apll1_ck",
|
||||
"top_mux_aud_2",
|
||||
"top_apll2_ck",
|
||||
"top_mux_aud_eng1",
|
||||
"top_apll1_d8",
|
||||
"top_mux_aud_eng2",
|
||||
"top_apll2_d8",
|
||||
"top_i2s0_m_sel",
|
||||
"top_i2s1_m_sel",
|
||||
"top_i2s2_m_sel",
|
||||
"top_i2s3_m_sel",
|
||||
"top_i2s4_m_sel",
|
||||
"top_i2s5_m_sel",
|
||||
"top_apll12_div0",
|
||||
"top_apll12_div1",
|
||||
"top_apll12_div2",
|
||||
"top_apll12_div3",
|
||||
"top_apll12_div4",
|
||||
"top_apll12_divb",
|
||||
"top_clk26m_clk";
|
||||
};
|
||||
|
||||
...
|
||||
@@ -167,30 +167,30 @@ examples:
|
||||
"HDMI1", "TX";
|
||||
|
||||
hs-playback-dai-link {
|
||||
link-name = "I2S0";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&da7219>;
|
||||
};
|
||||
link-name = "I2S0";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&da7219>;
|
||||
};
|
||||
};
|
||||
|
||||
hs-capture-dai-link {
|
||||
link-name = "I2S1";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&da7219>;
|
||||
};
|
||||
link-name = "I2S1";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&da7219>;
|
||||
};
|
||||
};
|
||||
|
||||
spk-dp-playback-dai-link {
|
||||
link-name = "I2S3";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&anx_bridge_dp>, <&max98357a>;
|
||||
};
|
||||
link-name = "I2S3";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&anx_bridge_dp>, <&max98357a>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -171,30 +171,30 @@ examples:
|
||||
"HDMI1", "TX";
|
||||
|
||||
hs-playback-dai-link {
|
||||
link-name = "I2S0";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&rt5682s 0>;
|
||||
};
|
||||
link-name = "I2S0";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&rt5682s 0>;
|
||||
};
|
||||
};
|
||||
|
||||
hs-capture-dai-link {
|
||||
link-name = "I2S1";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&rt5682s 0>;
|
||||
};
|
||||
link-name = "I2S1";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&rt5682s 0>;
|
||||
};
|
||||
};
|
||||
|
||||
spk-hdmi-playback-dai-link {
|
||||
link-name = "I2S3";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&it6505dptx>, <&rt1019p>;
|
||||
};
|
||||
link-name = "I2S3";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&it6505dptx>, <&rt1019p>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -165,38 +165,38 @@ examples:
|
||||
"Speakers", "Speaker";
|
||||
|
||||
spk-playback-dai-link {
|
||||
link-name = "I2S3";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&rt1015p>;
|
||||
};
|
||||
link-name = "I2S3";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&rt1015p>;
|
||||
};
|
||||
};
|
||||
|
||||
hs-playback-dai-link {
|
||||
link-name = "I2S8";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&rt5682 0>;
|
||||
};
|
||||
link-name = "I2S8";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&rt5682 0>;
|
||||
};
|
||||
};
|
||||
|
||||
hs-capture-dai-link {
|
||||
link-name = "I2S9";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&rt5682 0>;
|
||||
};
|
||||
link-name = "I2S9";
|
||||
dai-format = "i2s";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&rt5682 0>;
|
||||
};
|
||||
};
|
||||
|
||||
displayport-dai-link {
|
||||
link-name = "TDM";
|
||||
dai-format = "dsp_a";
|
||||
codec {
|
||||
sound-dai = <&anx_bridge_dp>;
|
||||
};
|
||||
link-name = "TDM";
|
||||
dai-format = "dsp_a";
|
||||
codec {
|
||||
sound-dai = <&anx_bridge_dp>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -156,46 +156,46 @@ examples:
|
||||
"Ext Spk", "Speaker";
|
||||
|
||||
mm-dai-link {
|
||||
link-name = "ETDM1_IN_BE";
|
||||
mediatek,clk-provider = "cpu";
|
||||
link-name = "ETDM1_IN_BE";
|
||||
mediatek,clk-provider = "cpu";
|
||||
};
|
||||
|
||||
hs-playback-dai-link {
|
||||
link-name = "ETDM1_OUT_BE";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&headset_codec>;
|
||||
};
|
||||
link-name = "ETDM1_OUT_BE";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&headset_codec>;
|
||||
};
|
||||
};
|
||||
|
||||
hs-capture-dai-link {
|
||||
link-name = "ETDM2_IN_BE";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&headset_codec>;
|
||||
};
|
||||
link-name = "ETDM2_IN_BE";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&headset_codec>;
|
||||
};
|
||||
};
|
||||
|
||||
spk-playback-dai-link {
|
||||
link-name = "ETDM2_OUT_BE";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&spk_amplifier>;
|
||||
};
|
||||
link-name = "ETDM2_OUT_BE";
|
||||
mediatek,clk-provider = "cpu";
|
||||
codec {
|
||||
sound-dai = <&spk_amplifier>;
|
||||
};
|
||||
};
|
||||
|
||||
hdmi-dai-link {
|
||||
link-name = "ETDM3_OUT_BE";
|
||||
codec {
|
||||
sound-dai = <&hdmi_tx>;
|
||||
};
|
||||
link-name = "ETDM3_OUT_BE";
|
||||
codec {
|
||||
sound-dai = <&hdmi_tx>;
|
||||
};
|
||||
};
|
||||
|
||||
displayport-dai-link {
|
||||
link-name = "DPTX_BE";
|
||||
codec {
|
||||
sound-dai = <&dp_tx>;
|
||||
};
|
||||
link-name = "DPTX_BE";
|
||||
codec {
|
||||
sound-dai = <&dp_tx>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nuvoton,nau8360.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Nuvoton NAU83G60 Stereo Class-D Amplifier with DSP
|
||||
|
||||
description:
|
||||
Stereo Class-D Amplifier with DSP and I/V-sense.
|
||||
This device supports I2C.
|
||||
|
||||
maintainers:
|
||||
- Neo Chang <YLCHANG2@nuvoton.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nuvoton,nau8360
|
||||
|
||||
reg:
|
||||
description: The I2C address is determined by the hardware pins.
|
||||
enum: [0x1a, 0x1b, 0x4a, 0x4b]
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: mclk
|
||||
|
||||
firmware-name:
|
||||
description:
|
||||
List of DSP core firmware filenames. Both Left and Right DSP firmware
|
||||
must be provided and loaded. In PBTL mode, the Left DSP must use the
|
||||
same binary file as the Right DSP.
|
||||
items:
|
||||
- description: Left DSP core firmware filename.
|
||||
- description: Right DSP core firmware filename.
|
||||
|
||||
nuvoton,pbtl-enable:
|
||||
type: boolean
|
||||
description: NAU83G60 supports PBTL mode for mono output.
|
||||
|
||||
nuvoton,dac-cur-enable:
|
||||
type: boolean
|
||||
description:
|
||||
Adjust DAC output current to match speaker impedance and prevent
|
||||
hardware damage. +3.2dB when present, 0dB by default.
|
||||
|
||||
nuvoton,dsp-rx-slot-mapping:
|
||||
description:
|
||||
Configures the TDM slot routing for DSP RX functions.
|
||||
Each integer assigns a specific DSP internal function to a TDM slot.
|
||||
The indices of the array correspond to the following hardware functions
|
||||
(0) DACL
|
||||
(1) DACR
|
||||
(2) ANCL
|
||||
(3) ANCR
|
||||
Assigned slots must be unique, except 255 which disables the function.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
items:
|
||||
enum: [ 0, 1, 2, 3, 4, 5, 6, 7, 255 ]
|
||||
|
||||
nuvoton,dsp-tx-slot-mapping:
|
||||
description:
|
||||
Configures the TDM slot routing for DSP TX functions.
|
||||
Each integer assigns a specific DSP internal function to a TDM slot.
|
||||
The indices of the array correspond to the following hardware functions
|
||||
(0) AECL (Acoustic echo cancellation left)
|
||||
(1) AECR (Acoustic echo cancellation right)
|
||||
(2) ISNSL (Current sense left)
|
||||
(3) ISNSR (Current sense right)
|
||||
(4) VSNSL (Voltage sense left)
|
||||
(5) VSNSR (Voltage sense right)
|
||||
(6) TJ (Junction temperature)
|
||||
(7) VBAT (Battery voltage)
|
||||
Assigned slots must be unique, except 255 which disables the function.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
items:
|
||||
enum: [ 0, 1, 2, 3, 4, 5, 6, 7, 255 ]
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- firmware-name
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
codec@1a {
|
||||
compatible = "nuvoton,nau8360";
|
||||
reg = <0x1a>;
|
||||
#sound-dai-cells = <0>;
|
||||
firmware-name = "NAU83G60.kcs.bin.l", "NAU83G60.kcs.bin.r";
|
||||
nuvoton,dac-cur-enable;
|
||||
nuvoton,pbtl-enable;
|
||||
nuvoton,dsp-rx-slot-mapping = <0 1 2 3>;
|
||||
nuvoton,dsp-tx-slot-mapping = <0 1 2 3 4 5 6 7>;
|
||||
};
|
||||
};
|
||||
@@ -48,6 +48,11 @@ properties:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle of audio codec
|
||||
|
||||
nvidia,aux-devs:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: List of phandles pointing to auxiliary devices,
|
||||
such as amplifiers or dsp, to be added to the sound card.
|
||||
|
||||
nvidia,spkr-en-gpios:
|
||||
maxItems: 1
|
||||
description: The GPIO that enables the speakers
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nvidia,tegra-audio-wm8994.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra audio complex with WM8994 CODEC
|
||||
|
||||
maintainers:
|
||||
- Svyatoslav Ryhel <clamor95@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: nvidia,tegra-audio-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- pattern: '^[a-z0-9]+,tegra-audio-wm8994(-[a-z0-9]+)+$'
|
||||
- const: nvidia,tegra-audio-wm8994
|
||||
|
||||
nvidia,audio-routing:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
description: |
|
||||
A list of the connections between audio components.
|
||||
Each entry is a pair of strings, the first being the connection's sink,
|
||||
the second being the connection's source. Valid names for sources and
|
||||
sinks are the pins (documented in the binding document),
|
||||
and the jacks on the board.
|
||||
minItems: 2
|
||||
items:
|
||||
enum:
|
||||
# Board Connectors
|
||||
- Headphone Jack
|
||||
- Int Spk
|
||||
- Earpiece
|
||||
- Line Out
|
||||
- Mic Jack
|
||||
- Int Mic
|
||||
- Internal Mic 1
|
||||
- Internal Mic 2
|
||||
- FM Radio
|
||||
|
||||
# CODEC Pins
|
||||
- SPKOUTLP
|
||||
- SPKOUTLN
|
||||
- SPKOUTRP
|
||||
- SPKOUTRN
|
||||
- HPOUT1L
|
||||
- HPOUT1R
|
||||
- HPOUT2P
|
||||
- HPOUT2N
|
||||
- LINEOUT1P
|
||||
- LINEOUT1N
|
||||
- LINEOUT2P
|
||||
- LINEOUT2N
|
||||
- IN1LN
|
||||
- IN1LP
|
||||
- IN2LN
|
||||
- IN2LP:VXRN
|
||||
- IN1RN
|
||||
- IN1RP
|
||||
- IN2RN
|
||||
- IN2RP:VXRP
|
||||
- DMIC1DAT
|
||||
- DMIC2DAT
|
||||
- MICBIAS1
|
||||
- MICBIAS2
|
||||
|
||||
required:
|
||||
- nvidia,i2s-controller
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra20-car.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
sound {
|
||||
compatible = "lg,tegra-audio-wm8994-star",
|
||||
"nvidia,tegra-audio-wm8994";
|
||||
nvidia,model = "LG Optimus 2X WM8994";
|
||||
|
||||
nvidia,audio-routing =
|
||||
"Headphone Jack", "HPOUT1L",
|
||||
"Headphone Jack", "HPOUT1R",
|
||||
"Int Spk", "SPKOUTLN",
|
||||
"Int Spk", "SPKOUTLP",
|
||||
"Earpiece", "HPOUT2N",
|
||||
"Earpiece", "HPOUT2P",
|
||||
"IN2RN", "MICBIAS2",
|
||||
"IN2RN", "Mic Jack",
|
||||
"IN1LN", "MICBIAS1",
|
||||
"IN1LN", "Internal Mic 1",
|
||||
"IN1RN", "MICBIAS1",
|
||||
"IN1RN", "Internal Mic 2";
|
||||
|
||||
nvidia,i2s-controller = <&tegra_i2s1>;
|
||||
nvidia,audio-codec = <&wm8994>;
|
||||
|
||||
nvidia,hp-det-gpios = <&gpio 51 GPIO_ACTIVE_HIGH>;
|
||||
nvidia,mic-det-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>;
|
||||
nvidia,ext-mic-en-gpios = <&gpio 57 GPIO_ACTIVE_HIGH>;
|
||||
nvidia,coupled-mic-hp-det;
|
||||
|
||||
clocks = <&tegra_car TEGRA20_CLK_PLL_A>,
|
||||
<&tegra_car TEGRA20_CLK_PLL_A_OUT0>,
|
||||
<&tegra_car TEGRA20_CLK_CDEV1>;
|
||||
clock-names = "pll_a", "pll_a_out0", "mclk";
|
||||
};
|
||||
@@ -1,88 +0,0 @@
|
||||
NVIDIA Tegra30 AHUB (Audio Hub)
|
||||
|
||||
Required properties:
|
||||
- compatible : For Tegra30, must contain "nvidia,tegra30-ahub". For Tegra114,
|
||||
must contain "nvidia,tegra114-ahub". For Tegra124, must contain
|
||||
"nvidia,tegra124-ahub". Otherwise, must contain "nvidia,<chip>-ahub",
|
||||
plus at least one of the above, where <chip> is tegra132.
|
||||
- reg : Should contain the register physical address and length for each of
|
||||
the AHUB's register blocks.
|
||||
- Tegra30 requires 2 entries, for the APBIF and AHUB/AUDIO register blocks.
|
||||
- Tegra114 requires an additional entry, for the APBIF2 register block.
|
||||
- interrupts : Should contain AHUB interrupt
|
||||
- clocks : Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names : Must include the following entries:
|
||||
- d_audio
|
||||
- apbif
|
||||
- resets : Must contain an entry for each entry in reset-names.
|
||||
See ../reset/reset.txt for details.
|
||||
- reset-names : Must include the following entries:
|
||||
Tegra30 and later:
|
||||
- d_audio
|
||||
- apbif
|
||||
- i2s0
|
||||
- i2s1
|
||||
- i2s2
|
||||
- i2s3
|
||||
- i2s4
|
||||
- dam0
|
||||
- dam1
|
||||
- dam2
|
||||
- spdif
|
||||
Tegra114 and later additionally require:
|
||||
- amx
|
||||
- adx
|
||||
Tegra124 and later additionally require:
|
||||
- amx1
|
||||
- adx1
|
||||
- afc0
|
||||
- afc1
|
||||
- afc2
|
||||
- afc3
|
||||
- afc4
|
||||
- afc5
|
||||
- ranges : The bus address mapping for the configlink register bus.
|
||||
Can be empty since the mapping is 1:1.
|
||||
- dmas : Must contain an entry for each entry in clock-names.
|
||||
See ../dma/dma.txt for details.
|
||||
- dma-names : Must include the following entries:
|
||||
- rx0 .. rx<n>
|
||||
- tx0 .. tx<n>
|
||||
... where n is:
|
||||
Tegra30: 3
|
||||
Tegra114, Tegra124: 9
|
||||
- #address-cells : For the configlink bus. Should be <1>;
|
||||
- #size-cells : For the configlink bus. Should be <1>.
|
||||
|
||||
AHUB client modules need to specify the IDs of their CIFs (Client InterFaces).
|
||||
For RX CIFs, the numbers indicate the register number within AHUB routing
|
||||
register space (APBIF 0..3 RX, I2S 0..5 RX, DAM 0..2 RX 0..1, SPDIF RX 0..1).
|
||||
For TX CIFs, the numbers indicate the bit position within the AHUB routing
|
||||
registers (APBIF 0..3 TX, I2S 0..5 TX, DAM 0..2 TX, SPDIF TX 0..1).
|
||||
|
||||
Example:
|
||||
|
||||
ahub@70080000 {
|
||||
compatible = "nvidia,tegra30-ahub";
|
||||
reg = <0x70080000 0x200 0x70080200 0x100>;
|
||||
interrupts = < 0 103 0x04 >;
|
||||
nvidia,dma-request-selector = <&apbdma 1>;
|
||||
clocks = <&tegra_car 106>, <&tegra_car 107>;
|
||||
clock-names = "d_audio", "apbif";
|
||||
resets = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>,
|
||||
<&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>,
|
||||
<&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>,
|
||||
<&tegra_car 110>, <&tegra_car 10>;
|
||||
reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
|
||||
"i2s3", "i2s4", "dam0", "dam1", "dam2",
|
||||
"spdif";
|
||||
dmas = <&apbdma 1>, <&apbdma 1>;
|
||||
<&apbdma 2>, <&apbdma 2>;
|
||||
<&apbdma 3>, <&apbdma 3>;
|
||||
<&apbdma 4>, <&apbdma 4>;
|
||||
dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2", "rx3", "tx3";
|
||||
ranges;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
};
|
||||
@@ -0,0 +1,289 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/nvidia,tegra30-ahub.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NVIDIA Tegra30 AHUB (Audio Hub)
|
||||
|
||||
maintainers:
|
||||
- Thierry Reding <thierry.reding@gmail.com>
|
||||
- Jon Hunter <jonathanh@nvidia.com>
|
||||
|
||||
description:
|
||||
AHUB client modules need to specify the IDs of their CIFs (Client
|
||||
InterFaces). For RX CIFs, the numbers indicate the register number within
|
||||
AHUB routing register space (APBIF 0..3 RX, I2S 0..5 RX, DAM 0..2 RX 0..1,
|
||||
SPDIF RX 0..1). For TX CIFs, the numbers indicate the bit position within
|
||||
the AHUB routing registers (APBIF 0..3 TX, I2S 0..5 TX, DAM 0..2 TX, SPDIF
|
||||
TX 0..1).
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: nvidia,tegra30-ahub
|
||||
- const: nvidia,tegra114-ahub
|
||||
- const: nvidia,tegra124-ahub
|
||||
- items:
|
||||
- const: nvidia,tegra132-ahub
|
||||
- const: nvidia,tegra124-ahub
|
||||
|
||||
reg:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: digital audio clock
|
||||
- description: module clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: d_audio
|
||||
- const: apbif
|
||||
|
||||
resets:
|
||||
minItems: 11
|
||||
maxItems: 21
|
||||
|
||||
reset-names:
|
||||
minItems: 11
|
||||
maxItems: 21
|
||||
|
||||
ranges: true
|
||||
|
||||
dmas:
|
||||
minItems: 8
|
||||
maxItems: 20
|
||||
|
||||
dma-names:
|
||||
minItems: 8
|
||||
maxItems: 20
|
||||
|
||||
"#address-cells":
|
||||
enum: [1, 2]
|
||||
|
||||
"#size-cells":
|
||||
enum: [1, 2]
|
||||
|
||||
patternProperties:
|
||||
"^i2s@[0-9a-f]+$":
|
||||
type: object
|
||||
required:
|
||||
- compatible
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
- ranges
|
||||
- dmas
|
||||
- dma-names
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
const: nvidia,tegra30-ahub
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: APBIF registers
|
||||
- description: AHUB/AUDIO registers
|
||||
|
||||
resets:
|
||||
maxItems: 11
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: d_audio
|
||||
- const: apbif
|
||||
- const: i2s0
|
||||
- const: i2s1
|
||||
- const: i2s2
|
||||
- const: i2s3
|
||||
- const: i2s4
|
||||
- const: dam0
|
||||
- const: dam1
|
||||
- const: dam2
|
||||
- const: spdif
|
||||
|
||||
dmas:
|
||||
maxItems: 8
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: rx0
|
||||
- const: tx0
|
||||
- const: rx1
|
||||
- const: tx1
|
||||
- const: rx2
|
||||
- const: tx2
|
||||
- const: rx3
|
||||
- const: tx3
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
const: nvidia,tegra114-ahub
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: APBIF registers
|
||||
- description: AHUB/AUDIO registers
|
||||
- description: APBIF2 registers
|
||||
|
||||
resets:
|
||||
minItems: 13
|
||||
maxItems: 13
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: d_audio
|
||||
- const: apbif
|
||||
- const: i2s0
|
||||
- const: i2s1
|
||||
- const: i2s2
|
||||
- const: i2s3
|
||||
- const: i2s4
|
||||
- const: dam0
|
||||
- const: dam1
|
||||
- const: dam2
|
||||
- const: spdif
|
||||
- const: amx
|
||||
- const: adx
|
||||
|
||||
dmas:
|
||||
minItems: 20
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: rx0
|
||||
- const: tx0
|
||||
- const: rx1
|
||||
- const: tx1
|
||||
- const: rx2
|
||||
- const: tx2
|
||||
- const: rx3
|
||||
- const: tx3
|
||||
- const: rx4
|
||||
- const: tx4
|
||||
- const: rx5
|
||||
- const: tx5
|
||||
- const: rx6
|
||||
- const: tx6
|
||||
- const: rx7
|
||||
- const: tx7
|
||||
- const: rx8
|
||||
- const: tx8
|
||||
- const: rx9
|
||||
- const: tx9
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: nvidia,tegra124-ahub
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: APBIF registers
|
||||
- description: AHUB/AUDIO registers
|
||||
- description: APBIF2 registers
|
||||
|
||||
resets:
|
||||
minItems: 21
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: d_audio
|
||||
- const: apbif
|
||||
- const: i2s0
|
||||
- const: i2s1
|
||||
- const: i2s2
|
||||
- const: i2s3
|
||||
- const: i2s4
|
||||
- const: dam0
|
||||
- const: dam1
|
||||
- const: dam2
|
||||
- const: spdif
|
||||
- const: amx
|
||||
- const: amx1
|
||||
- const: adx
|
||||
- const: adx1
|
||||
- const: afc0
|
||||
- const: afc1
|
||||
- const: afc2
|
||||
- const: afc3
|
||||
- const: afc4
|
||||
- const: afc5
|
||||
|
||||
dmas:
|
||||
minItems: 20
|
||||
|
||||
dma-names:
|
||||
items:
|
||||
- const: rx0
|
||||
- const: tx0
|
||||
- const: rx1
|
||||
- const: tx1
|
||||
- const: rx2
|
||||
- const: tx2
|
||||
- const: rx3
|
||||
- const: tx3
|
||||
- const: rx4
|
||||
- const: tx4
|
||||
- const: rx5
|
||||
- const: tx5
|
||||
- const: rx6
|
||||
- const: tx6
|
||||
- const: rx7
|
||||
- const: tx7
|
||||
- const: rx8
|
||||
- const: tx8
|
||||
- const: rx9
|
||||
- const: tx9
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/tegra30-car.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
ahub@70080000 {
|
||||
compatible = "nvidia,tegra30-ahub";
|
||||
reg = <0x70080000 0x200>,
|
||||
<0x70080200 0x100>;
|
||||
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA30_CLK_D_AUDIO>,
|
||||
<&tegra_car TEGRA30_CLK_APBIF>;
|
||||
clock-names = "d_audio", "apbif";
|
||||
resets = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>,
|
||||
<&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>,
|
||||
<&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>,
|
||||
<&tegra_car 110>, <&tegra_car 10>;
|
||||
reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
|
||||
"i2s3", "i2s4", "dam0", "dam1", "dam2",
|
||||
"spdif";
|
||||
dmas = <&apbdma 1>, <&apbdma 1>,
|
||||
<&apbdma 2>, <&apbdma 2>,
|
||||
<&apbdma 3>, <&apbdma 3>,
|
||||
<&apbdma 4>, <&apbdma 4>;
|
||||
dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2", "rx3", "tx3";
|
||||
ranges;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
};
|
||||
@@ -18,6 +18,7 @@ properties:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,sdm660-wcd-digital-codec
|
||||
- qcom,sdm670-wcd-digital-codec
|
||||
- const: qcom,msm8916-wcd-digital-codec
|
||||
|
||||
- const: qcom,msm8916-wcd-digital-codec
|
||||
|
||||
@@ -20,9 +20,24 @@ properties:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
memory-region:
|
||||
minItems: 1
|
||||
items:
|
||||
- description:
|
||||
Control-path buffer (audio_heap_mem) for platforms where the DSP
|
||||
runs in a stage-2 protected context (e.g. modem-DSP).
|
||||
- description:
|
||||
Data-path buffer pool from which per-stream DMA buffers are
|
||||
allocated.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- iommus
|
||||
|
||||
oneOf:
|
||||
- required:
|
||||
- iommus
|
||||
- required:
|
||||
- memory-region
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
||||
@@ -75,11 +75,11 @@ examples:
|
||||
#size-cells = <0>;
|
||||
|
||||
dai@10 {
|
||||
reg = <PRIMARY_MI2S_RX>;
|
||||
clocks = <&q6prmcc LPASS_CLK_ID_PRI_MI2S_IBIT
|
||||
LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&q6prmcc LPASS_CLK_ID_MCLK_1
|
||||
LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
|
||||
clock-names = "bclk", "mclk";
|
||||
reg = <PRIMARY_MI2S_RX>;
|
||||
clocks = <&q6prmcc LPASS_CLK_ID_PRI_MI2S_IBIT
|
||||
LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&q6prmcc LPASS_CLK_ID_MCLK_1
|
||||
LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
|
||||
clock-names = "bclk", "mclk";
|
||||
};
|
||||
};
|
||||
@@ -108,10 +108,15 @@ patternProperties:
|
||||
properties:
|
||||
reg:
|
||||
contains:
|
||||
# TDM DAI ID range from PRIMARY_TDM_RX_0 - QUINARY_TDM_TX_7
|
||||
# TDM DAI ID range from PRIMARY_TDM_RX_0 - QUINARY_TDM_TX_7 and
|
||||
# AIF_TDM_RX_0 - AIF_TDM_TX_12
|
||||
items:
|
||||
minimum: 24
|
||||
maximum: 103
|
||||
oneOf:
|
||||
- minimum: 24
|
||||
maximum: 103
|
||||
- minimum: 179
|
||||
maximum: 204
|
||||
|
||||
then:
|
||||
required:
|
||||
- qcom,tdm-sync-mode
|
||||
@@ -127,7 +132,8 @@ patternProperties:
|
||||
contains:
|
||||
# MI2S DAI ID range PRIMARY_MI2S_RX - QUATERNARY_MI2S_TX and
|
||||
# QUINARY_MI2S_RX - QUINARY_MI2S_TX and
|
||||
# LPI_MI2S_RX_0 - LPI_MI2S_TX_6
|
||||
# LPI_MI2S_RX_0 - LPI_MI2S_TX_6 and
|
||||
# AIF_MI2S_RX_0 - AIF_MI2S_TX_12
|
||||
items:
|
||||
oneOf:
|
||||
- minimum: 16
|
||||
@@ -136,6 +142,8 @@ patternProperties:
|
||||
maximum: 128
|
||||
- minimum: 137
|
||||
maximum: 152
|
||||
- minimum: 153
|
||||
maximum: 178
|
||||
then:
|
||||
required:
|
||||
- qcom,sd-lines
|
||||
|
||||
@@ -0,0 +1,290 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/qcom,shikra-qaif-cpu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Audio Interface (QAIF) CPU DAI Controller
|
||||
|
||||
maintainers:
|
||||
- Harendra Gautam <harendra.gautam@oss.qualcomm.com>
|
||||
|
||||
description: |
|
||||
The Qualcomm Audio Interface (QAIF) is a fully configurable DMA-based
|
||||
audio subsystem controller. It serialises and deserialises PCM audio
|
||||
between system memory and external serial audio peripherals (PCM, TDM,
|
||||
I2S, MI2S) through the AIF path, and transfers parallel audio between
|
||||
memory and an internal WCD codec through the CIF path.
|
||||
|
||||
AIF (Audio Interface): up to 13 multi-lane Unified Audio Interfaces,
|
||||
each supporting up to 8 independent data lanes. Each lane is individually
|
||||
configurable as TX (output/speaker) or RX (input/mic). All lanes of an
|
||||
interface share a single bit clock and frame sync. Supported modes are
|
||||
PCM (short/long sync), TDM, and MI2S (stereo/mono). Per-interface
|
||||
configuration includes sync source (master/slave), sync mode, sync delay,
|
||||
sync inversion, slot width (8/16/24/32-bit), sample width, active slot
|
||||
masks (up to 32 slots), bits-per-lane frame size, lane enable/direction
|
||||
masks, loopback, output-enable control, and full-cycle path support for
|
||||
long chip-to-chip connections.
|
||||
|
||||
CIF (Codec Interface): up to 10 RDDMA (playback) and 10 WRDMA (capture)
|
||||
channels connecting to an internal codec over a parallel bus. Each channel
|
||||
supports active-channel enable mask (up to 16 channels), frame-sync
|
||||
selection, frame-sync delay, frame-sync output gating, dynamic clock
|
||||
gating, and 16-bit packing/unpacking.
|
||||
|
||||
Note on RX/TX naming convention: in QAIF, TX refers to the output
|
||||
(speaker/playback) direction and RX refers to the input (mic/capture)
|
||||
direction. This applies to both AIF lane directions and CIF slot/mask
|
||||
properties.
|
||||
|
||||
DMA engine: RDDMA fetches audio from DDR/TCM/LPM into a shared SRAM
|
||||
latency buffer (SHRAM) and drains it to the interface. WRDMA collects
|
||||
data from the interface into SHRAM and writes it to memory. Each DMA
|
||||
owns a private SHRAM region defined by start address and length registers.
|
||||
Burst sizes of 1/2/4/8/16 beats (64-bit) are supported with up to 4
|
||||
outstanding transactions per DMA. Two QSB master ports (QXM0 for TCM,
|
||||
QXM1 for DDR/LPM) provide the memory interface.
|
||||
|
||||
Resources are partitioned among up to 5 Execution Engines (EEs) via
|
||||
EE map registers. Each EE owns a set of DMAs, audio interfaces, and
|
||||
interface groups, and receives its own independent interrupt output.
|
||||
The interrupt hierarchy has a two-level structure: a summary register
|
||||
identifies the event class (DMA period, underflow/overflow, error
|
||||
response, audio interface underflow/overflow, group done, rate detector,
|
||||
VFR), and per-resource status registers identify the specific channel.
|
||||
|
||||
Interface grouping (bonding) allows up to 6 groups of audio and codec
|
||||
interfaces to start synchronously and align their DMA period interrupts
|
||||
within half a frame duration using the RDDMA padding feature.
|
||||
|
||||
Two rate detector blocks measure the frequency of incoming frame sync or
|
||||
word select signals and generate interrupts on rate change, undetected
|
||||
rate, or sync timeout.
|
||||
|
||||
Block diagram::
|
||||
|
||||
System Memory (DDR / LPM / TCM)
|
||||
+---------------------------------+
|
||||
| Circular Buffers (ping-pong) |
|
||||
+----------+----------+-----------+
|
||||
| ^
|
||||
64-bit AXI 64-bit AXI
|
||||
| |
|
||||
+----------v----------+-----------+
|
||||
| QSB Master Ports |
|
||||
| +----------+ +----------+ |
|
||||
| | QXM0 | | QXM1 | |
|
||||
| +----+-----+ +-----+----+ |
|
||||
+-------|--------------|----------+
|
||||
| |
|
||||
+-------v--------------v----------+
|
||||
| Shared RAM (SHRAM) |
|
||||
| +------------+ +------------+ |
|
||||
| | QXM0 Read | | QXM0 Write | |
|
||||
| | SHRAM | | SHRAM | |
|
||||
| +------------+ +------------+ |
|
||||
| +------------+ +------------+ |
|
||||
| | QXM1 Read | | QXM1 Write | |
|
||||
| | SHRAM | | SHRAM | |
|
||||
| +------------+ +------------+ |
|
||||
+---+--------+--------+-------+---+
|
||||
| | | |
|
||||
+---v--+ +--v---+ +--v---+ +-v----+
|
||||
|RDDMA | |RDDMA | |WRDMA | |WRDMA |
|
||||
| AIF | | CIF | | AIF | | CIF |
|
||||
|[0..n]| |[0..n]| |[0..n]| |[0..n]|
|
||||
+--+---+ +--+---+ +--+---+ +-+----+
|
||||
| | ^ ^
|
||||
| TX | TX | RX | RX
|
||||
v v | |
|
||||
+--+--------------------+ +----+----------+
|
||||
| Unified Audio Intf | | Codec DMA |
|
||||
| (AIF 0..12) | | Interface |
|
||||
| | | (CIF) |
|
||||
| AUD_INTFa block: | | |
|
||||
| - Serializer (TX) | | RDDMA: DDR -> |
|
||||
| - De-serializer (RX) | | internal |
|
||||
| - Sync gen/detect | | codec |
|
||||
| - Up to 8 data lanes | | WRDMA: codec |
|
||||
| - PCM / TDM / MI2S | | -> DDR |
|
||||
| - Near Pad Logic | | Up to 16 ch |
|
||||
+--+--------------------+ +----+----------+
|
||||
| Lane 0..7 (TX/RX) | Parallel bus
|
||||
| Bit clk + Frame sync | + Frame sync
|
||||
v v
|
||||
+--+--------+ +------+------+
|
||||
| External | | Internal |
|
||||
| Serial | | Digital |
|
||||
| Peripherals| | Codec |
|
||||
| (PCM/TDM/ | | (Bolero/ |
|
||||
| MI2S) | | WCD) |
|
||||
+-----------+ +-------------+
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,shikra-qaif-cpu
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description:
|
||||
QAIF summary interrupt for this Execution Engine.
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
dma-coherent: true
|
||||
|
||||
clocks:
|
||||
maxItems: 9
|
||||
|
||||
clock-names:
|
||||
description:
|
||||
Core clocks for register access and DMA, followed by one bit
|
||||
clock per AIF interface.
|
||||
items:
|
||||
- const: lpass_config
|
||||
- const: lpass_core_axim
|
||||
- const: aud_dma
|
||||
- const: aud_dma_mem
|
||||
- const: bus
|
||||
- const: aif_if0_ibit
|
||||
- const: aif_if1_ibit
|
||||
- const: aif_if2_ibit
|
||||
- const: aif_if3_ibit
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
'^aif@[0-9a-f]+$':
|
||||
type: object
|
||||
description:
|
||||
QAIF AIF interface child node for PCM, TDM or MI2S configuration.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/sound/tdm-slot.yaml#
|
||||
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
description:
|
||||
DAI ID of the AIF interface (QAIF_MI2S_AIF* or QAIF_TDM_AIF*).
|
||||
|
||||
dai-format:
|
||||
description: Serial audio interface format (MI2S, TDM or PCM).
|
||||
enum: [i2s, dsp_a, dsp_b]
|
||||
|
||||
dai-tdm-slot-width:
|
||||
enum: [8, 16, 24, 32]
|
||||
|
||||
dai-tdm-slot-num:
|
||||
minimum: 1
|
||||
maximum: 32
|
||||
|
||||
dai-tdm-slot-rx-mask:
|
||||
minItems: 1
|
||||
maxItems: 32
|
||||
|
||||
dai-tdm-slot-tx-mask:
|
||||
minItems: 1
|
||||
maxItems: 32
|
||||
|
||||
qcom,qaif-aif-lane-map:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
description:
|
||||
Per-lane direction map, one entry per lane starting from lane 0.
|
||||
Use 0 for TX (output/speaker) and 1 for RX (input/mic).
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
items:
|
||||
enum: [0, 1]
|
||||
|
||||
required:
|
||||
- reg
|
||||
- dai-format
|
||||
- qcom,qaif-aif-lane-map
|
||||
|
||||
if:
|
||||
properties:
|
||||
dai-format:
|
||||
enum: [dsp_a, dsp_b]
|
||||
then:
|
||||
required:
|
||||
- dai-tdm-slot-width
|
||||
- dai-tdm-slot-num
|
||||
- dai-tdm-slot-rx-mask
|
||||
- dai-tdm-slot-tx-mask
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- iommus
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#sound-dai-cells'
|
||||
- '#address-cells'
|
||||
- '#size-cells'
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
qaif_cpu: audio-controller@a000000 {
|
||||
compatible = "qcom,shikra-qaif-cpu";
|
||||
reg = <0x0 0x0a000000 0x0 0x20000>;
|
||||
interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>;
|
||||
iommus = <&apps_smmu 0x1c0 0x0>;
|
||||
clocks = <&gcc 213>,
|
||||
<&gcc 214>,
|
||||
<&audiocorecc 15>,
|
||||
<&audiocorecc 17>,
|
||||
<&audiocorecc 18>,
|
||||
<&audiocorecc 5>,
|
||||
<&audiocorecc 8>,
|
||||
<&audiocorecc 11>,
|
||||
<&audiocorecc 14>;
|
||||
clock-names = "lpass_config",
|
||||
"lpass_core_axim",
|
||||
"aud_dma",
|
||||
"aud_dma_mem",
|
||||
"bus",
|
||||
"aif_if0_ibit",
|
||||
"aif_if1_ibit",
|
||||
"aif_if2_ibit",
|
||||
"aif_if3_ibit";
|
||||
#sound-dai-cells = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
aif@b5 {
|
||||
reg = <181>;
|
||||
dai-format = "dsp_a";
|
||||
dai-tdm-slot-width = <32>;
|
||||
dai-tdm-slot-num = <2>;
|
||||
dai-tdm-slot-rx-mask = <1 1>;
|
||||
dai-tdm-slot-tx-mask = <1 1>;
|
||||
qcom,qaif-aif-lane-map = <1 0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -36,8 +36,10 @@ properties:
|
||||
- ayaneo,pocket-s2-sndcard
|
||||
- fairphone,fp4-sndcard
|
||||
- fairphone,fp5-sndcard
|
||||
- motorola,dubai-sndcard
|
||||
- qcom,apq8096-sndcard
|
||||
- qcom,glymur-sndcard
|
||||
- qcom,nord-sndcard
|
||||
- qcom,qcm6490-idp-sndcard
|
||||
- qcom,qcs615-sndcard
|
||||
- qcom,qcs6490-rb3gen2-sndcard
|
||||
@@ -54,6 +56,7 @@ properties:
|
||||
- qcom,sm8250-sndcard
|
||||
- qcom,sm8450-sndcard
|
||||
- qcom,x1e80100-sndcard
|
||||
- thundercomm,qcs6490-rubikpi3-sndcard
|
||||
|
||||
audio-routing:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/qcom,wcd9378-sdw.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm WCD9378 (Tambora) SoundWire codec
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
|
||||
|
||||
description:
|
||||
Qualcomm WCD9378 (Tambora) SoundWire codec. The same silicon can be
|
||||
fused for a mobile (non-SDCA) mode or an SDCA-compliant mode; the
|
||||
qcom,sdca-compliant property selects the latter and is required by
|
||||
this driver.
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sdw20217011000
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
qcom,sdca-compliant:
|
||||
description:
|
||||
Present when the codec is fused as SDCA-compliant. The mobile
|
||||
(non-SDCA) variant carries the same class-ID compatible and is
|
||||
handled by a different driver.
|
||||
type: boolean
|
||||
|
||||
qcom,port-mapping:
|
||||
description:
|
||||
Each entry maps a slave data port to a master data port.
|
||||
Entries are in order starting from slave port 1; slave port 0
|
||||
is reserved and not represented. SDCA-compliant mode uses 8
|
||||
entries covering DP1..DP8.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 8
|
||||
maxItems: 8
|
||||
|
||||
reset-gpios:
|
||||
description: GPIO used to release the codec from reset.
|
||||
maxItems: 1
|
||||
|
||||
vdd-buck-supply:
|
||||
description: 1.8 V analog buck supply.
|
||||
|
||||
vdd-rxtx-supply:
|
||||
description: 1.8 V RX/TX supply.
|
||||
|
||||
vdd-io-supply:
|
||||
description: Digital I/O supply.
|
||||
|
||||
vdd-mic-bias-supply:
|
||||
description: Mic bias supply.
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- qcom,sdca-compliant
|
||||
- qcom,port-mapping
|
||||
- reset-gpios
|
||||
- vdd-buck-supply
|
||||
- vdd-rxtx-supply
|
||||
- vdd-io-supply
|
||||
- vdd-mic-bias-supply
|
||||
- '#sound-dai-cells'
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
soundwire@7630000 {
|
||||
reg = <0x07630000 0x10000>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
wcd9378c_sdw: audio-codec@0,3 {
|
||||
compatible = "sdw20217011000";
|
||||
reg = <0 3>;
|
||||
|
||||
qcom,sdca-compliant;
|
||||
|
||||
qcom,port-mapping = <2 2 3 4 5 6 7 8>;
|
||||
|
||||
reset-gpios = <&tlmm 191 GPIO_ACTIVE_LOW>;
|
||||
|
||||
vdd-buck-supply = <&vreg_l15b_1p8>;
|
||||
vdd-rxtx-supply = <&vreg_l15b_1p8>;
|
||||
vdd-io-supply = <&vreg_l18b_1p2>;
|
||||
vdd-mic-bias-supply = <&vreg_bob1>;
|
||||
|
||||
#sound-dai-cells = <1>;
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -44,6 +44,14 @@ properties:
|
||||
'#gpio-cells':
|
||||
const: 2
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: phandle and clock specifier for the codec MCLK1 input.
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk1
|
||||
|
||||
realtek,pow-ldo2-gpio:
|
||||
maxItems: 1
|
||||
description: CODEC's POW_LDO2 pin.
|
||||
@@ -127,6 +135,8 @@ examples:
|
||||
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
clocks = <&osc>;
|
||||
clock-names = "mclk1";
|
||||
realtek,pow-ldo2-gpio = <&gpio 3 GPIO_ACTIVE_HIGH>;
|
||||
realtek,reset-gpio = <&gpio 3 GPIO_ACTIVE_LOW>;
|
||||
realtek,in1-differential;
|
||||
|
||||
@@ -432,14 +432,14 @@ examples:
|
||||
"ssi.1", "ssi.0";
|
||||
|
||||
rcar_sound,dvc {
|
||||
dvc0: dvc-0 {
|
||||
dmas = <&audma0 0xbc>;
|
||||
dma-names = "tx";
|
||||
};
|
||||
dvc1: dvc-1 {
|
||||
dmas = <&audma0 0xbe>;
|
||||
dma-names = "tx";
|
||||
};
|
||||
dvc0: dvc-0 {
|
||||
dmas = <&audma0 0xbc>;
|
||||
dma-names = "tx";
|
||||
};
|
||||
dvc1: dvc-1 {
|
||||
dmas = <&audma0 0xbe>;
|
||||
dma-names = "tx";
|
||||
};
|
||||
};
|
||||
|
||||
rcar_sound,mix {
|
||||
|
||||
@@ -95,20 +95,20 @@ examples:
|
||||
ssi0: ssi@10049c00 {
|
||||
compatible = "renesas,r9a07g044-ssi",
|
||||
"renesas,rz-ssi";
|
||||
reg = <0x10049c00 0x400>;
|
||||
interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 327 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 328 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "int_req", "dma_rx", "dma_tx";
|
||||
clocks = <&cpg CPG_MOD R9A07G044_SSI0_PCLK2>,
|
||||
<&cpg CPG_MOD R9A07G044_SSI0_PCLK_SFR>,
|
||||
<&audio_clk1>,
|
||||
<&audio_clk2>;
|
||||
clock-names = "ssi", "ssi_sfr", "audio_clk1", "audio_clk2";
|
||||
power-domains = <&cpg>;
|
||||
resets = <&cpg R9A07G044_SSI0_RST_M2_REG>;
|
||||
dmas = <&dmac 0x2655>,
|
||||
<&dmac 0x2656>;
|
||||
dma-names = "tx", "rx";
|
||||
#sound-dai-cells = <0>;
|
||||
reg = <0x10049c00 0x400>;
|
||||
interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 327 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 328 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "int_req", "dma_rx", "dma_tx";
|
||||
clocks = <&cpg CPG_MOD R9A07G044_SSI0_PCLK2>,
|
||||
<&cpg CPG_MOD R9A07G044_SSI0_PCLK_SFR>,
|
||||
<&audio_clk1>,
|
||||
<&audio_clk2>;
|
||||
clock-names = "ssi", "ssi_sfr", "audio_clk1", "audio_clk2";
|
||||
power-domains = <&cpg>;
|
||||
resets = <&cpg R9A07G044_SSI0_RST_M2_REG>;
|
||||
dmas = <&dmac 0x2655>,
|
||||
<&dmac 0x2656>;
|
||||
dma-names = "tx", "rx";
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
@@ -0,0 +1,96 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/stericsson,ux500-msp-i2s.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ST-Ericsson Ux500 Multichannel Serial Port
|
||||
|
||||
maintainers:
|
||||
- Linus Walleij <linusw@kernel.org>
|
||||
|
||||
description:
|
||||
The Ux500 Multichannel Serial Port (MSP) is a synchronous serial audio
|
||||
interface supporting I2S and PCM/TDM protocols. Data is transferred to and
|
||||
from memory using the Ux500 DMA controller.
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: stericsson,ux500-msp-i2s
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
v-ape-supply:
|
||||
description: Analog power engine supply
|
||||
|
||||
dmas:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
dma-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
enum: [ rx, tx ]
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: MSP functional clock
|
||||
- description: MSP APB bus clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: msp
|
||||
- const: apb_pclk
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- v-ape-supply
|
||||
- dmas
|
||||
- dma-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- '#sound-dai-cells'
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/reset/stericsson,db8500-prcc-reset.h>
|
||||
|
||||
msp@80123000 {
|
||||
compatible = "stericsson,ux500-msp-i2s";
|
||||
reg = <0x80123000 0x1000>;
|
||||
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
|
||||
v-ape-supply = <&db8500_vape_reg>;
|
||||
dmas = <&dma 31 0 0x12>, <&dma 31 0 0x10>;
|
||||
dma-names = "rx", "tx";
|
||||
clocks = <&prcc_kclk 1 3>, <&prcc_pclk 1 3>;
|
||||
clock-names = "msp", "apb_pclk";
|
||||
resets = <&prcc_reset DB8500_PRCC_1 DB8500_PRCC_1_RESET_MSP0>;
|
||||
#sound-dai-cells = <0>;
|
||||
};
|
||||
|
||||
...
|
||||
@@ -0,0 +1,83 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/ti,da830-evm-audio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments SoC audio setups with TLV320AIC3X Codec
|
||||
|
||||
maintainers:
|
||||
- Eduard Bostina <egbostina@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,da830-evm-audio
|
||||
|
||||
ti,model:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: The user-visible name of this sound complex.
|
||||
|
||||
ti,audio-codec:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle of the TLV320AIC3x audio codec
|
||||
|
||||
ti,mcasp-controller:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle of the McASP controller
|
||||
|
||||
ti,audio-routing:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
description:
|
||||
A list of the connections between audio components. Each entry is a
|
||||
pair of strings, the first being the connection's sink, the second
|
||||
being the connection's source. Valid names for sources and sinks
|
||||
are the codec's pins, and the jacks on the board (Headphone Jack,
|
||||
Line Out, Mic Jack, Line In).
|
||||
|
||||
ti,codec-clock-rate:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: The Codec Clock rate (in Hz) applied to the Codec.
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description: Reference to the master clock
|
||||
|
||||
clock-names:
|
||||
const: mclk
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- ti,model
|
||||
- ti,audio-codec
|
||||
- ti,mcasp-controller
|
||||
- ti,audio-routing
|
||||
|
||||
anyOf:
|
||||
- required:
|
||||
- ti,codec-clock-rate
|
||||
- required:
|
||||
- clocks
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sound {
|
||||
compatible = "ti,da830-evm-audio";
|
||||
ti,model = "DA830 EVM";
|
||||
ti,audio-codec = <&tlv320aic3x>;
|
||||
ti,mcasp-controller = <&mcasp1>;
|
||||
ti,codec-clock-rate = <12000000>;
|
||||
ti,audio-routing =
|
||||
"Headphone Jack", "HPLOUT",
|
||||
"Headphone Jack", "HPROUT",
|
||||
"Line Out", "LLOUT",
|
||||
"Line Out", "RLOUT",
|
||||
"MIC3L", "Mic Bias 2V",
|
||||
"MIC3R", "Mic Bias 2V",
|
||||
"Mic Bias 2V", "Mic Jack",
|
||||
"LINE1L", "Line In",
|
||||
"LINE2L", "Line In",
|
||||
"LINE1R", "Line In",
|
||||
"LINE2R", "Line In";
|
||||
};
|
||||
@@ -21,6 +21,22 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description: System clock (SCK)
|
||||
|
||||
clock-names:
|
||||
const: sck
|
||||
|
||||
VCC1-supply:
|
||||
description: 5V analog power supply
|
||||
|
||||
VCC2-supply:
|
||||
description: 5V analog power supply
|
||||
|
||||
VDD-supply:
|
||||
description: 3.3V digital power supply
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
|
||||
@@ -219,9 +219,7 @@ allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- ti,tas2781
|
||||
const: ti,tas2781
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
|
||||
@@ -45,13 +45,13 @@ examples:
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
tas5805m: tas5805m@2c {
|
||||
reg = <0x2c>;
|
||||
compatible = "ti,tas5805m";
|
||||
reg = <0x2c>;
|
||||
compatible = "ti,tas5805m";
|
||||
|
||||
pvdd-supply = <&audiopwr>;
|
||||
pdn-gpios = <&tlmm 160 0>;
|
||||
pvdd-supply = <&audiopwr>;
|
||||
pdn-gpios = <&tlmm 160 0>;
|
||||
|
||||
ti,dsp-config-name = "mono_pbtl_48khz";
|
||||
ti,dsp-config-name = "mono_pbtl_48khz";
|
||||
};
|
||||
};
|
||||
...
|
||||
@@ -121,6 +121,6 @@ examples:
|
||||
AVDD-supply = <®ulator>;
|
||||
IOVDD-supply = <®ulator>;
|
||||
DVDD-supply = <®ulator>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -50,6 +50,6 @@ examples:
|
||||
reg = <0x60>;
|
||||
Vdd-supply = <&vmmc2>;
|
||||
power-gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
* MOP500 Audio Machine Driver
|
||||
|
||||
This node is responsible for linking together all ux500 Audio Driver components.
|
||||
|
||||
Required properties:
|
||||
- compatible : "stericsson,snd-soc-mop500"
|
||||
|
||||
Non-standard properties:
|
||||
- stericsson,cpu-dai : Phandle to the CPU-side DAI
|
||||
- stericsson,audio-codec : Phandle to the Audio CODEC
|
||||
- stericsson,card-name : Over-ride default card name
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "stericsson,snd-soc-mop500";
|
||||
|
||||
stericsson,cpu-dai = <&msp1 &msp3>;
|
||||
stericsson,audio-codec = <&codec>;
|
||||
};
|
||||
|
||||
msp1: msp@80124000 {
|
||||
compatible = "stericsson,ux500-msp-i2s";
|
||||
reg = <0x80124000 0x1000>;
|
||||
interrupts = <0 62 0x4>;
|
||||
v-ape-supply = <&db8500_vape_reg>;
|
||||
};
|
||||
|
||||
msp3: msp@80125000 {
|
||||
compatible = "stericsson,ux500-msp-i2s";
|
||||
reg = <0x80125000 0x1000>;
|
||||
interrupts = <0 62 0x4>;
|
||||
v-ape-supply = <&db8500_vape_reg>;
|
||||
};
|
||||
|
||||
codec: ab8500-codec {
|
||||
compatible = "stericsson,ab8500-codec";
|
||||
stericsson,earpeice-cmv = <950>; /* Units in mV. */
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
* ux500 MSP (CPU-side Digital Audio Interface)
|
||||
|
||||
Required properties:
|
||||
- compatible :"stericsson,ux500-msp-i2s"
|
||||
- reg : Physical base address and length of the device's registers.
|
||||
|
||||
Optional properties:
|
||||
- interrupts : The interrupt output from the device.
|
||||
- <name>-supply : Phandle to the regulator <name> supply
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "stericsson,snd-soc-mop500";
|
||||
|
||||
stericsson,platform-pcm-dma = <&pcm>;
|
||||
stericsson,cpu-dai = <&msp1 &msp3>;
|
||||
stericsson,audio-codec = <&codec>;
|
||||
};
|
||||
|
||||
pcm: ux500-pcm {
|
||||
compatible = "stericsson,ux500-pcm";
|
||||
};
|
||||
|
||||
msp1: msp@80124000 {
|
||||
compatible = "stericsson,ux500-msp-i2s";
|
||||
reg = <0x80124000 0x1000>;
|
||||
interrupts = <0 62 0x4>;
|
||||
v-ape-supply = <&db8500_vape_reg>;
|
||||
};
|
||||
|
||||
msp3: msp@80125000 {
|
||||
compatible = "stericsson,ux500-msp-i2s";
|
||||
reg = <0x80125000 0x1000>;
|
||||
interrupts = <0 62 0x4>;
|
||||
v-ape-supply = <&db8500_vape_reg>;
|
||||
};
|
||||
|
||||
codec: ab8500-codec {
|
||||
compatible = "stericsson,ab8500-codec";
|
||||
stericsson,earpeice-cmv = <950>; /* Units in mV. */
|
||||
};
|
||||
@@ -561,6 +561,8 @@ patternProperties:
|
||||
description: Seiko Epson Corp.
|
||||
"^esp,.*":
|
||||
description: Espressif Systems Co. Ltd.
|
||||
"^esstech,.*":
|
||||
description: ESS Technology, Inc.
|
||||
"^est,.*":
|
||||
description: ESTeem Wireless Modems
|
||||
"^eswin,.*":
|
||||
|
||||
@@ -2407,6 +2407,12 @@ quirk_flags
|
||||
the requested rate. A device advertising a single rate is otherwise
|
||||
never sent the request at all, and some require it before streaming
|
||||
will start.
|
||||
* bit 33: ``swap_rates``
|
||||
The clock source applies a requested rate to the other base-rate
|
||||
family, i.e. asking for 44100 makes the device run at 48000 and vice
|
||||
versa (same for 88200 <-> 96000 and 176400 <-> 192000). The driver
|
||||
sends the partner rate in SET_CUR so the device ends up running at the
|
||||
requested one.
|
||||
|
||||
This module supports multiple devices, autoprobe and hotplugging.
|
||||
|
||||
|
||||
@@ -6,9 +6,11 @@ Software Interface ALSA-DSP MADI Driver
|
||||
|
||||
2004 - winfried ritsch
|
||||
|
||||
driver name - snd-hdspm
|
||||
|
||||
|
||||
Full functionality has been added to the driver. Since some of
|
||||
the Controls and startup-options are ALSA-Standard and only the
|
||||
the Controls and startup options are ALSA-Standard, only the
|
||||
special Controls are described and discussed below.
|
||||
|
||||
|
||||
@@ -18,7 +20,7 @@ Hardware functionality
|
||||
Audio transmission
|
||||
------------------
|
||||
|
||||
* number of channels -- depends on transmission mode
|
||||
* number of channels -- depends on transmission mode
|
||||
|
||||
The number of channels chosen is from 1..Nmax. The reason to
|
||||
use for a lower number of channels is only resource allocation,
|
||||
@@ -29,29 +31,29 @@ Audio transmission
|
||||
* Single Speed -- 1..64 channels
|
||||
|
||||
.. note::
|
||||
(Note: Choosing the 56channel mode for transmission or as
|
||||
Choosing the 56-channel mode for transmission or as
|
||||
receiver, only 56 are transmitted/received over the MADI, but
|
||||
all 64 channels are available for the mixer, so channel count
|
||||
for the driver)
|
||||
for the driver.
|
||||
|
||||
* Double Speed -- 1..32 channels
|
||||
|
||||
.. note::
|
||||
Note: Choosing the 56-channel mode for
|
||||
transmission/receive-mode , only 28 are transmitted/received
|
||||
Choosing the 56-channel mode for
|
||||
transmission/receive-mode, only 28 are transmitted/received
|
||||
over the MADI, but all 32 channels are available for the mixer,
|
||||
so channel count for the driver
|
||||
so channel count for the driver.
|
||||
|
||||
|
||||
* Quad Speed -- 1..16 channels
|
||||
|
||||
.. note::
|
||||
Choosing the 56-channel mode for
|
||||
transmission/receive-mode , only 14 are transmitted/received
|
||||
transmission/receive-mode, only 14 are transmitted/received
|
||||
over the MADI, but all 16 channels are available for the mixer,
|
||||
so channel count for the driver
|
||||
so channel count for the driver.
|
||||
|
||||
* Format -- signed 32 Bit Little Endian (SNDRV_PCM_FMTBIT_S32_LE)
|
||||
* Format -- signed 32-bit Little Endian (SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
||||
* Sample Rates --
|
||||
|
||||
@@ -67,30 +69,6 @@ Audio transmission
|
||||
|
||||
* fragments -- 2
|
||||
|
||||
* Hardware-pointer -- 2 Modi
|
||||
|
||||
|
||||
The Card supports the readout of the actual Buffer-pointer,
|
||||
where DMA reads/writes. Since of the bulk mode of PCI it is only
|
||||
64 Byte accurate. SO it is not really usable for the
|
||||
ALSA-mid-level functions (here the buffer-ID gives a better
|
||||
result), but if MMAP is used by the application. Therefore it
|
||||
can be configured at load-time with the parameter
|
||||
precise-pointer.
|
||||
|
||||
|
||||
.. hint::
|
||||
(Hint: Experimenting I found that the pointer is maximum 64 to
|
||||
large never to small. So if you subtract 64 you always have a
|
||||
safe pointer for writing, which is used on this mode inside
|
||||
ALSA. In theory now you can get now a latency as low as 16
|
||||
Samples, which is a quarter of the interrupt possibilities.)
|
||||
|
||||
* Precise Pointer -- off
|
||||
interrupt used for pointer-calculation
|
||||
|
||||
* Precise Pointer -- on
|
||||
hardware pointer used.
|
||||
|
||||
Controller
|
||||
----------
|
||||
@@ -104,7 +82,7 @@ hwdep-interface.
|
||||
Also all 128+256 Peak and RMS-Meter can be accessed via the
|
||||
hwdep-interface. Since it could be a performance problem always
|
||||
copying and converting Peak and RMS-Levels even if you just need
|
||||
one, I decided to export the hardware structure, so that of
|
||||
one, I decided to export the hardware structure, so that if
|
||||
needed some driver-guru can implement a memory-mapping of mixer
|
||||
or peak-meters over ioctl, or also to do only copying and no
|
||||
conversion. A test-application shows the usage of the controller.
|
||||
@@ -112,9 +90,9 @@ conversion. A test-application shows the usage of the controller.
|
||||
* Latency Controls --- not implemented !!!
|
||||
|
||||
.. note::
|
||||
Note: Within the windows-driver the latency is accessible of a
|
||||
control-panel, but buffer-sizes are controlled with ALSA from
|
||||
hwparams-calls and should not be changed in run-state, I did not
|
||||
Within the Windows driver the latency is accessible via
|
||||
Control Panel, but buffer sizes are controlled with ALSA from
|
||||
hwparams calls and should not be changed in run-state. I did not
|
||||
implement it here.
|
||||
|
||||
|
||||
@@ -127,12 +105,12 @@ conversion. A test-application shows the usage of the controller.
|
||||
* Values -- "Master" "Slave"
|
||||
|
||||
.. note::
|
||||
!!!! This is a hardware-function but is in conflict with the
|
||||
Clock-source controller, which is a kind of ALSA-standard. I
|
||||
!!!! This is a hardware function but is in conflict with the
|
||||
Clock-source controller, which is a kind of ALSA-standard. It
|
||||
makes sense to set the card to a special mode (master at some
|
||||
frequency or slave), since even not using an Audio-application
|
||||
frequency or slave), since even not using an Audio application
|
||||
a studio should have working synchronisations setup. So use
|
||||
Clock-source-controller instead !!!!
|
||||
Clock-source controller instead !!!!
|
||||
|
||||
* Clock Source
|
||||
|
||||
@@ -145,11 +123,11 @@ conversion. A test-application shows the usage of the controller.
|
||||
"Internal 96.0 kHz"
|
||||
|
||||
Choose between Master at a specific Frequency and so also the
|
||||
Speed-mode or Slave (Autosync). Also see "Preferred Sync Ref"
|
||||
Speed-mode or Slave (Autosync). Also see "Preferred Sync Ref".
|
||||
|
||||
.. warning::
|
||||
!!!! This is no pure hardware function but was implemented by
|
||||
ALSA by some ALSA-drivers before, so I use it also. !!!
|
||||
!!!! This is not a pure hardware function but was implemented by
|
||||
ALSA by some ALSA drivers before, so I use it also. !!!
|
||||
|
||||
|
||||
* Preferred Sync Ref
|
||||
@@ -165,7 +143,7 @@ conversion. A test-application shows the usage of the controller.
|
||||
chosen. If it is not available another is used if possible.
|
||||
|
||||
.. note::
|
||||
Note: Since MADI has a much higher bit-rate than word-clock, the
|
||||
Since MADI has a much higher bit-rate than word-clock, the
|
||||
card should synchronise better in MADI Mode. But since the
|
||||
RME-PLL is very good, there are almost no problems with
|
||||
word-clock too. I never found a difference.
|
||||
@@ -179,12 +157,12 @@ conversion. A test-application shows the usage of the controller.
|
||||
|
||||
* Values -- 0 1
|
||||
|
||||
Using 64-channel-modus (1) or 56-channel-modus for
|
||||
Using 64-channel mode (1) or 56-channel mode for
|
||||
MADI-transmission (0).
|
||||
|
||||
|
||||
.. note::
|
||||
Note: This control is for output only. Input-mode is detected
|
||||
This control is for output only. Input mode is detected
|
||||
automatically from hardware sending MADI.
|
||||
|
||||
|
||||
@@ -200,7 +178,7 @@ conversion. A test-application shows the usage of the controller.
|
||||
Don't use to lower 5 Audio-bits on AES as additional Bits.
|
||||
|
||||
|
||||
* Safe Mode oder Auto Input
|
||||
* Safe Mode or Auto Input
|
||||
|
||||
* Name -- "Safe Mode"
|
||||
|
||||
@@ -222,7 +200,7 @@ conversion. A test-application shows the usage of the controller.
|
||||
* Values -- optical coaxial
|
||||
|
||||
|
||||
Choosing the Input, optical or coaxial. If Safe-mode is active,
|
||||
Choosing the Input, optical or coaxial. If Safe mode is active,
|
||||
this is the preferred Input.
|
||||
|
||||
Mixer
|
||||
@@ -240,7 +218,7 @@ Mixer
|
||||
Here as a first value the channel-index is taken to get/set the
|
||||
corresponding mixer channel, where 0-63 are the input to output
|
||||
fader and 64-127 the playback to outputs fader. Value 0
|
||||
is channel muted 0 and 32768 an amplification of 1.
|
||||
is channel muted 0 and 32768 an amplification of 1.
|
||||
|
||||
* Chn 1-64
|
||||
|
||||
@@ -250,14 +228,14 @@ Mixer
|
||||
|
||||
* Line Out
|
||||
|
||||
* Name -- "Line Out"
|
||||
* Name -- "Line Out"
|
||||
|
||||
* Access -- Read Write
|
||||
|
||||
* Values -- 0 1
|
||||
|
||||
Switching on and off the analog out, which has nothing to do
|
||||
with mixing or routing. the analog outs reflects channel 63,64.
|
||||
with mixing or routing. The analog outs reflects channel 63,64.
|
||||
|
||||
|
||||
Information (only read access)
|
||||
@@ -280,7 +258,7 @@ Information (only read access)
|
||||
|
||||
|
||||
Should be "Autosync Rate", but Name used is
|
||||
ALSA-Scheme. External Sample frequency liked used on Autosync is
|
||||
ALSA-Scheme. External Sample frequency like used on Autosync is
|
||||
reported.
|
||||
|
||||
|
||||
@@ -315,19 +293,19 @@ Information (only read access)
|
||||
|
||||
Sync-Reference is either "WordClock", "MADI" or none.
|
||||
|
||||
* RX 64ch --- noch nicht implementiert
|
||||
* RX 64ch --- not yet implemented
|
||||
|
||||
MADI-Receiver is in 64 channel mode oder 56 channel mode.
|
||||
MADI-Receiver is in 64-channel mode or 56-channel mode.
|
||||
|
||||
|
||||
* AB_inp --- not tested
|
||||
* AB_inp --- not tested
|
||||
|
||||
Used input for Auto-Input.
|
||||
|
||||
|
||||
* actual Buffer Position --- not implemented
|
||||
|
||||
!!! this is a ALSA internal function, so no control is used !!!
|
||||
!!! This is an ALSA internal function, so no control is used !!!
|
||||
|
||||
|
||||
|
||||
@@ -352,22 +330,15 @@ Calling Parameter
|
||||
|
||||
note: ALSA-standard
|
||||
|
||||
* precise_ptr int array (min = 1, max = 8)
|
||||
|
||||
Enable precise pointer, or disable.
|
||||
|
||||
.. note::
|
||||
note: Use only when the application supports this (which is a special case).
|
||||
|
||||
* line_outs_monitor int array (min = 1, max = 8)
|
||||
|
||||
Send playback streams to analog outs by default.
|
||||
|
||||
.. note::
|
||||
note: each playback channel is mixed to the same numbered output
|
||||
Each playback channel is mixed to the same numbered output
|
||||
channel (routed). This is against the ALSA-convention, where all
|
||||
channels have to be muted on after loading the driver, but was
|
||||
used before on other cards, so i historically use it again)
|
||||
used before on other cards, so I historically use it again.
|
||||
|
||||
|
||||
|
||||
@@ -375,5 +346,5 @@ Calling Parameter
|
||||
|
||||
Enable Analog Out on Channel 63/64 by default.
|
||||
|
||||
.. note ::
|
||||
note: here the analog output is enabled (but not routed).
|
||||
.. note::
|
||||
Here the analog output is enabled (but not routed).
|
||||
+40
@@ -779,6 +779,14 @@ F: Documentation/devicetree/bindings/phy/airoha,en7581-pcie-phy.yaml
|
||||
F: drivers/phy/phy-airoha-pcie-regs.h
|
||||
F: drivers/phy/phy-airoha-pcie.c
|
||||
|
||||
AIROHA SOUND DRIVER
|
||||
M: Christian Marangi <ansuelsmth@gmail.com>
|
||||
L: linux-sound@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/airoha,an7581-afe.yaml
|
||||
F: Documentation/devicetree/bindings/sound/airoha,an7581-wm8960.yaml
|
||||
F: sound/soc/mediatek/an7581/*
|
||||
|
||||
AIROHA SPI SNFI DRIVER
|
||||
M: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
M: Ray Liu <ray.liu@airoha.com>
|
||||
@@ -4399,6 +4407,13 @@ F: drivers/net/ieee802154/at86rf230.h
|
||||
F: drivers/net/ieee802154/atusb.c
|
||||
F: drivers/net/ieee802154/atusb.h
|
||||
|
||||
AUDIENT EVO MIXER DRIVER
|
||||
M: Christian Ruppert <arc@gmx.li>
|
||||
L: linux-sound@vger.kernel.org
|
||||
S: Maintained
|
||||
F: sound/usb/mixer_evo.c
|
||||
F: sound/usb/mixer_evo.h
|
||||
|
||||
AUDIT SUBSYSTEM
|
||||
M: Paul Moore <paul@paul-moore.com>
|
||||
M: Eric Paris <eparis@redhat.com>
|
||||
@@ -4472,6 +4487,12 @@ L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/media/pci/hws/
|
||||
|
||||
AWINIC AW88399 HDA SIDE CODEC DRIVER
|
||||
M: Marco Giunta <marco_giunta@outlook.it>
|
||||
L: linux-sound@vger.kernel.org
|
||||
S: Maintained
|
||||
F: sound/hda/codecs/side-codecs/aw88399*
|
||||
|
||||
AWINIC AW99706 WLED BACKLIGHT DRIVER
|
||||
M: Junjie Cao <junjie.cao@linux.dev>
|
||||
S: Maintained
|
||||
@@ -9874,6 +9895,13 @@ S: Maintained
|
||||
F: include/linux/errseq.h
|
||||
F: lib/errseq.c
|
||||
|
||||
ES9039Q2M AUDIO CODEC DRIVER
|
||||
M: Karl Asseily <karl@asseily.com>
|
||||
L: linux-sound@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/esstech,es9039q2m.yaml
|
||||
F: sound/soc/codecs/es9039q2m.c
|
||||
|
||||
ESD CAN NETWORK DRIVERS
|
||||
M: Stefan Mätje <stefan.maetje@esd.eu>
|
||||
R: socketcan@esd.eu
|
||||
@@ -22395,6 +22423,15 @@ F: sound/soc/codecs/wcd93*.*
|
||||
F: sound/soc/codecs/wsa88*.*
|
||||
F: sound/soc/qcom/
|
||||
|
||||
QCOM AUDIO INTERFACE (QAIF) DRIVER
|
||||
M: Harendra Gautam <harendra.gautam@oss.qualcomm.com>
|
||||
M: Srinivas Kandagatla <srini@kernel.org>
|
||||
L: linux-sound@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/sound/qcom,shikra-qaif-cpu.yaml
|
||||
F: sound/soc/qcom/qaif*
|
||||
|
||||
QCOM EMBEDDED USB DEBUGGER (EUD)
|
||||
M: Souradeep Chowdhury <quic_schowdhu@quicinc.com>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
@@ -30630,9 +30667,12 @@ F: tools/testing/selftests/cgroup/test_zswap.c
|
||||
|
||||
SENARYTECH AUDIO CODEC DRIVER
|
||||
M: bo liu <bo.liu@senarytech.com>
|
||||
M: qianghua.wang <qianghua.wang@senarytech.com>
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
|
||||
F: sound/hda/codecs/senarytech.c
|
||||
F: sound/soc/codecs/sn624x*
|
||||
F: sound/soc/sdw_utils/soc_sdw_senary*
|
||||
|
||||
ZTE DINGHAI ETHERNET DRIVER
|
||||
M: Junyang Han <han.junyang@zte.com.cn>
|
||||
|
||||
@@ -1763,6 +1763,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
|
||||
/* Non-conforming _HID for Cirrus Logic already released */
|
||||
{"CLSA0100", },
|
||||
{"CLSA0101", },
|
||||
{"CLSA0102", },
|
||||
/*
|
||||
* Some ACPI devs contain SerialBus resources even though they are not
|
||||
* attached to a serial bus at all.
|
||||
|
||||
@@ -2960,6 +2960,8 @@ int cs_dsp_run(struct cs_dsp *dsp)
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dsp->running = false;
|
||||
|
||||
if (dsp->ops->stop_core)
|
||||
dsp->ops->stop_core(dsp);
|
||||
if (dsp->ops->disable_core)
|
||||
@@ -3505,7 +3507,7 @@ EXPORT_SYMBOL_NS_GPL(cs_dsp_chunk_write, "FW_CS_DSP");
|
||||
*
|
||||
* As cs_dsp_chunk_write only writes data when a whole DSP word is ready to
|
||||
* be written out it is possible that some data will remain in the cache, this
|
||||
* function will pad that data with zeros upto a whole DSP word and write out.
|
||||
* function will pad that data with zeros up to a whole DSP word and write out.
|
||||
*
|
||||
* Return: Zero for success, a negative number on error.
|
||||
*/
|
||||
|
||||
@@ -36,6 +36,8 @@ struct cs_dsp_test_local {
|
||||
int num_post_stop;
|
||||
int num_watchdog_expired;
|
||||
|
||||
bool fail_post_run;
|
||||
|
||||
struct cs_dsp_coeff_ctl *passed_ctl[16];
|
||||
struct cs_dsp *passed_dsp;
|
||||
};
|
||||
@@ -106,6 +108,9 @@ static int cs_dsp_test_post_run_callback(struct cs_dsp *dsp)
|
||||
local->passed_dsp = dsp;
|
||||
local->num_post_run++;
|
||||
|
||||
if (local->fail_post_run)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -198,6 +203,33 @@ static void cs_dsp_test_run_stop_callbacks(struct kunit *test)
|
||||
local->passed_dsp = NULL;
|
||||
}
|
||||
|
||||
static void cs_dsp_test_run_error_clears_running(struct kunit *test)
|
||||
{
|
||||
struct cs_dsp_test *priv = test->priv;
|
||||
struct cs_dsp_test_local *local = priv->local;
|
||||
struct firmware *wmfw;
|
||||
|
||||
wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder);
|
||||
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
cs_dsp_power_up(priv->dsp, wmfw, "wmfw", NULL, NULL, "misc"),
|
||||
0);
|
||||
|
||||
/*
|
||||
* By the time the post_run hook runs, the core has been started. A
|
||||
* failure there stops and disables the core again, so the DSP must not
|
||||
* be left looking like it is running.
|
||||
*/
|
||||
local->fail_post_run = true;
|
||||
KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), -EIO);
|
||||
KUNIT_EXPECT_FALSE(test, priv->dsp->running);
|
||||
|
||||
/* and the next run must be able to start it again */
|
||||
local->fail_post_run = false;
|
||||
KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), 0);
|
||||
KUNIT_EXPECT_TRUE(test, priv->dsp->running);
|
||||
}
|
||||
|
||||
static void cs_dsp_test_ctl_v1_callbacks(struct kunit *test)
|
||||
{
|
||||
struct cs_dsp_test *priv = test->priv;
|
||||
@@ -609,6 +641,7 @@ KUNIT_ARRAY_PARAM(cs_dsp_no_callbacks,
|
||||
|
||||
static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv1_test_cases[] = {
|
||||
KUNIT_CASE_PARAM(cs_dsp_test_run_stop_callbacks, cs_dsp_callbacks_ops_gen_params),
|
||||
KUNIT_CASE_PARAM(cs_dsp_test_run_error_clears_running, cs_dsp_callbacks_ops_gen_params),
|
||||
KUNIT_CASE_PARAM(cs_dsp_test_ctl_v1_callbacks, cs_dsp_callbacks_ops_gen_params),
|
||||
KUNIT_CASE_PARAM(cs_dsp_test_no_callbacks, cs_dsp_no_callbacks_gen_params),
|
||||
|
||||
@@ -617,6 +650,7 @@ static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv1_test_cases[] = {
|
||||
|
||||
static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv2_test_cases[] = {
|
||||
KUNIT_CASE_PARAM(cs_dsp_test_run_stop_callbacks, cs_dsp_callbacks_ops_gen_params),
|
||||
KUNIT_CASE_PARAM(cs_dsp_test_run_error_clears_running, cs_dsp_callbacks_ops_gen_params),
|
||||
KUNIT_CASE_PARAM(cs_dsp_test_ctl_v2_callbacks, cs_dsp_callbacks_ops_gen_params),
|
||||
KUNIT_CASE_PARAM(cs_dsp_test_no_callbacks, cs_dsp_no_callbacks_gen_params),
|
||||
|
||||
@@ -625,6 +659,7 @@ static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv2_test_cases[] = {
|
||||
|
||||
static struct kunit_case cs_dsp_callbacks_halo_test_cases[] = {
|
||||
KUNIT_CASE_PARAM(cs_dsp_test_run_stop_callbacks, cs_dsp_callbacks_ops_gen_params),
|
||||
KUNIT_CASE_PARAM(cs_dsp_test_run_error_clears_running, cs_dsp_callbacks_ops_gen_params),
|
||||
KUNIT_CASE_PARAM(cs_dsp_test_ctl_v2_callbacks, cs_dsp_callbacks_ops_gen_params),
|
||||
KUNIT_CASE_PARAM(cs_dsp_test_no_callbacks, cs_dsp_no_callbacks_gen_params),
|
||||
|
||||
|
||||
@@ -1458,11 +1458,15 @@ static int fmh_gpib_attach_impl(struct gpib_board *board, const struct gpib_boar
|
||||
e_priv->irq = irq;
|
||||
|
||||
if (acquire_dma) {
|
||||
e_priv->dma_channel = dma_request_slave_channel(board->dev, "rxtx");
|
||||
if (!e_priv->dma_channel) {
|
||||
struct dma_chan *tmp_chan;
|
||||
|
||||
tmp_chan = dma_request_chan(board->dev, "rxtx");
|
||||
retval = PTR_ERR_OR_ZERO(tmp_chan);
|
||||
if (retval) {
|
||||
dev_err(board->dev, "failed to acquire dma channel \"rxtx\".\n");
|
||||
return -EIO;
|
||||
return retval;
|
||||
}
|
||||
e_priv->dma_channel = tmp_chan;
|
||||
}
|
||||
/*
|
||||
* in the future we might want to know the half-fifo size
|
||||
|
||||
@@ -426,6 +426,7 @@ static const struct acpi_device_id smi_acpi_ids[] = {
|
||||
/* Non-conforming _HID for Cirrus Logic already released */
|
||||
{ "CLSA0100", (unsigned long)&cs35l41_hda },
|
||||
{ "CLSA0101", (unsigned long)&cs35l41_hda },
|
||||
{ "CLSA0102", (unsigned long)&cs35l41_hda },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, smi_acpi_ids);
|
||||
|
||||
@@ -17,6 +17,33 @@
|
||||
#define CS35L45_ASP_TX_HIZ_UNUSED 0x1
|
||||
#define CS35L45_ASP_TX_HIZ_DISABLED 0x2
|
||||
|
||||
/*
|
||||
* cirrus,boost-low-power-mode
|
||||
*
|
||||
* BST_LPMODE_NO_REACTION: No reaction
|
||||
* BST_LPMODE_DCM_MODE: Force boost DCM low power mode
|
||||
* BST_LPMODE_STATIC_BYPASS: Force boost static bypass
|
||||
*/
|
||||
#define CS35L45_BST_LPMODE_NO_REACTION 0x0
|
||||
#define CS35L45_BST_LPMODE_DCM_MODE 0x1
|
||||
#define CS35L45_BST_LPMODE_STATIC_BYPASS 0x2
|
||||
|
||||
/*
|
||||
* cirrus,amplifier-low-power-mode
|
||||
*
|
||||
* AMP_LPMODE_NG_MODE: Noise gate mode
|
||||
* AMP_LPMODE_NFR_MODE: Noise floor reduction mode
|
||||
*/
|
||||
#define CS35L45_AMP_LPMODE_NG_MODE 0x0
|
||||
#define CS35L45_AMP_LPMODE_NFR_MODE 0x1
|
||||
|
||||
/*
|
||||
* cirrus,ldpm-groupX-pcm-threshold-db
|
||||
*
|
||||
* LDPM_PCM_THLD_TRUE_ZERO:
|
||||
*/
|
||||
#define CS35L45_LDPM_PCM_THLD_TRUE_ZERO -2147483648
|
||||
|
||||
/*
|
||||
* Optional GPIOX Sub-nodes:
|
||||
* The cs35l45 node can have up to three "cirrus,gpio-ctrlX" ('X' = [1,2,3])
|
||||
|
||||
@@ -156,6 +156,58 @@
|
||||
#define LPI_MI2S_TX_5 150
|
||||
#define LPI_MI2S_RX_6 151
|
||||
#define LPI_MI2S_TX_6 152
|
||||
#define AIF_MI2S_RX_0 153
|
||||
#define AIF_MI2S_TX_0 154
|
||||
#define AIF_MI2S_RX_1 155
|
||||
#define AIF_MI2S_TX_1 156
|
||||
#define AIF_MI2S_RX_2 157
|
||||
#define AIF_MI2S_TX_2 158
|
||||
#define AIF_MI2S_RX_3 159
|
||||
#define AIF_MI2S_TX_3 160
|
||||
#define AIF_MI2S_RX_4 161
|
||||
#define AIF_MI2S_TX_4 162
|
||||
#define AIF_MI2S_RX_5 163
|
||||
#define AIF_MI2S_TX_5 164
|
||||
#define AIF_MI2S_RX_6 165
|
||||
#define AIF_MI2S_TX_6 166
|
||||
#define AIF_MI2S_RX_7 167
|
||||
#define AIF_MI2S_TX_7 168
|
||||
#define AIF_MI2S_RX_8 169
|
||||
#define AIF_MI2S_TX_8 170
|
||||
#define AIF_MI2S_RX_9 171
|
||||
#define AIF_MI2S_TX_9 172
|
||||
#define AIF_MI2S_RX_10 173
|
||||
#define AIF_MI2S_TX_10 174
|
||||
#define AIF_MI2S_RX_11 175
|
||||
#define AIF_MI2S_TX_11 176
|
||||
#define AIF_MI2S_RX_12 177
|
||||
#define AIF_MI2S_TX_12 178
|
||||
#define AIF_TDM_RX_0 179
|
||||
#define AIF_TDM_TX_0 180
|
||||
#define AIF_TDM_RX_1 181
|
||||
#define AIF_TDM_TX_1 182
|
||||
#define AIF_TDM_RX_2 183
|
||||
#define AIF_TDM_TX_2 184
|
||||
#define AIF_TDM_RX_3 185
|
||||
#define AIF_TDM_TX_3 186
|
||||
#define AIF_TDM_RX_4 187
|
||||
#define AIF_TDM_TX_4 188
|
||||
#define AIF_TDM_RX_5 189
|
||||
#define AIF_TDM_TX_5 190
|
||||
#define AIF_TDM_RX_6 191
|
||||
#define AIF_TDM_TX_6 192
|
||||
#define AIF_TDM_RX_7 193
|
||||
#define AIF_TDM_TX_7 194
|
||||
#define AIF_TDM_RX_8 195
|
||||
#define AIF_TDM_TX_8 196
|
||||
#define AIF_TDM_RX_9 197
|
||||
#define AIF_TDM_TX_9 198
|
||||
#define AIF_TDM_RX_10 199
|
||||
#define AIF_TDM_TX_10 200
|
||||
#define AIF_TDM_RX_11 201
|
||||
#define AIF_TDM_TX_11 202
|
||||
#define AIF_TDM_RX_12 203
|
||||
#define AIF_TDM_TX_12 204
|
||||
|
||||
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
|
||||
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2
|
||||
|
||||
@@ -1760,15 +1760,6 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
|
||||
#define dma_request_channel(mask, x, y) \
|
||||
__dma_request_channel(&(mask), x, y, NULL)
|
||||
|
||||
/* Deprecated, please use dma_request_chan() directly */
|
||||
static inline struct dma_chan * __deprecated
|
||||
dma_request_slave_channel(struct device *dev, const char *name)
|
||||
{
|
||||
struct dma_chan *ch = dma_request_chan(dev, name);
|
||||
|
||||
return IS_ERR(ch) ? NULL : ch;
|
||||
}
|
||||
|
||||
static inline struct dma_chan
|
||||
*dma_request_slave_channel_compat(const dma_cap_mask_t mask,
|
||||
dma_filter_fn fn, void *fn_param,
|
||||
|
||||
@@ -96,7 +96,7 @@ struct cs_dsp_alg_region {
|
||||
struct cs_dsp_coeff_ctl {
|
||||
struct list_head list;
|
||||
struct cs_dsp *dsp;
|
||||
void *cache;
|
||||
void *cache __counted_by_ptr(len);
|
||||
const char *fw_name;
|
||||
/* Subname is needed to match with firmware */
|
||||
const char *subname;
|
||||
|
||||
@@ -449,6 +449,11 @@
|
||||
#define AW88399_NOISE_GATE_EN_MASK \
|
||||
(~(((1<<AW88399_NOISE_GATE_EN_BITS_LEN)-1) << AW88399_NOISE_GATE_EN_START_BIT))
|
||||
|
||||
#define AW88399_EPS_EN_START_BIT (2)
|
||||
#define AW88399_EPS_EN_BITS_LEN (1)
|
||||
#define AW88399_EPS_EN_MASK \
|
||||
(~(((1 << AW88399_EPS_EN_BITS_LEN) - 1) << AW88399_EPS_EN_START_BIT))
|
||||
|
||||
#define AW88399_WDT_CNT_START_BIT (0)
|
||||
#define AW88399_WDT_CNT_BITS_LEN (8)
|
||||
#define AW88399_WDT_CNT_MASK \
|
||||
@@ -598,7 +603,6 @@ struct aw88399 {
|
||||
unsigned int crc_init_val;
|
||||
unsigned int vcalb_init_val;
|
||||
unsigned int dither_st;
|
||||
bool bsts_unreliable;
|
||||
bool fw_needs_reload;
|
||||
};
|
||||
|
||||
@@ -613,7 +617,7 @@ void aw88399_dev_set_channel(struct aw88399 *aw88399, int channel);
|
||||
void aw88399_hw_reset(struct aw88399 *aw88399);
|
||||
int aw88399_init(struct aw88399 *aw88399, struct i2c_client *i2c, struct regmap *regmap);
|
||||
extern const struct regmap_config aw88399_remap_config;
|
||||
int aw88399_request_firmware_file(struct aw88399 *aw88399);
|
||||
int aw88399_request_firmware_file(struct aw88399 *aw88399, const char *fw_name);
|
||||
void aw88399_start(struct aw88399 *aw88399, bool sync_start);
|
||||
void aw88399_startup_work(struct work_struct *work);
|
||||
int aw88399_stop(struct aw_device *aw_dev);
|
||||
|
||||
@@ -188,6 +188,7 @@ struct snd_compr_ops {
|
||||
* @card: sound card pointer
|
||||
* @direction: Playback or capture direction
|
||||
* @lock: device lock
|
||||
* @open_list: list of open compress files
|
||||
* @device: device id
|
||||
* @use_pause_in_draining: allow pause in draining, true when set
|
||||
*/
|
||||
@@ -199,6 +200,7 @@ struct snd_compr {
|
||||
struct snd_card *card;
|
||||
unsigned int direction;
|
||||
struct mutex lock;
|
||||
struct list_head open_list;
|
||||
int device;
|
||||
bool use_pause_in_draining;
|
||||
#ifdef CONFIG_SND_VERBOSE_PROCFS
|
||||
|
||||
@@ -244,7 +244,7 @@ int _snd_ctl_add_follower(struct snd_kcontrol *master,
|
||||
* @follower: follower element to add
|
||||
*
|
||||
* Add a virtual follower control to the given master element created via
|
||||
* snd_ctl_create_virtual_master() beforehand.
|
||||
* snd_ctl_make_virtual_master() beforehand.
|
||||
*
|
||||
* All followers must be the same type (returning the same information
|
||||
* via info callback). The function doesn't check it, so it's your
|
||||
@@ -289,7 +289,7 @@ snd_ctl_add_follower_uncached(struct snd_kcontrol *master,
|
||||
return _snd_ctl_add_follower(master, follower, SND_CTL_FOLLOWER_NEED_UPDATE);
|
||||
}
|
||||
|
||||
int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
|
||||
int snd_ctl_add_vmaster_hook(struct snd_card *card, struct snd_kcontrol *kctl,
|
||||
void (*hook)(void *private_data, int),
|
||||
void *private_data);
|
||||
void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
|
||||
|
||||
@@ -84,6 +84,7 @@ struct snd_device {
|
||||
struct snd_refcount {
|
||||
atomic_t count;
|
||||
wait_queue_head_t waiter;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
void snd_refcount_init(struct snd_refcount *ref);
|
||||
@@ -300,7 +301,8 @@ int snd_card_locked(int card);
|
||||
#define SND_MIXER_OSS_NOTIFY_REGISTER 0
|
||||
#define SND_MIXER_OSS_NOTIFY_DISCONNECT 1
|
||||
#define SND_MIXER_OSS_NOTIFY_FREE 2
|
||||
extern int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int cmd);
|
||||
void snd_mixer_oss_set_notify(int (*callback)(struct snd_card *card, int cmd));
|
||||
void snd_mixer_oss_notify(struct snd_card *card, int cmd);
|
||||
#endif
|
||||
|
||||
int snd_card_new(struct device *parent, int idx, const char *xid,
|
||||
@@ -314,7 +316,6 @@ void snd_card_disconnect(struct snd_card *card);
|
||||
void snd_card_disconnect_sync(struct snd_card *card);
|
||||
void snd_card_free(struct snd_card *card);
|
||||
void snd_card_free_when_closed(struct snd_card *card);
|
||||
int snd_card_free_on_error(struct device *dev, int ret);
|
||||
void snd_card_set_id(struct snd_card *card, const char *id);
|
||||
int snd_card_register(struct snd_card *card);
|
||||
int snd_card_info_init(void);
|
||||
|
||||
@@ -633,8 +633,8 @@ SUB_REG(PEFE, FILTERAMOUNT, 0x000000ff) /* Filter envlope amount */
|
||||
#define A_ADCCR_RCHANENABLE 0x00000020
|
||||
#define A_ADCCR_LCHANENABLE 0x00000010
|
||||
|
||||
#define A_ADCCR_SAMPLERATE_MASK 0x0000000F /* Audigy sample rate convertor output rate */
|
||||
#define ADCCR_SAMPLERATE_MASK 0x00000007 /* Sample rate convertor output rate */
|
||||
#define A_ADCCR_SAMPLERATE_MASK 0x0000000F /* Audigy sample rate converter output rate */
|
||||
#define ADCCR_SAMPLERATE_MASK 0x00000007 /* Sample rate converter output rate */
|
||||
#define ADCCR_SAMPLERATE_48 0x00000000 /* 48kHz sample rate */
|
||||
#define ADCCR_SAMPLERATE_44 0x00000001 /* 44.1kHz sample rate */
|
||||
#define ADCCR_SAMPLERATE_32 0x00000002 /* 32kHz sample rate */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
|
||||
*
|
||||
* Definitions of OSS compatible headers for Emu8000 device informations
|
||||
* Definitions of OSS compatible headers for Emu8000 device information
|
||||
*/
|
||||
|
||||
#include <sound/seq_oss_legacy.h>
|
||||
|
||||
@@ -28,6 +28,7 @@ struct hda_codec;
|
||||
struct hda_pcm;
|
||||
struct hda_pcm_stream;
|
||||
struct hda_codec_ops;
|
||||
struct hda_jack_tbl;
|
||||
|
||||
/*
|
||||
* codec bus
|
||||
@@ -274,7 +275,8 @@ struct hda_codec {
|
||||
struct hda_codec *codec, hda_nid_t nid);
|
||||
|
||||
/* jack detection */
|
||||
struct snd_array jacktbl;
|
||||
struct hda_jack_tbl *jacktbl, *jacktbl_last; /* linked list head/tail */
|
||||
int jacktbl_used; /* number of jacktbl elements */
|
||||
unsigned long jackpoll_interval; /* In jiffies. Zero means no poll, rely on unsol events */
|
||||
struct delayed_work jackpoll_work;
|
||||
|
||||
@@ -519,7 +521,7 @@ void snd_hda_update_power_acct(struct hda_codec *codec);
|
||||
|
||||
static inline bool hda_codec_need_resume(struct hda_codec *codec)
|
||||
{
|
||||
return !codec->relaxed_resume && codec->jacktbl.used;
|
||||
return !codec->relaxed_resume && codec->jacktbl_used;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -96,7 +96,8 @@ struct hdac_device {
|
||||
bool lazy_cache:1; /* don't wake up for writes */
|
||||
bool caps_overwriting:1; /* caps overwrite being in process */
|
||||
bool cache_coef:1; /* cache COEF read/write too */
|
||||
unsigned int registered:1; /* codec was registered */
|
||||
bool registered; /* codec was registered */
|
||||
bool unsol_disabled; /* unsol events blocked; protected by bus->reg_lock */
|
||||
};
|
||||
|
||||
/* device/driver type used for matching */
|
||||
@@ -123,6 +124,7 @@ int snd_hdac_device_init(struct hdac_device *dev, struct hdac_bus *bus,
|
||||
const char *name, unsigned int addr);
|
||||
void snd_hdac_device_exit(struct hdac_device *dev);
|
||||
int snd_hdac_device_register(struct hdac_device *codec);
|
||||
void snd_hdac_device_disable_unsol(struct hdac_device *codec);
|
||||
void snd_hdac_device_unregister(struct hdac_device *codec);
|
||||
int snd_hdac_device_set_chip_name(struct hdac_device *codec, const char *name);
|
||||
int snd_hdac_codec_modalias(const struct hdac_device *hdac, char *buf, size_t size);
|
||||
@@ -179,9 +181,9 @@ static inline int snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid,
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int snd_hdac_power_up(struct hdac_device *codec);
|
||||
int snd_hdac_power_down(struct hdac_device *codec);
|
||||
void snd_hdac_power_down(struct hdac_device *codec);
|
||||
int snd_hdac_power_up_pm(struct hdac_device *codec);
|
||||
int snd_hdac_power_down_pm(struct hdac_device *codec);
|
||||
void snd_hdac_power_down_pm(struct hdac_device *codec);
|
||||
int snd_hdac_keep_power_up(struct hdac_device *codec);
|
||||
|
||||
/* call this at entering into suspend/resume callbacks in codec driver */
|
||||
@@ -207,9 +209,9 @@ static inline bool snd_hdac_is_power_on(struct hdac_device *codec)
|
||||
}
|
||||
#else
|
||||
static inline int snd_hdac_power_up(struct hdac_device *codec) { return 0; }
|
||||
static inline int snd_hdac_power_down(struct hdac_device *codec) { return 0; }
|
||||
static inline void snd_hdac_power_down(struct hdac_device *codec) {}
|
||||
static inline int snd_hdac_power_up_pm(struct hdac_device *codec) { return 0; }
|
||||
static inline int snd_hdac_power_down_pm(struct hdac_device *codec) { return 0; }
|
||||
static inline void snd_hdac_power_down_pm(struct hdac_device *codec) {}
|
||||
static inline int snd_hdac_keep_power_up(struct hdac_device *codec) { return 0; }
|
||||
static inline void snd_hdac_enter_pm(struct hdac_device *codec) {}
|
||||
static inline void snd_hdac_leave_pm(struct hdac_device *codec) {}
|
||||
|
||||
@@ -62,10 +62,10 @@ struct snd_jack {
|
||||
struct list_head kctl_list;
|
||||
struct snd_card *card;
|
||||
const char *id;
|
||||
bool registered;
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
struct input_dev *input_dev;
|
||||
struct mutex input_dev_lock;
|
||||
int registered;
|
||||
int type;
|
||||
char name[100];
|
||||
unsigned int key[6]; /* Keep in sync with definitions above */
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* Abramo Bagnara <abramo@alsa-project.org>
|
||||
*/
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/asound.h>
|
||||
#include <sound/memalloc.h>
|
||||
#include <sound/minors.h>
|
||||
@@ -414,6 +415,7 @@ struct snd_pcm_runtime {
|
||||
snd_pcm_uframes_t twake; /* do transfer (!poll) wakeup if non-zero */
|
||||
wait_queue_head_t sleep; /* poll sleep */
|
||||
wait_queue_head_t tsleep; /* transfer sleep */
|
||||
struct snd_refcount refcnt; /* refcount for draining, etc */
|
||||
struct snd_fasync *fasync;
|
||||
bool stop_operating; /* sync_stop will be called */
|
||||
struct mutex buffer_mutex; /* protect for buffer changes */
|
||||
|
||||
@@ -70,6 +70,7 @@ struct snd_pcm_oss_stream {
|
||||
struct snd_pcm_oss {
|
||||
int reg;
|
||||
unsigned int reg_mask;
|
||||
bool registered;
|
||||
};
|
||||
|
||||
#endif /* __SOUND_PCM_OSS_H */
|
||||
@@ -86,6 +86,7 @@ struct snd_rawmidi_substream {
|
||||
bool opened; /* open flag */
|
||||
bool append; /* append flag (merge more streams) */
|
||||
bool active_sensing; /* send active sensing when close */
|
||||
bool disconnected; /* already disconnected */
|
||||
unsigned int framing; /* whether to frame input data */
|
||||
unsigned int clock_type; /* clock source to use for input framing */
|
||||
int use_count; /* use counter (for output) */
|
||||
|
||||
+18
-5
@@ -60,20 +60,16 @@ enum sdca_quirk {
|
||||
SDCA_QUIRKS_SKIP_FUNC_TYPE_PATCHING,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA)
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_SDCA)
|
||||
|
||||
void sdca_lookup_functions(struct sdw_slave *slave);
|
||||
void sdca_lookup_swft(struct sdw_slave *slave);
|
||||
void sdca_lookup_interface_revision(struct sdw_slave *slave);
|
||||
bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk);
|
||||
int sdca_dev_register_functions(struct sdw_slave *slave);
|
||||
void sdca_dev_unregister_functions(struct sdw_slave *slave);
|
||||
|
||||
#else
|
||||
|
||||
static inline void sdca_lookup_functions(struct sdw_slave *slave) {}
|
||||
static inline void sdca_lookup_swft(struct sdw_slave *slave) {}
|
||||
static inline void sdca_lookup_interface_revision(struct sdw_slave *slave) {}
|
||||
static inline bool sdca_device_quirk_match(struct sdw_slave *slave, enum sdca_quirk quirk)
|
||||
{
|
||||
return false;
|
||||
@@ -88,4 +84,21 @@ static inline void sdca_dev_unregister_functions(struct sdw_slave *slave) {}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Called from the SoundWire bus during peripheral enumeration; gated on
|
||||
* ACPI to avoid a soundwire_bus <-> snd_soc_sdca module cycle on DT builds
|
||||
* (where the bodies are stubs anyway).
|
||||
*/
|
||||
#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_SOC_SDCA)
|
||||
|
||||
void sdca_lookup_functions(struct sdw_slave *slave);
|
||||
void sdca_lookup_interface_revision(struct sdw_slave *slave);
|
||||
|
||||
#else
|
||||
|
||||
static inline void sdca_lookup_functions(struct sdw_slave *slave) {}
|
||||
static inline void sdca_lookup_interface_revision(struct sdw_slave *slave) {}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* The MIPI SDCA specification is available for public downloads at
|
||||
* https://www.mipi.org/mipi-sdca-v1-0-download
|
||||
*
|
||||
* Copyright (C) 2025 Cirrus Logic, Inc. and
|
||||
* Cirrus Logic International Semiconductor Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __SDCA_CLASS_H__
|
||||
#define __SDCA_CLASS_H__
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
struct device;
|
||||
struct regmap;
|
||||
struct sdw_slave;
|
||||
struct sdca_function_data;
|
||||
|
||||
/**
|
||||
* struct sdca_class_ops - optional codec-provided class callbacks
|
||||
* @populate_function: fill @function (entities, clusters, init_table, ...)
|
||||
* from static tables in place of sdca_parse_function() on
|
||||
* DT/non-DisCo platforms. Called once per SDCA function with
|
||||
* @dev pointing at that function's device. Pure data source;
|
||||
* performs no bus I/O. Return 0 on success or a negative errno.
|
||||
*/
|
||||
struct sdca_class_ops {
|
||||
int (*populate_function)(struct device *dev,
|
||||
struct sdca_function_data *function);
|
||||
};
|
||||
|
||||
struct sdca_class_drv {
|
||||
struct device *dev;
|
||||
struct regmap *dev_regmap;
|
||||
struct sdw_slave *sdw;
|
||||
|
||||
struct sdca_interrupt_info *irq_info;
|
||||
|
||||
const struct sdca_class_ops *ops;
|
||||
|
||||
struct mutex regmap_lock;
|
||||
/* Serialise function initialisations */
|
||||
struct mutex init_lock;
|
||||
struct work_struct boot_work;
|
||||
};
|
||||
|
||||
/* Library helpers used by codec-specific SDCA SoundWire drivers. */
|
||||
int sdca_class_probe(struct sdw_slave *sdw,
|
||||
struct sdca_class_drv *drv,
|
||||
const struct sdca_class_ops *ops);
|
||||
void sdca_class_remove(struct sdca_class_drv *drv);
|
||||
|
||||
/*
|
||||
* PM helpers. Codec drivers embed sdca_class_drv in their own priv,
|
||||
* own dev_set_drvdata(), and compose these into their own dev_pm_ops:
|
||||
*
|
||||
* static int wcd_runtime_suspend(struct device *dev) {
|
||||
* struct wcd_priv *priv = dev_get_drvdata(dev);
|
||||
* return sdca_class_runtime_suspend(&priv->class);
|
||||
* }
|
||||
*/
|
||||
int sdca_class_runtime_suspend(struct sdca_class_drv *drv);
|
||||
int sdca_class_runtime_resume(struct sdca_class_drv *drv);
|
||||
int sdca_class_system_suspend(struct sdca_class_drv *drv);
|
||||
int sdca_class_system_resume(struct sdca_class_drv *drv);
|
||||
|
||||
#endif /* __SDCA_CLASS_H__ */
|
||||
@@ -219,12 +219,14 @@ static inline int simple_util_parse_aux_devs(struct simple_util_priv *priv, char
|
||||
int simple_util_init_jack(struct snd_soc_card *card,
|
||||
struct simple_util_jack *sjack,
|
||||
int is_hp, char *prefix, char *pin);
|
||||
void simple_util_remove_jack(struct simple_util_jack *sjack);
|
||||
int simple_util_init_aux_jacks(struct snd_soc_card *card, char *prefix);
|
||||
int simple_util_init_priv(struct simple_util_priv *priv,
|
||||
struct link_info *li);
|
||||
void simple_util_remove(struct platform_device *pdev);
|
||||
|
||||
int graph_util_card_probe(struct snd_soc_card *card);
|
||||
int graph_util_card_remove(struct snd_soc_card *card);
|
||||
int graph_util_is_ports0(struct device_node *port);
|
||||
int graph_util_parse_dai(struct simple_util_priv *priv, struct device_node *ep,
|
||||
struct snd_soc_dai_link_component *dlc, int *is_single_link);
|
||||
|
||||
@@ -154,6 +154,8 @@ struct snd_soc_component_driver {
|
||||
struct snd_pcm_substream *substream);
|
||||
snd_pcm_sframes_t (*delay)(struct snd_soc_component *component,
|
||||
struct snd_pcm_substream *substream);
|
||||
int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_pcm_hw_params *params);
|
||||
|
||||
const struct snd_compress_ops *compress_ops;
|
||||
|
||||
@@ -194,12 +196,13 @@ struct snd_soc_component_driver {
|
||||
unsigned int endianness:1;
|
||||
unsigned int legacy_dai_naming:1;
|
||||
|
||||
/* use DAI link PCM ID as PCM device number */
|
||||
unsigned int use_dai_pcm_id:1;
|
||||
|
||||
/* this component uses topology and ignore machine driver FEs */
|
||||
const char *ignore_machine;
|
||||
const char *topology_name_prefix;
|
||||
int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_pcm_hw_params *params);
|
||||
bool use_dai_pcm_id; /* use DAI link PCM ID as PCM device number */
|
||||
|
||||
int be_pcm_base; /* base device ID for all BE PCMs */
|
||||
|
||||
const char *debugfs_prefix;
|
||||
@@ -258,37 +261,24 @@ struct snd_soc_component {
|
||||
void *priv;
|
||||
};
|
||||
|
||||
#define for_each_component_dais(component, dai)\
|
||||
list_for_each_entry(dai, &(component)->dai_list, list)
|
||||
#define for_each_component_dais_safe(component, dai, _dai)\
|
||||
list_for_each_entry_safe(dai, _dai, &(component)->dai_list, list)
|
||||
#define for_each_component_dais(component, dai) \
|
||||
for (dai = snd_soc_dai_from_list((component)->dai_list.next); \
|
||||
snd_soc_dai_to_list(dai) != &(component)->dai_list; \
|
||||
dai = snd_soc_dai_from_list(snd_soc_dai_to_list(dai)->next))
|
||||
|
||||
/**
|
||||
* snd_soc_component_to_dapm() - Returns the DAPM context associated with a
|
||||
* component
|
||||
* @component: The component for which to get the DAPM context
|
||||
*/
|
||||
static inline struct snd_soc_dapm_context *snd_soc_component_to_dapm(
|
||||
struct snd_soc_component *component)
|
||||
{
|
||||
return component->dapm;
|
||||
}
|
||||
#define for_each_component_dais_safe(component, dai, _dai) \
|
||||
for (dai = snd_soc_dai_from_list((component)->dai_list.next), \
|
||||
_dai = snd_soc_dai_from_list(snd_soc_dai_to_list(dai)->next); \
|
||||
snd_soc_dai_to_list(dai) != &(component)->dai_list; \
|
||||
dai = _dai, _dai = snd_soc_dai_from_list(snd_soc_dai_to_list(_dai)->next))
|
||||
|
||||
/**
|
||||
* snd_soc_component_cache_sync() - Sync the register cache with the hardware
|
||||
* @component: COMPONENT to sync
|
||||
*
|
||||
* Note: This function will call regcache_sync()
|
||||
*/
|
||||
static inline int snd_soc_component_cache_sync(
|
||||
struct snd_soc_component *component)
|
||||
{
|
||||
return regcache_sync(component->regmap);
|
||||
}
|
||||
struct snd_soc_dapm_context *snd_soc_component_to_dapm(struct snd_soc_component *component);
|
||||
struct snd_soc_component *snd_soc_component_new(struct device *dev, const char *name,
|
||||
const struct snd_soc_component_driver *driver);
|
||||
int snd_soc_component_register(struct snd_soc_component *component,
|
||||
struct snd_soc_dai_driver *dai_drv,
|
||||
int num_dai);
|
||||
|
||||
struct snd_soc_component *snd_soc_component_alloc(struct device *dev);
|
||||
|
||||
void snd_soc_component_set_name(struct snd_soc_component *component, const char *name);
|
||||
const char *snd_soc_component_name(struct snd_soc_component *component);
|
||||
|
||||
void snd_soc_component_set_priv(struct snd_soc_component *component, void *priv);
|
||||
@@ -299,6 +289,11 @@ void snd_soc_component_set_aux(struct snd_soc_component *component,
|
||||
int snd_soc_component_init(struct snd_soc_component *component);
|
||||
int snd_soc_component_is_dummy(struct snd_soc_component *component);
|
||||
|
||||
struct snd_soc_component *snd_soc_component_lookup_nolock(struct device *dev,
|
||||
const char *driver_name);
|
||||
struct snd_soc_component *snd_soc_component_lookup(struct device *dev, const char *driver_name);
|
||||
struct snd_soc_component *snd_soc_component_lookup_by_name(const char *component_name);
|
||||
|
||||
/* component IO */
|
||||
unsigned int snd_soc_component_read(struct snd_soc_component *component,
|
||||
unsigned int reg);
|
||||
@@ -310,7 +305,6 @@ int snd_soc_component_update_bits(struct snd_soc_component *component,
|
||||
int snd_soc_component_update_bits_async(struct snd_soc_component *component,
|
||||
unsigned int reg, unsigned int mask,
|
||||
unsigned int val);
|
||||
void snd_soc_component_async_complete(struct snd_soc_component *component);
|
||||
int snd_soc_component_test_bits(struct snd_soc_component *component,
|
||||
unsigned int reg, unsigned int mask,
|
||||
unsigned int value);
|
||||
@@ -340,12 +334,18 @@ int snd_soc_component_set_bias_level(struct snd_soc_component *component,
|
||||
enum snd_soc_bias_level level);
|
||||
|
||||
int snd_soc_component_regmap_val_bytes(struct snd_soc_component *component);
|
||||
int snd_soc_component_regmap_cache_sync(struct snd_soc_component *component);
|
||||
void snd_soc_component_regmap_async_complete(struct snd_soc_component *component);
|
||||
#ifdef CONFIG_REGMAP
|
||||
void snd_soc_component_init_regmap(struct snd_soc_component *component,
|
||||
struct regmap *regmap);
|
||||
void snd_soc_component_exit_regmap(struct snd_soc_component *component);
|
||||
#endif
|
||||
|
||||
int snd_soc_component_fixup_controls(struct snd_soc_component *component);
|
||||
int snd_soc_component_add_controls(struct snd_soc_component *component,
|
||||
const struct snd_kcontrol_new *controls, unsigned int num_controls);
|
||||
|
||||
#define snd_soc_component_module_get_when_probe(component)\
|
||||
snd_soc_component_module_get(component, NULL, 0)
|
||||
#define snd_soc_component_module_get_when_open(component, substream) \
|
||||
@@ -370,11 +370,7 @@ static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
|
||||
return dev_get_drvdata(c->dev);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
snd_soc_component_active(struct snd_soc_component *component)
|
||||
{
|
||||
return component->active;
|
||||
}
|
||||
unsigned int snd_soc_component_active(struct snd_soc_component *component);
|
||||
|
||||
/* component controls */
|
||||
struct snd_kcontrol *snd_soc_component_get_kcontrol(struct snd_soc_component *component,
|
||||
@@ -391,9 +387,6 @@ int snd_soc_component_close(struct snd_soc_component *component,
|
||||
void snd_soc_component_suspend(struct snd_soc_component *component);
|
||||
void snd_soc_component_resume(struct snd_soc_component *component);
|
||||
int snd_soc_component_is_suspended(struct snd_soc_component *component);
|
||||
int snd_soc_component_probe(struct snd_soc_component *component);
|
||||
int snd_soc_component_fixup_controls(struct snd_soc_component *component);
|
||||
void snd_soc_component_remove(struct snd_soc_component *component);
|
||||
int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
|
||||
struct device_node *ep);
|
||||
int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
|
||||
@@ -423,7 +416,7 @@ int snd_soc_component_compr_set_metadata(struct snd_compr_stream *cstream,
|
||||
int snd_soc_component_compr_get_metadata(struct snd_compr_stream *cstream,
|
||||
struct snd_compr_metadata *metadata);
|
||||
|
||||
int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream);
|
||||
snd_pcm_uframes_t snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream);
|
||||
int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
|
||||
unsigned int cmd, void *arg);
|
||||
int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream);
|
||||
@@ -451,4 +444,11 @@ int snd_soc_pcm_component_ack(struct snd_pcm_substream *substream);
|
||||
void snd_soc_pcm_component_delay(struct snd_pcm_substream *substream,
|
||||
snd_pcm_sframes_t *cpu_delay, snd_pcm_sframes_t *codec_delay);
|
||||
|
||||
/* REMOVE ME */
|
||||
#define snd_soc_component_cache_sync snd_soc_component_regmap_cache_sync
|
||||
#define snd_soc_component_async_complete snd_soc_component_regmap_async_complete
|
||||
#define snd_soc_lookup_component_nolocked snd_soc_component_lookup_nolock
|
||||
#define snd_soc_lookup_component snd_soc_component_lookup
|
||||
#define snd_soc_lookup_component_by_name snd_soc_component_lookup_by_name
|
||||
|
||||
#endif /* __SOC_COMPONENT_H */
|
||||
+78
-101
@@ -212,8 +212,11 @@ int snd_soc_dai_get_channel_map(const struct snd_soc_dai *dai,
|
||||
unsigned int *tx_num, unsigned int *tx_slot,
|
||||
unsigned int *rx_num, unsigned int *rx_slot);
|
||||
|
||||
struct snd_soc_component *snd_soc_dai_to_component(const struct snd_soc_dai *dai);
|
||||
struct snd_soc_dai_driver *snd_soc_dai_to_driver(const struct snd_soc_dai *dai);
|
||||
int snd_soc_dai_is_dummy(const struct snd_soc_dai *dai);
|
||||
|
||||
int snd_soc_dai_add_controls(struct snd_soc_dai *dai,
|
||||
const struct snd_kcontrol_new *controls, int num_controls);
|
||||
int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params);
|
||||
@@ -228,18 +231,7 @@ void snd_soc_dai_suspend(struct snd_soc_dai *dai);
|
||||
void snd_soc_dai_resume(struct snd_soc_dai *dai);
|
||||
int snd_soc_dai_compress_new(struct snd_soc_dai *dai, struct snd_soc_pcm_runtime *rtd);
|
||||
bool snd_soc_dai_stream_valid(const struct snd_soc_dai *dai, int stream);
|
||||
void snd_soc_dai_action(struct snd_soc_dai *dai,
|
||||
int stream, int action);
|
||||
static inline void snd_soc_dai_activate(struct snd_soc_dai *dai,
|
||||
int stream)
|
||||
{
|
||||
snd_soc_dai_action(dai, stream, 1);
|
||||
}
|
||||
static inline void snd_soc_dai_deactivate(struct snd_soc_dai *dai,
|
||||
int stream)
|
||||
{
|
||||
snd_soc_dai_action(dai, stream, -1);
|
||||
}
|
||||
|
||||
int snd_soc_dai_active(const struct snd_soc_dai *dai);
|
||||
|
||||
int snd_soc_pcm_dai_probe(struct snd_soc_pcm_runtime *rtd, int order);
|
||||
@@ -277,7 +269,12 @@ int snd_soc_dai_compr_get_metadata(struct snd_soc_dai *dai,
|
||||
struct snd_compr_stream *cstream,
|
||||
struct snd_compr_metadata *metadata);
|
||||
|
||||
const char *snd_soc_dai_name_get(const struct snd_soc_dai *dai);
|
||||
int snd_soc_dai_matches_args(const struct snd_soc_dai *dai,
|
||||
const struct of_phandle_args *args2);
|
||||
int snd_soc_dai_matches_dlc(struct snd_soc_dai *dai,
|
||||
const struct snd_soc_dai_link_component *dlc);
|
||||
const char *snd_soc_dai_name(const struct snd_soc_dai *dai);
|
||||
int snd_soc_dai_id(const struct snd_soc_dai *dai);
|
||||
|
||||
struct snd_soc_dai_ops {
|
||||
/* DAI driver callbacks */
|
||||
@@ -489,69 +486,51 @@ struct snd_soc_dai {
|
||||
void *priv;
|
||||
};
|
||||
|
||||
const struct snd_soc_pcm_stream *
|
||||
snd_soc_dai_pcm_stream_get_i(const struct snd_soc_dai *dai, int stream);
|
||||
static inline const struct snd_soc_pcm_stream *
|
||||
snd_soc_dai_get_pcm_stream(const struct snd_soc_dai *dai, int stream)
|
||||
snd_soc_dai_pcm_stream_get_s(const struct snd_soc_dai *dai, struct snd_pcm_substream *substream)
|
||||
{
|
||||
return (stream == SNDRV_PCM_STREAM_PLAYBACK) ?
|
||||
&dai->driver->playback : &dai->driver->capture;
|
||||
return snd_soc_dai_pcm_stream_get_i(dai, substream->stream);
|
||||
}
|
||||
#define snd_soc_dai_pcm_stream_get(dai, x) _Generic((x), \
|
||||
int : snd_soc_dai_pcm_stream_get_i, \
|
||||
struct snd_pcm_substream * : snd_soc_dai_pcm_stream_get_s)(dai, x)
|
||||
|
||||
#define snd_soc_dai_get_widget_playback(dai) snd_soc_dai_get_widget(dai, SNDRV_PCM_STREAM_PLAYBACK)
|
||||
#define snd_soc_dai_get_widget_capture(dai) snd_soc_dai_get_widget(dai, SNDRV_PCM_STREAM_CAPTURE)
|
||||
static inline
|
||||
struct snd_soc_dapm_widget *snd_soc_dai_get_widget(struct snd_soc_dai *dai, int stream)
|
||||
{
|
||||
return dai->stream[stream].widget;
|
||||
}
|
||||
#define snd_soc_dai_stream_widget_get_playback(dai) snd_soc_dai_stream_widget_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
|
||||
#define snd_soc_dai_stream_widget_get_capture(dai) snd_soc_dai_stream_widget_get(dai, SNDRV_PCM_STREAM_CAPTURE)
|
||||
struct snd_soc_dapm_widget *snd_soc_dai_stream_widget_get(struct snd_soc_dai *dai, int stream);
|
||||
|
||||
#define snd_soc_dai_set_widget_playback(dai, widget) snd_soc_dai_set_widget(dai, SNDRV_PCM_STREAM_PLAYBACK, widget)
|
||||
#define snd_soc_dai_set_widget_capture(dai, widget) snd_soc_dai_set_widget(dai, SNDRV_PCM_STREAM_CAPTURE, widget)
|
||||
static inline
|
||||
void snd_soc_dai_set_widget(struct snd_soc_dai *dai, int stream, struct snd_soc_dapm_widget *widget)
|
||||
{
|
||||
dai->stream[stream].widget = widget;
|
||||
}
|
||||
#define snd_soc_dai_stream_widget_set_playback(dai, widget) snd_soc_dai_stream_widget_set(dai, SNDRV_PCM_STREAM_PLAYBACK, widget)
|
||||
#define snd_soc_dai_stream_widget_set_capture(dai, widget) snd_soc_dai_stream_widget_set(dai, SNDRV_PCM_STREAM_CAPTURE, widget)
|
||||
void snd_soc_dai_stream_widget_set(struct snd_soc_dai *dai, int stream, struct snd_soc_dapm_widget *widget);
|
||||
|
||||
#define snd_soc_dai_dma_data_get_playback(dai) snd_soc_dai_dma_data_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
|
||||
#define snd_soc_dai_dma_data_get_capture(dai) snd_soc_dai_dma_data_get(dai, SNDRV_PCM_STREAM_CAPTURE)
|
||||
#define snd_soc_dai_get_dma_data(dai, ss) snd_soc_dai_dma_data_get(dai, ss->stream)
|
||||
static inline void *snd_soc_dai_dma_data_get(const struct snd_soc_dai *dai, int stream)
|
||||
#define snd_soc_dai_stream_dma_data_get_playback(dai) snd_soc_dai_stream_dma_data_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
|
||||
#define snd_soc_dai_stream_dma_data_get_capture(dai) snd_soc_dai_stream_dma_data_get(dai, SNDRV_PCM_STREAM_CAPTURE)
|
||||
void *snd_soc_dai_stream_dma_data_get_i(const struct snd_soc_dai *dai, int stream);
|
||||
static inline void *snd_soc_dai_stream_dma_data_get_s(const struct snd_soc_dai *dai, struct snd_pcm_substream *substream)
|
||||
{
|
||||
return dai->stream[stream].dma_data;
|
||||
return snd_soc_dai_stream_dma_data_get_i(dai, substream->stream);
|
||||
}
|
||||
#define snd_soc_dai_stream_dma_data_get(dai, x) _Generic((x), \
|
||||
int : snd_soc_dai_stream_dma_data_get_i, \
|
||||
struct snd_pcm_substream * : snd_soc_dai_stream_dma_data_get_s)(dai, x)
|
||||
|
||||
#define snd_soc_dai_dma_data_set_playback(dai, data) snd_soc_dai_dma_data_set(dai, SNDRV_PCM_STREAM_PLAYBACK, data)
|
||||
#define snd_soc_dai_dma_data_set_capture(dai, data) snd_soc_dai_dma_data_set(dai, SNDRV_PCM_STREAM_CAPTURE, data)
|
||||
#define snd_soc_dai_set_dma_data(dai, ss, data) snd_soc_dai_dma_data_set(dai, ss->stream, data)
|
||||
static inline void snd_soc_dai_dma_data_set(struct snd_soc_dai *dai, int stream, void *data)
|
||||
#define snd_soc_dai_stream_dma_data_set_playback(dai, data) snd_soc_dai_stream_dma_data_set(dai, SNDRV_PCM_STREAM_PLAYBACK, data)
|
||||
#define snd_soc_dai_stream_dma_data_set_capture(dai, data) snd_soc_dai_stream_dma_data_set(dai, SNDRV_PCM_STREAM_CAPTURE, data)
|
||||
void snd_soc_dai_stream_dma_data_set_i(struct snd_soc_dai *dai, int stream, void *data);
|
||||
static inline void snd_soc_dai_stream_dma_data_set_s(struct snd_soc_dai *dai, struct snd_pcm_substream *substream, void *data)
|
||||
{
|
||||
dai->stream[stream].dma_data = data;
|
||||
snd_soc_dai_stream_dma_data_set_i(dai, substream->stream, data);
|
||||
}
|
||||
#define snd_soc_dai_stream_dma_data_set(dai, x, data) _Generic((x), \
|
||||
int : snd_soc_dai_stream_dma_data_set_i, \
|
||||
struct snd_pcm_substream * : snd_soc_dai_stream_dma_data_set_s)(dai, x, data)
|
||||
|
||||
static inline void snd_soc_dai_init_dma_data(struct snd_soc_dai *dai, void *playback, void *capture)
|
||||
{
|
||||
snd_soc_dai_dma_data_set_playback(dai, playback);
|
||||
snd_soc_dai_dma_data_set_capture(dai, capture);
|
||||
}
|
||||
unsigned int snd_soc_dai_stream_tdm_mask_get(const struct snd_soc_dai *dai, int stream);
|
||||
void snd_soc_dai_stream_tdm_mask_set(struct snd_soc_dai *dai, int stream, unsigned int tdm_mask);
|
||||
|
||||
static inline unsigned int snd_soc_dai_tdm_mask_get(const struct snd_soc_dai *dai,
|
||||
int stream)
|
||||
{
|
||||
return dai->stream[stream].tdm_mask;
|
||||
}
|
||||
|
||||
static inline void snd_soc_dai_tdm_mask_set(struct snd_soc_dai *dai, int stream,
|
||||
unsigned int tdm_mask)
|
||||
{
|
||||
dai->stream[stream].tdm_mask = tdm_mask;
|
||||
}
|
||||
|
||||
static inline unsigned int snd_soc_dai_stream_active(const struct snd_soc_dai *dai,
|
||||
int stream)
|
||||
{
|
||||
/* see snd_soc_dai_action() for setup */
|
||||
return dai->stream[stream].active;
|
||||
}
|
||||
unsigned int snd_soc_dai_stream_active(const struct snd_soc_dai *dai, int stream);
|
||||
|
||||
static inline void snd_soc_dai_set_drvdata(struct snd_soc_dai *dai,
|
||||
void *data)
|
||||
@@ -564,45 +543,43 @@ static inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai)
|
||||
return dev_get_drvdata(dai->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_soc_dai_set_stream() - Configures a DAI for stream operation
|
||||
* @dai: DAI
|
||||
* @stream: STREAM (opaque structure depending on DAI type)
|
||||
* @direction: Stream direction(Playback/Capture)
|
||||
* Some subsystems, such as SoundWire, don't have a notion of direction and we reuse
|
||||
* the ASoC stream direction to configure sink/source ports.
|
||||
* Playback maps to source ports and Capture for sink ports.
|
||||
*
|
||||
* This should be invoked with NULL to clear the stream set previously.
|
||||
* Returns 0 on success, a negative error code otherwise.
|
||||
*/
|
||||
static inline int snd_soc_dai_set_stream(struct snd_soc_dai *dai,
|
||||
void *stream, int direction)
|
||||
{
|
||||
if (dai->driver->ops->set_stream)
|
||||
return dai->driver->ops->set_stream(dai, stream, direction);
|
||||
else
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
int snd_soc_dai_set_stream(struct snd_soc_dai *dai, void *stream, int direction);
|
||||
void *snd_soc_dai_get_stream(struct snd_soc_dai *dai, int direction);
|
||||
|
||||
/**
|
||||
* snd_soc_dai_get_stream() - Retrieves stream from DAI
|
||||
* @dai: DAI
|
||||
* @direction: Stream direction(Playback/Capture)
|
||||
*
|
||||
* This routine only retrieves that was previously configured
|
||||
* with snd_soc_dai_get_stream()
|
||||
*
|
||||
* Returns pointer to stream or an ERR_PTR value, e.g.
|
||||
* ERR_PTR(-ENOTSUPP) if callback is not supported;
|
||||
*/
|
||||
static inline void *snd_soc_dai_get_stream(struct snd_soc_dai *dai,
|
||||
int direction)
|
||||
struct snd_soc_dai *snd_soc_dai_register(struct snd_soc_component *component,
|
||||
struct snd_soc_dai_driver *dai_drv,
|
||||
bool legacy_dai_naming);
|
||||
void snd_soc_dai_unregister(struct snd_soc_dai *dai);
|
||||
struct snd_soc_dai *snd_soc_dai_from_list(struct list_head *list);
|
||||
struct list_head *snd_soc_dai_to_list(struct snd_soc_dai *dai);
|
||||
unsigned int snd_soc_dai_get_symmetric_rate(struct snd_soc_dai *dai);
|
||||
unsigned int snd_soc_dai_get_symmetric_channels(struct snd_soc_dai *dai);
|
||||
unsigned int snd_soc_dai_get_symmetric_sample_bits(struct snd_soc_dai *dai);
|
||||
void snd_soc_dai_set_priv(struct snd_soc_dai *dai, void *priv);
|
||||
void *snd_soc_dai_to_priv(struct snd_soc_dai *dai);
|
||||
|
||||
/* REMOVE ME */
|
||||
#define snd_soc_dai_get_pcm_stream snd_soc_dai_pcm_stream_get
|
||||
#define snd_soc_dai_get_widget_playback(dai) snd_soc_dai_stream_widget_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
|
||||
#define snd_soc_dai_get_widget_capture(dai) snd_soc_dai_stream_widget_get(dai, SNDRV_PCM_STREAM_CAPTURE)
|
||||
#define snd_soc_dai_get_widget snd_soc_dai_stream_widget_get
|
||||
#define snd_soc_dai_set_widget_playback(dai, widget) snd_soc_dai_stream_widget_set(dai, SNDRV_PCM_STREAM_PLAYBACK, widget)
|
||||
#define snd_soc_dai_set_widget_capture(dai, widget) snd_soc_dai_stream_widget_set(dai, SNDRV_PCM_STREAM_CAPTURE, widget)
|
||||
#define snd_soc_dai_set_widget snd_soc_dai_stream_widget_set
|
||||
#define snd_soc_dai_dma_data_get_playback(dai) snd_soc_dai_stream_dma_data_get(dai, SNDRV_PCM_STREAM_PLAYBACK)
|
||||
#define snd_soc_dai_dma_data_get_capture(dai) snd_soc_dai_stream_dma_data_get(dai, SNDRV_PCM_STREAM_CAPTURE)
|
||||
#define snd_soc_dai_get_dma_data snd_soc_dai_stream_dma_data_get
|
||||
#define snd_soc_dai_dma_data_get snd_soc_dai_stream_dma_data_get
|
||||
#define snd_soc_dai_dma_data_set_playback(dai, data) snd_soc_dai_stream_dma_data_set(dai, SNDRV_PCM_STREAM_PLAYBACK, data)
|
||||
#define snd_soc_dai_dma_data_set_capture(dai, data) snd_soc_dai_stream_dma_data_set(dai, SNDRV_PCM_STREAM_CAPTURE, data)
|
||||
#define snd_soc_dai_set_dma_data snd_soc_dai_stream_dma_data_set
|
||||
#define snd_soc_dai_dma_data_set snd_soc_dai_stream_dma_data_set
|
||||
#define snd_soc_dai_tdm_mask_get snd_soc_dai_stream_tdm_mask_get
|
||||
#define snd_soc_dai_tdm_mask_set snd_soc_dai_stream_tdm_mask_set
|
||||
static inline void snd_soc_dai_init_dma_data(struct snd_soc_dai *dai, void *playback, void *capture)
|
||||
{
|
||||
if (dai->driver->ops->get_stream)
|
||||
return dai->driver->ops->get_stream(dai, direction);
|
||||
else
|
||||
return ERR_PTR(-ENOTSUPP);
|
||||
snd_soc_dai_stream_dma_data_set_playback(dai, playback);
|
||||
snd_soc_dai_stream_dma_data_set_capture(dai, capture);
|
||||
}
|
||||
|
||||
#endif
|
||||
+12
-23
@@ -447,15 +447,9 @@ static inline int snd_soc_resume(struct device *dev)
|
||||
}
|
||||
#endif
|
||||
int snd_soc_poweroff(struct device *dev);
|
||||
int snd_soc_register_component_c(struct snd_soc_component *component,
|
||||
const struct snd_soc_component_driver *component_driver,
|
||||
struct snd_soc_dai_driver *dai_drv, int num_dai);
|
||||
int snd_soc_register_component_d(struct device *dev,
|
||||
int snd_soc_register_component(struct device *dev,
|
||||
const struct snd_soc_component_driver *component_driver,
|
||||
struct snd_soc_dai_driver *dai_drv, int num_dai);
|
||||
#define snd_soc_register_component(x, ...) _Generic((x), \
|
||||
struct device * : snd_soc_register_component_d, \
|
||||
struct snd_soc_component * : snd_soc_register_component_c)(x, __VA_ARGS__)
|
||||
|
||||
int devm_snd_soc_register_component(struct device *dev,
|
||||
const struct snd_soc_component_driver *component_driver,
|
||||
@@ -463,11 +457,6 @@ int devm_snd_soc_register_component(struct device *dev,
|
||||
#define snd_soc_unregister_component(dev) snd_soc_unregister_component_by_driver(dev, NULL)
|
||||
void snd_soc_unregister_component_by_driver(struct device *dev,
|
||||
const struct snd_soc_component_driver *component_driver);
|
||||
struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev,
|
||||
const char *driver_name);
|
||||
struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
|
||||
const char *driver_name);
|
||||
struct snd_soc_component *snd_soc_lookup_component_by_name(const char *component_name);
|
||||
|
||||
int soc_new_pcm(struct snd_soc_pcm_runtime *rtd);
|
||||
#ifdef CONFIG_SND_SOC_COMPRESS
|
||||
@@ -551,12 +540,8 @@ static inline int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
|
||||
struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
|
||||
void *data, const char *long_name,
|
||||
const char *prefix);
|
||||
int snd_soc_add_component_controls(struct snd_soc_component *component,
|
||||
const struct snd_kcontrol_new *controls, unsigned int num_controls);
|
||||
int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
|
||||
const struct snd_kcontrol_new *controls, int num_controls);
|
||||
int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
|
||||
const struct snd_kcontrol_new *controls, int num_controls);
|
||||
int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
|
||||
@@ -1331,6 +1316,9 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np,
|
||||
unsigned int *rx_mask,
|
||||
unsigned int *slots,
|
||||
unsigned int *slot_width);
|
||||
int snd_soc_of_xlate_dai_name(struct snd_soc_component *component,
|
||||
const struct of_phandle_args *args,
|
||||
const char **dai_name);
|
||||
void snd_soc_of_parse_node_prefix(struct device_node *np,
|
||||
struct snd_soc_codec_conf *codec_conf,
|
||||
struct device_node *of_node,
|
||||
@@ -1389,19 +1377,12 @@ void snd_soc_dlc_use_cpu_as_platform(struct snd_soc_dai_link_component *platform
|
||||
struct of_phandle_args *snd_soc_copy_dai_args(struct device *dev,
|
||||
const struct of_phandle_args *args);
|
||||
struct snd_soc_dai *snd_soc_get_dai_via_args(const struct of_phandle_args *dai_args);
|
||||
struct snd_soc_dai *snd_soc_register_dai(struct snd_soc_component *component,
|
||||
struct snd_soc_dai_driver *dai_drv,
|
||||
bool legacy_dai_naming);
|
||||
void snd_soc_unregister_dai(struct snd_soc_dai *dai);
|
||||
|
||||
struct snd_soc_dai *snd_soc_find_dai(
|
||||
const struct snd_soc_dai_link_component *dlc);
|
||||
struct snd_soc_dai *snd_soc_find_dai_with_mutex(
|
||||
const struct snd_soc_dai_link_component *dlc);
|
||||
|
||||
void soc_pcm_set_dai_params(struct snd_soc_dai *dai,
|
||||
struct snd_pcm_hw_params *params);
|
||||
|
||||
#include <sound/soc-dai.h>
|
||||
|
||||
static inline
|
||||
@@ -1551,4 +1532,12 @@ static inline void _snd_soc_dpcm_mutex_assert_held_r(struct snd_soc_pcm_runtime
|
||||
#include <sound/soc-card.h>
|
||||
#include <sound/soc-jack.h>
|
||||
|
||||
/*
|
||||
* REMOVE ME
|
||||
*/
|
||||
#define snd_soc_add_dai_controls snd_soc_dai_add_controls
|
||||
#define snd_soc_register_dai snd_soc_dai_register
|
||||
#define snd_soc_unregister_dai snd_soc_dai_unregister
|
||||
#define snd_soc_add_component_controls snd_soc_component_add_controls
|
||||
|
||||
#endif
|
||||
@@ -292,4 +292,24 @@ int asoc_sdw_es9356_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai
|
||||
int asoc_sdw_es9356_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
|
||||
int asoc_sdw_es9356_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
|
||||
|
||||
/* Senary SN624x SDCA */
|
||||
int asoc_sdw_senary_sdca_jack_init(struct snd_soc_card *card,
|
||||
struct snd_soc_dai_link *dai_links,
|
||||
struct asoc_sdw_codec_info *info,
|
||||
bool playback);
|
||||
int asoc_sdw_senary_sdca_jack_exit(struct snd_soc_card *card,
|
||||
struct snd_soc_dai_link *dai_link);
|
||||
int asoc_sdw_senary_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_soc_dai *dai);
|
||||
int asoc_sdw_senary_amp_init(struct snd_soc_card *card,
|
||||
struct snd_soc_dai_link *dai_links,
|
||||
struct asoc_sdw_codec_info *info,
|
||||
bool playback);
|
||||
int asoc_sdw_senary_amp_exit(struct snd_soc_card *card,
|
||||
struct snd_soc_dai_link *dai_link);
|
||||
int asoc_sdw_senary_sdca_spk_rtd_init(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_soc_dai *dai);
|
||||
int asoc_sdw_senary_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_soc_dai *dai);
|
||||
|
||||
#endif
|
||||
@@ -436,12 +436,10 @@ enum sof_ipc4_fw_config_params {
|
||||
SOF_IPC4_FW_CFG_RESERVED,
|
||||
SOF_IPC4_FW_CFG_POWER_GATING_POLICY,
|
||||
SOF_IPC4_FW_CFG_ASSERT_MODE,
|
||||
SOF_IPC4_FW_RESERVED1,
|
||||
SOF_IPC4_FW_RESERVED2,
|
||||
SOF_IPC4_FW_RESERVED3,
|
||||
SOF_IPC4_FW_RESERVED4,
|
||||
SOF_IPC4_FW_RESERVED5,
|
||||
SOF_IPC4_FW_CONTEXT_SAVE
|
||||
/* Reserved: 24 - 28 */
|
||||
SOF_IPC4_FW_CONTEXT_SAVE = 29,
|
||||
/* Reserved: 30 - 34 */
|
||||
SOF_IPC4_FW_CFG_SOF_INFO = 35,
|
||||
};
|
||||
|
||||
struct sof_ipc4_fw_version {
|
||||
@@ -451,6 +449,14 @@ struct sof_ipc4_fw_version {
|
||||
uint16_t build;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* tuple based array for SOF specific information under SOF_IPC4_FW_CFG_SOF_INFO
|
||||
* tuple of fw_config
|
||||
*/
|
||||
enum ipc4_fw_sof_info_params {
|
||||
SOF_IPC4_SOF_CODEC_INFO,
|
||||
};
|
||||
|
||||
/* Payload data for SOF_IPC4_MOD_SET_DX */
|
||||
struct sof_ipc4_dx_state_info {
|
||||
/* core(s) to apply the change */
|
||||
@@ -641,9 +647,10 @@ struct sof_ipc4_notify_module_data {
|
||||
* The event_data contains the struct sof_ipc4_control_msg_payload of the control
|
||||
* which sent the notification.
|
||||
*/
|
||||
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_MASK GENMASK(31, 16)
|
||||
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_SOF_MAGIC_MASK GENMASK(31, 16)
|
||||
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_MAGIC_VAL 0xA15A0000
|
||||
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_PARAMID_MASK GENMASK(15, 0)
|
||||
#define SOF_IPC4_NOTIFY_MODULE_EVENTID_COMPR_MAGIC_VAL 0xC0C00000
|
||||
|
||||
/*
|
||||
* Macros for creating struct sof_ipc4_module_init_ext_init payload
|
||||
@@ -706,7 +713,8 @@ struct sof_ipc4_module_init_ext_object {
|
||||
enum sof_ipc4_mod_init_ext_obj_id {
|
||||
SOF_IPC4_MOD_INIT_DATA_ID_INVALID = 0,
|
||||
SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA,
|
||||
SOF_IPC4_MOD_INIT_DATA_ID_MAX = SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA,
|
||||
SOF_IPC4_MOD_INIT_DATA_ID_MODULE_DATA,
|
||||
SOF_IPC4_MOD_INIT_DATA_ID_MAX = SOF_IPC4_MOD_INIT_DATA_ID_MODULE_DATA,
|
||||
};
|
||||
|
||||
/* DP module memory configuration data object for object array */
|
||||
|
||||
@@ -56,6 +56,10 @@ enum tasdevice_dsp_dev_idx {
|
||||
TASDEVICE_DSP_TAS_2781_QUAD,
|
||||
TASDEVICE_DSP_TAS_5825_MONO,
|
||||
TASDEVICE_DSP_TAS_5825_DUAL,
|
||||
TASDEVICE_DSP_TAS_2573_MONO,
|
||||
TASDEVICE_DSP_TAS_2573_DUAL,
|
||||
TASDEVICE_DSP_TAS_2573_21,
|
||||
TASDEVICE_DSP_TAS_2573_QUAD,
|
||||
TASDEVICE_DSP_TAS_MAX_DEVICE
|
||||
};
|
||||
|
||||
@@ -142,6 +146,7 @@ struct tasdevice_fw {
|
||||
struct tasdevice_calibration *calibrations;
|
||||
struct fct_param_address fct_par_addr;
|
||||
struct device *dev;
|
||||
int calibration_config_id;
|
||||
};
|
||||
|
||||
enum tasdevice_fw_state {
|
||||
@@ -206,6 +211,14 @@ struct tasdevice_rca {
|
||||
* capture.
|
||||
*/
|
||||
int capture_profile_id;
|
||||
/*
|
||||
* Primarily designed for speaker calibration scenarios with special
|
||||
* requirements. For regular use cases, when the default value -1 is
|
||||
* set, calibration will directly reuse the current playback
|
||||
* configuration; non-negative values can be customized for special
|
||||
* calibration demands.
|
||||
*/
|
||||
int calibration_profile_id;
|
||||
/*
|
||||
* Since version 0x105, the keyword 'init' was introduced into the
|
||||
* profile, which is used for chip initialization, particularly to
|
||||
|
||||
@@ -49,6 +49,13 @@
|
||||
#define TASDEVICE_REG(book, page, reg) (((book * 256 * 128) + \
|
||||
(page * 128)) + reg)
|
||||
|
||||
#define TAS_REG_ERR_LOG(dev, chn, reg, ret) \
|
||||
dev_err((dev), "%s, C%uBx%02xPx%02xRx%02x E=%d\n", \
|
||||
__func__, chn, TASDEVICE_BOOK_ID(reg), \
|
||||
TASDEVICE_PAGE_ID(reg), \
|
||||
TASDEVICE_PAGE_REG(reg), \
|
||||
(ret))
|
||||
|
||||
/* Software Reset, compatble with new device (TAS5825). */
|
||||
#define TASDEVICE_REG_SWRESET TASDEVICE_REG(0x0, 0x0, 0x01)
|
||||
#define TASDEVICE_REG_SWRESET_RESET BIT(0)
|
||||
@@ -91,6 +98,30 @@
|
||||
/* prm_TE_1_Beta1 */
|
||||
#define TAS2563_TE_DT_REG TASDEVICE_REG(0x00, 0x0f, 0x70)
|
||||
|
||||
#define TAS2573_FCT_INT_LATCH TASDEVICE_REG(0x00, 0x00, 0x67)
|
||||
/* YM57 */
|
||||
#define TAS2573_FCT_OUTPUT_R0 TASDEVICE_REG(0x00, 0x65, 0x74)
|
||||
/* YM58 */
|
||||
#define TAS2573_FCT_OUTPUT_R0_LOW TASDEVICE_REG(0x00, 0x65, 0x78)
|
||||
/* YM59 */
|
||||
#define TAS2573_FCT_OUTPUT_INV_R0 TASDEVICE_REG(0x00, 0x65, 0x7C)
|
||||
/* YM61 */
|
||||
#define TAS2573_FCT_OUTPUT_POWERTOT TASDEVICE_REG(0x00, 0x66, 0x0C)
|
||||
/* YM64 */
|
||||
#define TAS2573_FCT_OUTPUT_F0 TASDEVICE_REG(0x00, 0x65, 0x18)
|
||||
/* YM147 */
|
||||
#define TAS2573_FCT_STATUS_CTRL TASDEVICE_REG(0x00, 0x68, 0x74)
|
||||
/* YM148 */
|
||||
#define TAS2573_FCT_STATUS_BINNING TASDEVICE_REG(0x00, 0x68, 0x78)
|
||||
/* YM664 */
|
||||
#define TAS2573_RE_OUT TASDEVICE_REG(0x00, 0x7A, 0x18)
|
||||
/* YM952 */
|
||||
#define TAS2573_SILENCE_DETECTED TASDEVICE_REG(0x00, 0x83, 0x60)
|
||||
/* YM954 */
|
||||
#define TAS2573_OPEN_CIRCUIT TASDEVICE_REG(0x00, 0x83, 0x68)
|
||||
/* YM955 */
|
||||
#define TAS2573_SHORTCKT TASDEVICE_REG(0x00, 0x83, 0x6C)
|
||||
|
||||
#define TAS2781_PRM_INT_MASK_REG TASDEVICE_REG(0x00, 0x00, 0x3b)
|
||||
#define TAS2781_PRM_CLK_CFG_REG TASDEVICE_REG(0x00, 0x00, 0x5c)
|
||||
#define TAS2781_PRM_RSVD_REG TASDEVICE_REG(0x00, 0x01, 0x19)
|
||||
|
||||
@@ -99,9 +99,10 @@ enum {
|
||||
SNDRV_HWDEP_IFACE_LINE6, /* Line6 USB processors */
|
||||
SNDRV_HWDEP_IFACE_FW_MOTU, /* MOTU FireWire series */
|
||||
SNDRV_HWDEP_IFACE_FW_FIREFACE, /* RME Fireface series */
|
||||
SNDRV_HWDEP_IFACE_CAIAQ, /* Native Instruments caiaq USB devices */
|
||||
|
||||
/* Don't forget to change the following: */
|
||||
SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_FIREFACE
|
||||
SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_CAIAQ
|
||||
};
|
||||
|
||||
struct snd_hwdep_info {
|
||||
|
||||
+117
-25
@@ -42,6 +42,7 @@
|
||||
#endif
|
||||
|
||||
struct snd_compr_file {
|
||||
struct list_head list;
|
||||
unsigned long caps;
|
||||
struct snd_compr_stream stream;
|
||||
};
|
||||
@@ -75,11 +76,11 @@ static inline void snd_compr_task_free_all(struct snd_compr_stream *stream) { }
|
||||
static int snd_compr_open(struct inode *inode, struct file *f)
|
||||
{
|
||||
struct snd_compr *compr;
|
||||
struct snd_compr_file *data;
|
||||
struct snd_compr_runtime *runtime;
|
||||
struct snd_compr_file *data = NULL;
|
||||
struct snd_compr_runtime *runtime = NULL;
|
||||
enum snd_compr_direction dirn;
|
||||
int maj = imajor(inode);
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if ((f->f_flags & O_ACCMODE) == O_WRONLY)
|
||||
dirn = SND_COMPRESS_PLAYBACK;
|
||||
@@ -101,17 +102,30 @@ static int snd_compr_open(struct inode *inode, struct file *f)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = snd_card_file_add(compr->card, f);
|
||||
if (ret < 0) {
|
||||
snd_card_unref(compr->card);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!try_module_get(compr->card->module)) {
|
||||
snd_card_file_remove(compr->card, f);
|
||||
snd_card_unref(compr->card);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (dirn != compr->direction) {
|
||||
pr_err("this device doesn't support this direction\n");
|
||||
snd_card_unref(compr->card);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto __error;
|
||||
}
|
||||
|
||||
data = kzalloc_obj(*data);
|
||||
if (!data) {
|
||||
snd_card_unref(compr->card);
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto __error;
|
||||
}
|
||||
INIT_LIST_HEAD(&data->list);
|
||||
|
||||
INIT_DELAYED_WORK(&data->stream.error_work, error_delayed_work);
|
||||
|
||||
@@ -121,9 +135,8 @@ static int snd_compr_open(struct inode *inode, struct file *f)
|
||||
data->stream.device = compr;
|
||||
runtime = kzalloc_obj(*runtime);
|
||||
if (!runtime) {
|
||||
kfree(data);
|
||||
snd_card_unref(compr->card);
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto __error;
|
||||
}
|
||||
runtime->state = SNDRV_PCM_STATE_OPEN;
|
||||
init_waitqueue_head(&runtime->sleep);
|
||||
@@ -132,11 +145,18 @@ static int snd_compr_open(struct inode *inode, struct file *f)
|
||||
#endif
|
||||
data->stream.runtime = runtime;
|
||||
f->private_data = (void *)data;
|
||||
scoped_guard(mutex, &compr->lock)
|
||||
scoped_guard(mutex, &compr->lock) {
|
||||
ret = compr->ops->open(&data->stream);
|
||||
if (!ret)
|
||||
list_add_tail(&data->list, &compr->open_list);
|
||||
}
|
||||
|
||||
__error:
|
||||
if (ret) {
|
||||
kfree(runtime);
|
||||
kfree(data);
|
||||
module_put(compr->card->module);
|
||||
snd_card_file_remove(compr->card, f);
|
||||
}
|
||||
snd_card_unref(compr->card);
|
||||
return ret;
|
||||
@@ -146,17 +166,23 @@ static int snd_compr_free(struct inode *inode, struct file *f)
|
||||
{
|
||||
struct snd_compr_file *data = f->private_data;
|
||||
struct snd_compr_runtime *runtime = data->stream.runtime;
|
||||
struct snd_compr *compr = data->stream.device;
|
||||
|
||||
cancel_delayed_work_sync(&data->stream.error_work);
|
||||
|
||||
switch (runtime->state) {
|
||||
case SNDRV_PCM_STATE_RUNNING:
|
||||
case SNDRV_PCM_STATE_DRAINING:
|
||||
case SNDRV_PCM_STATE_PAUSED:
|
||||
data->stream.ops->trigger(&data->stream, SNDRV_PCM_TRIGGER_STOP);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
scoped_guard(mutex, &compr->lock) {
|
||||
if (!list_empty(&data->list))
|
||||
list_del_init(&data->list);
|
||||
|
||||
switch (runtime->state) {
|
||||
case SNDRV_PCM_STATE_RUNNING:
|
||||
case SNDRV_PCM_STATE_DRAINING:
|
||||
case SNDRV_PCM_STATE_PAUSED:
|
||||
data->stream.ops->trigger(&data->stream, SNDRV_PCM_TRIGGER_STOP);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
snd_compr_task_free_all(&data->stream);
|
||||
@@ -164,8 +190,10 @@ static int snd_compr_free(struct inode *inode, struct file *f)
|
||||
data->stream.ops->free(&data->stream);
|
||||
if (!data->stream.runtime->dma_buffer_p)
|
||||
kfree(data->stream.runtime->buffer);
|
||||
module_put(data->stream.device->card->module);
|
||||
kfree(data->stream.runtime);
|
||||
kfree(data);
|
||||
snd_card_file_remove(compr->card, f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -669,13 +697,30 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
retval = snd_compr_allocate_buffer(stream, params);
|
||||
if (retval)
|
||||
return -ENOMEM;
|
||||
if (stream->next_track) {
|
||||
/*
|
||||
* total_bytes_available/transferred still refer to the
|
||||
* current buffer; its geometry must not change.
|
||||
*/
|
||||
if (params->buffer.fragment_size != stream->runtime->fragment_size ||
|
||||
params->buffer.fragments != stream->runtime->fragments)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
retval = snd_compr_allocate_buffer(stream, params);
|
||||
if (retval)
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = stream->ops->set_params(stream, params);
|
||||
if (retval)
|
||||
if (retval) {
|
||||
/* the stream stays OPEN: drop the buffer of the rejected setup */
|
||||
if (stream->runtime->state == SNDRV_PCM_STATE_OPEN &&
|
||||
!stream->runtime->dma_buffer_p) {
|
||||
kfree(stream->runtime->buffer);
|
||||
stream->runtime->buffer = NULL;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (stream->next_track)
|
||||
return retval;
|
||||
@@ -744,6 +789,9 @@ snd_compr_set_metadata(struct snd_compr_stream *stream, unsigned long arg)
|
||||
* we should allow parameter change only when stream has been
|
||||
* opened not in other cases
|
||||
*/
|
||||
if (stream->runtime->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
|
||||
if (copy_from_user(&metadata, (void __user *)arg, sizeof(metadata)))
|
||||
return -EFAULT;
|
||||
|
||||
@@ -919,8 +967,10 @@ static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
|
||||
* It is expected that driver will notify the drain completion and then
|
||||
* stream will be moved to SETUP state, even if draining resulted in an
|
||||
* error. We can trigger next track after this.
|
||||
*
|
||||
* The state has been set to SNDRV_PCM_STATE_DRAINING by the caller,
|
||||
* before the drain trigger was issued.
|
||||
*/
|
||||
stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
|
||||
mutex_unlock(&stream->device->lock);
|
||||
|
||||
/* we wait for drain to complete here, drain can return when
|
||||
@@ -945,6 +995,7 @@ static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
|
||||
|
||||
static int snd_compr_drain(struct snd_compr_stream *stream)
|
||||
{
|
||||
snd_pcm_state_t state;
|
||||
int retval;
|
||||
|
||||
switch (stream->runtime->state) {
|
||||
@@ -959,9 +1010,20 @@ static int snd_compr_drain(struct snd_compr_stream *stream)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* The state must be set to draining before the trigger is issued as the
|
||||
* drain can be completed by the driver either from the trigger callback
|
||||
* itself or from a different context as soon as the trigger is called.
|
||||
* A snd_compr_drain_notify() arriving before the state is updated would
|
||||
* be lost and the wait for the drain to finish would never be woken up.
|
||||
*/
|
||||
state = stream->runtime->state;
|
||||
stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
|
||||
|
||||
retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN);
|
||||
if (retval) {
|
||||
pr_debug("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval);
|
||||
stream->runtime->state = state;
|
||||
wake_up(&stream->runtime->sleep);
|
||||
return retval;
|
||||
}
|
||||
@@ -997,6 +1059,7 @@ static int snd_compr_next_track(struct snd_compr_stream *stream)
|
||||
|
||||
static int snd_compr_partial_drain(struct snd_compr_stream *stream)
|
||||
{
|
||||
snd_pcm_state_t state;
|
||||
int retval;
|
||||
|
||||
switch (stream->runtime->state) {
|
||||
@@ -1020,9 +1083,16 @@ static int snd_compr_partial_drain(struct snd_compr_stream *stream)
|
||||
return -EPERM;
|
||||
|
||||
stream->partial_drain = true;
|
||||
|
||||
/* See the comment in snd_compr_drain() on the state handling */
|
||||
state = stream->runtime->state;
|
||||
stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
|
||||
|
||||
retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN);
|
||||
if (retval) {
|
||||
pr_debug("Partial drain returned failure\n");
|
||||
stream->partial_drain = false;
|
||||
stream->runtime->state = state;
|
||||
wake_up(&stream->runtime->sleep);
|
||||
return retval;
|
||||
}
|
||||
@@ -1136,7 +1206,9 @@ static int snd_compr_task_start_prepare(struct snd_compr_task_runtime *task,
|
||||
{
|
||||
if (task == NULL)
|
||||
return -EINVAL;
|
||||
if (task->state >= SND_COMPRESS_TASK_STATE_FINISHED)
|
||||
/* only an unqueued or already finished task may be (re)started */
|
||||
if (task->state != SND_COMPRESS_TASK_STATE_IDLE &&
|
||||
task->state != SND_COMPRESS_TASK_STATE_FINISHED)
|
||||
return -EBUSY;
|
||||
if (utask->input_size > task->input->size)
|
||||
return -EINVAL;
|
||||
@@ -1432,8 +1504,27 @@ static int snd_compress_dev_register(struct snd_device *device)
|
||||
static int snd_compress_dev_disconnect(struct snd_device *device)
|
||||
{
|
||||
struct snd_compr *compr;
|
||||
struct snd_compr_file *data;
|
||||
|
||||
compr = device->device_data;
|
||||
scoped_guard(mutex, &compr->lock) {
|
||||
list_for_each_entry(data, &compr->open_list, list) {
|
||||
switch (data->stream.runtime->state) {
|
||||
case SNDRV_PCM_STATE_RUNNING:
|
||||
case SNDRV_PCM_STATE_DRAINING:
|
||||
case SNDRV_PCM_STATE_PAUSED:
|
||||
data->stream.ops->trigger(&data->stream,
|
||||
SNDRV_PCM_TRIGGER_STOP);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
data->stream.runtime->state = SNDRV_PCM_STATE_DISCONNECTED;
|
||||
wake_up(&data->stream.runtime->sleep);
|
||||
}
|
||||
}
|
||||
|
||||
snd_unregister_device(compr->dev);
|
||||
return 0;
|
||||
}
|
||||
@@ -1541,6 +1632,7 @@ int snd_compress_new(struct snd_card *card, int device,
|
||||
compr->device = device;
|
||||
compr->direction = dirn;
|
||||
mutex_init(&compr->lock);
|
||||
INIT_LIST_HEAD(&compr->open_list);
|
||||
|
||||
snd_compress_set_id(compr, id);
|
||||
|
||||
|
||||
@@ -1802,6 +1802,8 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
alloc_size = compute_user_elem_size(private_size, count);
|
||||
|
||||
guard(rwsem_write)(&card->controls_rwsem);
|
||||
if (card->shutdown)
|
||||
return -ENODEV;
|
||||
if (check_user_elem_overflow(card, alloc_size))
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -563,12 +563,43 @@ static ssize_t set_led_id(struct snd_ctl_led_card *led_card, const char *buf, si
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* snd_ctl_led_disconnect() removes these files with card->controls_rwsem
|
||||
* held. so don't let the removal wait for a callback that takes it.
|
||||
*/
|
||||
static struct kernfs_node *snd_ctl_led_sysfs_enter(struct device *dev,
|
||||
struct device_attribute *attr)
|
||||
{
|
||||
struct kernfs_node *kn;
|
||||
|
||||
if (!try_module_get(THIS_MODULE))
|
||||
return NULL;
|
||||
kn = sysfs_break_active_protection(&dev->kobj, &attr->attr);
|
||||
if (!kn)
|
||||
module_put(THIS_MODULE);
|
||||
return kn;
|
||||
}
|
||||
|
||||
static void snd_ctl_led_sysfs_exit(struct kernfs_node *kn)
|
||||
{
|
||||
sysfs_unbreak_active_protection(kn);
|
||||
module_put(THIS_MODULE);
|
||||
}
|
||||
|
||||
static ssize_t attach_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
|
||||
return set_led_id(led_card, buf, count, true);
|
||||
struct kernfs_node *kn;
|
||||
ssize_t ret;
|
||||
|
||||
kn = snd_ctl_led_sysfs_enter(dev, attr);
|
||||
if (!kn)
|
||||
return -ENODEV;
|
||||
ret = set_led_id(led_card, buf, count, true);
|
||||
snd_ctl_led_sysfs_exit(kn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t detach_store(struct device *dev,
|
||||
@@ -576,7 +607,15 @@ static ssize_t detach_store(struct device *dev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
|
||||
return set_led_id(led_card, buf, count, false);
|
||||
struct kernfs_node *kn;
|
||||
ssize_t ret;
|
||||
|
||||
kn = snd_ctl_led_sysfs_enter(dev, attr);
|
||||
if (!kn)
|
||||
return -ENODEV;
|
||||
ret = set_led_id(led_card, buf, count, false);
|
||||
snd_ctl_led_sysfs_exit(kn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t reset_store(struct device *dev,
|
||||
@@ -594,10 +633,8 @@ static ssize_t reset_store(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t list_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static ssize_t snd_ctl_led_list(struct snd_ctl_led_card *led_card, char *buf)
|
||||
{
|
||||
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
|
||||
struct snd_ctl_led_ctl *lctl;
|
||||
size_t l = 0;
|
||||
struct snd_card *card __free(snd_card_unref) =
|
||||
@@ -620,6 +657,21 @@ static ssize_t list_show(struct device *dev,
|
||||
return l;
|
||||
}
|
||||
|
||||
static ssize_t list_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
|
||||
struct kernfs_node *kn;
|
||||
ssize_t ret;
|
||||
|
||||
kn = snd_ctl_led_sysfs_enter(dev, attr);
|
||||
if (!kn)
|
||||
return -ENODEV;
|
||||
ret = snd_ctl_led_list(led_card, buf);
|
||||
snd_ctl_led_sysfs_exit(kn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_WO(attach);
|
||||
static DEVICE_ATTR_WO(detach);
|
||||
static DEVICE_ATTR_WO(reset);
|
||||
|
||||
@@ -38,6 +38,7 @@ static int get_available_index(struct snd_card *card, const char *name)
|
||||
sid.iface = SNDRV_CTL_ELEM_IFACE_CARD;
|
||||
strscpy(sid.name, name, sizeof(sid.name));
|
||||
|
||||
guard(rwsem_read)(&card->controls_rwsem);
|
||||
while (snd_ctl_find_id(card, &sid)) {
|
||||
sid.index++;
|
||||
/* reset numid; otherwise snd_ctl_find_id() hits this again */
|
||||
|
||||
+2
-1
@@ -528,6 +528,8 @@ int snd_info_card_register(struct snd_card *card)
|
||||
void snd_info_card_id_change(struct snd_card *card)
|
||||
{
|
||||
guard(mutex)(&info_mutex);
|
||||
if (card->shutdown)
|
||||
return;
|
||||
if (card->proc_root_link) {
|
||||
proc_remove(card->proc_root_link);
|
||||
card->proc_root_link = NULL;
|
||||
@@ -555,7 +557,6 @@ void snd_info_card_disconnect(struct snd_card *card)
|
||||
if (card->proc_root)
|
||||
snd_info_clear_entries(card->proc_root);
|
||||
card->proc_root_link = NULL;
|
||||
card->proc_root = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+45
-50
@@ -82,8 +82,24 @@ static int module_slot_match(struct module *module, int idx)
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
|
||||
int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag);
|
||||
EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
|
||||
static DEFINE_MUTEX(mixer_oss_notify_mutex);
|
||||
static int (*mixer_oss_notify_callback)(struct snd_card *card, int cmd);
|
||||
|
||||
void snd_mixer_oss_notify(struct snd_card *card, int cmd)
|
||||
{
|
||||
guard(mutex)(&mixer_oss_notify_mutex);
|
||||
if (mixer_oss_notify_callback)
|
||||
mixer_oss_notify_callback(card, cmd);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_mixer_oss_notify);
|
||||
|
||||
void snd_mixer_oss_set_notify(int (*callback)(struct snd_card *, int))
|
||||
{
|
||||
/* Wait for callbacks, including a final module_put(), to return. */
|
||||
guard(mutex)(&mixer_oss_notify_mutex);
|
||||
mixer_oss_notify_callback = callback;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_mixer_oss_set_notify);
|
||||
#endif
|
||||
|
||||
static int check_empty_slot(struct module *module, int slot)
|
||||
@@ -216,11 +232,13 @@ static void __snd_card_release(struct device *dev, void *data)
|
||||
* is added automatically. In that way, the resource disconnection is assured
|
||||
* at first, then released in the expected order.
|
||||
*
|
||||
* If an error happens at the probe before snd_card_register() is called and
|
||||
* there have been other devres resources, you'd need to free the card manually
|
||||
* via snd_card_free() call in the error; otherwise it may lead to UAF due to
|
||||
* devres call orders. You can use snd_card_free_on_error() helper for
|
||||
* handling it more easily.
|
||||
* Caveat: if an error happens at the probe before snd_card_register() is
|
||||
* called and there have been other devres resources that are referred at the
|
||||
* card-level destructor call, you'd still need to free the card manually;
|
||||
* otherwise it may lead to UAF due to devres call orders. Instead of a manual
|
||||
* snd_card_free() call, you can use the automatic clean-up for the card
|
||||
* pointer via __free(snd_card_free), too. In this case, don't forget to do
|
||||
* NULL-clear the card pointer before the successful return!
|
||||
*
|
||||
* Return: zero if successful, or a negative error code
|
||||
*/
|
||||
@@ -250,30 +268,6 @@ int snd_devm_card_new(struct device *parent, int idx, const char *xid,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_devm_card_new);
|
||||
|
||||
/**
|
||||
* snd_card_free_on_error - a small helper for handling devm probe errors
|
||||
* @dev: the managed device object
|
||||
* @ret: the return code from the probe callback
|
||||
*
|
||||
* This function handles the explicit snd_card_free() call at the error from
|
||||
* the probe callback. It's just a small helper for simplifying the error
|
||||
* handling with the managed devices.
|
||||
*
|
||||
* Return: zero if successful, or a negative error code
|
||||
*/
|
||||
int snd_card_free_on_error(struct device *dev, int ret)
|
||||
{
|
||||
struct snd_card *card;
|
||||
|
||||
if (!ret)
|
||||
return 0;
|
||||
card = devres_find(dev, __snd_card_release, NULL, NULL);
|
||||
if (card)
|
||||
snd_card_free(card);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_card_free_on_error);
|
||||
|
||||
static int snd_card_init(struct snd_card *card, struct device *parent,
|
||||
int idx, const char *xid, struct module *module,
|
||||
size_t extra_size)
|
||||
@@ -356,7 +350,7 @@ static int snd_card_init(struct snd_card *card, struct device *parent,
|
||||
err = snd_info_card_create(card);
|
||||
if (err < 0) {
|
||||
dev_err(parent, "unable to create card info\n");
|
||||
goto __error_ctl;
|
||||
goto __error;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
@@ -365,16 +359,16 @@ static int snd_card_init(struct snd_card *card, struct device *parent,
|
||||
#endif
|
||||
#ifdef CONFIG_SND_CTL_DEBUG
|
||||
card->value_buf = kmalloc_obj(*card->value_buf);
|
||||
if (!card->value_buf)
|
||||
return -ENOMEM;
|
||||
if (!card->value_buf) {
|
||||
err = -ENOMEM;
|
||||
goto __error;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
__error_ctl:
|
||||
snd_device_free_all(card);
|
||||
__error:
|
||||
put_device(&card->card_dev);
|
||||
return err;
|
||||
snd_card_free(card);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -530,8 +524,7 @@ void snd_card_disconnect(struct snd_card *card)
|
||||
/* at this point, they cannot respond to any calls except release() */
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
|
||||
if (snd_mixer_oss_notify_callback)
|
||||
snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_DISCONNECT);
|
||||
snd_mixer_oss_notify(card, SND_MIXER_OSS_NOTIFY_DISCONNECT);
|
||||
#endif
|
||||
|
||||
/* notify all devices that we are disconnected */
|
||||
@@ -557,6 +550,8 @@ void snd_card_disconnect(struct snd_card *card)
|
||||
clear_bit(card->number, snd_cards_lock);
|
||||
}
|
||||
|
||||
/* order card->shutdown store against power_ref read */
|
||||
smp_mb();
|
||||
snd_power_sync_ref(card);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_card_disconnect);
|
||||
@@ -587,8 +582,7 @@ static int snd_card_do_free(struct snd_card *card)
|
||||
|
||||
card->releasing = true;
|
||||
#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
|
||||
if (snd_mixer_oss_notify_callback)
|
||||
snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_FREE);
|
||||
snd_mixer_oss_notify(card, SND_MIXER_OSS_NOTIFY_FREE);
|
||||
#endif
|
||||
snd_device_free_all(card);
|
||||
kfree(card->components);
|
||||
@@ -932,8 +926,7 @@ int snd_card_register(struct snd_card *card)
|
||||
return err;
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
|
||||
if (snd_mixer_oss_notify_callback)
|
||||
snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
|
||||
snd_mixer_oss_notify(card, SND_MIXER_OSS_NOTIFY_REGISTER);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -1174,12 +1167,14 @@ EXPORT_SYMBOL(snd_card_file_remove);
|
||||
int snd_power_ref_and_wait(struct snd_card *card)
|
||||
{
|
||||
snd_power_ref(card);
|
||||
if (snd_power_get_state(card) == SNDRV_CTL_POWER_D0)
|
||||
return 0;
|
||||
wait_event_cmd(card->power_sleep,
|
||||
card->shutdown ||
|
||||
snd_power_get_state(card) == SNDRV_CTL_POWER_D0,
|
||||
snd_power_unref(card), snd_power_ref(card));
|
||||
/* order power_ref increment against card->shutdown read */
|
||||
smp_mb__after_atomic();
|
||||
if (snd_power_get_state(card) != SNDRV_CTL_POWER_D0) {
|
||||
wait_event_cmd(card->power_sleep,
|
||||
card->shutdown ||
|
||||
snd_power_get_state(card) == SNDRV_CTL_POWER_D0,
|
||||
snd_power_unref(card), snd_power_ref(card));
|
||||
}
|
||||
if (card->shutdown) {
|
||||
snd_power_unref(card);
|
||||
return -ENODEV;
|
||||
|
||||
+54
-13
@@ -38,6 +38,7 @@ static const int jack_switch_types[SND_JACK_SWITCH_TYPES] = {
|
||||
};
|
||||
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
||||
|
||||
static void snd_jack_add_debugfs(struct snd_jack *jack);
|
||||
static void snd_jack_remove_debugfs(struct snd_jack *jack);
|
||||
|
||||
static int snd_jack_dev_disconnect(struct snd_device *device)
|
||||
@@ -68,6 +69,9 @@ static int snd_jack_dev_free(struct snd_device *device)
|
||||
struct snd_card *card = device->card;
|
||||
struct snd_jack_kctl *jack_kctl, *tmp_jack_kctl;
|
||||
|
||||
/* Remove debugfs while the controls are still linked. */
|
||||
snd_jack_remove_debugfs(jack);
|
||||
|
||||
list_for_each_entry_safe(jack_kctl, tmp_jack_kctl, &jack->kctl_list, list) {
|
||||
list_del_init(&jack_kctl->list);
|
||||
snd_ctl_remove(card, jack_kctl->kctl);
|
||||
@@ -85,11 +89,10 @@ static int snd_jack_dev_free(struct snd_device *device)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
static int snd_jack_dev_register(struct snd_device *device)
|
||||
static int snd_jack_input_dev_register(struct snd_card *card,
|
||||
struct snd_jack *jack)
|
||||
{
|
||||
struct snd_jack *jack = device->device_data;
|
||||
struct snd_card *card = device->card;
|
||||
int err, i;
|
||||
int i;
|
||||
|
||||
snprintf(jack->name, sizeof(jack->name), "%s %s",
|
||||
card->shortname, jack->id);
|
||||
@@ -117,14 +120,32 @@ static int snd_jack_dev_register(struct snd_device *device)
|
||||
input_set_capability(jack->input_dev, EV_KEY, jack->key[i]);
|
||||
}
|
||||
|
||||
err = input_register_device(jack->input_dev);
|
||||
if (err == 0)
|
||||
jack->registered = 1;
|
||||
|
||||
return err;
|
||||
return input_register_device(jack->input_dev);
|
||||
}
|
||||
#else
|
||||
static inline int snd_jack_input_dev_register(struct snd_card *card,
|
||||
struct snd_jack *jack)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
||||
|
||||
static int snd_jack_dev_register(struct snd_device *device)
|
||||
{
|
||||
struct snd_card *card = device->card;
|
||||
struct snd_jack *jack = device->device_data;
|
||||
int err;
|
||||
|
||||
err = snd_jack_input_dev_register(card, jack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
snd_jack_add_debugfs(jack);
|
||||
|
||||
jack->registered = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_JACK_INJECTION_DEBUG
|
||||
static void snd_jack_inject_report(struct snd_jack_kctl *jack_kctl, int status)
|
||||
{
|
||||
@@ -303,6 +324,7 @@ static ssize_t jack_type_read(struct file *file,
|
||||
}
|
||||
|
||||
static const struct file_operations jack_type_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = jack_type_read,
|
||||
.llseek = default_llseek,
|
||||
@@ -310,6 +332,7 @@ static const struct file_operations jack_type_fops = {
|
||||
#endif
|
||||
|
||||
static const struct file_operations sw_inject_enable_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = sw_inject_enable_read,
|
||||
.write = sw_inject_enable_write,
|
||||
@@ -317,24 +340,28 @@ static const struct file_operations sw_inject_enable_fops = {
|
||||
};
|
||||
|
||||
static const struct file_operations jackin_inject_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.write = jackin_inject_write,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static const struct file_operations jack_kctl_id_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = jack_kctl_id_read,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static const struct file_operations jack_kctl_mask_bits_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = jack_kctl_mask_bits_read,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static const struct file_operations jack_kctl_status_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = jack_kctl_status_read,
|
||||
.llseek = default_llseek,
|
||||
@@ -346,6 +373,9 @@ static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack,
|
||||
char *tname;
|
||||
int i;
|
||||
|
||||
if (jack_kctl->jack_debugfs_root)
|
||||
return 0;
|
||||
|
||||
/* Don't create injection interface for Phantom jacks */
|
||||
if (strstr(jack_kctl->kctl->id.name, "Phantom"))
|
||||
return 0;
|
||||
@@ -384,6 +414,14 @@ static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snd_jack_add_debugfs(struct snd_jack *jack)
|
||||
{
|
||||
struct snd_jack_kctl *jack_kctl;
|
||||
|
||||
list_for_each_entry(jack_kctl, &jack->kctl_list, list)
|
||||
snd_jack_debugfs_add_inject_node(jack, jack_kctl);
|
||||
}
|
||||
|
||||
static void snd_jack_remove_debugfs(struct snd_jack *jack)
|
||||
{
|
||||
struct snd_jack_kctl *jack_kctl;
|
||||
@@ -400,6 +438,10 @@ static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snd_jack_add_debugfs(struct snd_jack *jack)
|
||||
{
|
||||
}
|
||||
|
||||
static void snd_jack_remove_debugfs(struct snd_jack *jack)
|
||||
{
|
||||
}
|
||||
@@ -420,7 +462,8 @@ static void snd_jack_kctl_add(struct snd_jack *jack, struct snd_jack_kctl *jack_
|
||||
{
|
||||
jack_kctl->jack = jack;
|
||||
list_add_tail(&jack_kctl->list, &jack->kctl_list);
|
||||
snd_jack_debugfs_add_inject_node(jack, jack_kctl);
|
||||
if (jack->registered)
|
||||
snd_jack_debugfs_add_inject_node(jack, jack_kctl);
|
||||
}
|
||||
|
||||
static struct snd_jack_kctl * snd_jack_kctl_new(struct snd_card *card, const char *name, unsigned int mask)
|
||||
@@ -450,7 +493,7 @@ static struct snd_jack_kctl * snd_jack_kctl_new(struct snd_card *card, const cha
|
||||
|
||||
return jack_kctl;
|
||||
error:
|
||||
snd_ctl_free_one(kctl);
|
||||
snd_ctl_remove(card, kctl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -501,9 +544,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
|
||||
int err;
|
||||
static const struct snd_device_ops ops = {
|
||||
.dev_free = snd_jack_dev_free,
|
||||
#ifdef CONFIG_SND_JACK_INPUT_DEV
|
||||
.dev_register = snd_jack_dev_register,
|
||||
#endif /* CONFIG_SND_JACK_INPUT_DEV */
|
||||
.dev_disconnect = snd_jack_dev_disconnect,
|
||||
};
|
||||
|
||||
|
||||
+4
-1
@@ -183,11 +183,13 @@ void snd_refcount_init(struct snd_refcount *ref)
|
||||
{
|
||||
atomic_set(&ref->count, 0);
|
||||
init_waitqueue_head(&ref->waiter);
|
||||
spin_lock_init(&ref->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_refcount_init);
|
||||
|
||||
void snd_refcount_put(struct snd_refcount *ref)
|
||||
{
|
||||
guard(spinlock_irqsave)(&ref->lock);
|
||||
if (atomic_dec_and_test(&ref->count))
|
||||
wake_up(&ref->waiter);
|
||||
}
|
||||
@@ -195,6 +197,7 @@ EXPORT_SYMBOL_GPL(snd_refcount_put);
|
||||
|
||||
void snd_refcount_sync(struct snd_refcount *ref)
|
||||
{
|
||||
wait_event(ref->waiter, !atomic_read(&ref->count));
|
||||
guard(spinlock_irq)(&ref->lock);
|
||||
wait_event_lock_irq(ref->waiter, !atomic_read(&ref->count), ref->lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_refcount_sync);
|
||||
Loaded 100 of 832 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user