sound updates for 7.3-rc1

It was a fairly busy development cycle -- the changes spread over from
 the core side to leaf drivers, with lots of cleanups and enhancements.
 Here we go, some highlights:
 
 * ALSA core:
 - Extension of ALSA control component list ABI
 - Locking optimization and RCU conversion of ALSA sequencer core
 - A few hardening fixes for UMP and sequencer core
 - Drop __bitwise and __force prefix from UAPI definitions
 
 * ASoC:
 - Automatic DAI format selection code deployment across many drivers
 - Sorting of register default tables to prevent ordering issues in
   many drivers
 - Lots of code cleanups and refactoring
 - Updates in Qualcomm driver stack
 - New platforms: AMD ACP7.B/F, Cirrus Logic CS35L62, Loongson 2K0300,
   Meson GX, Qualcomm LPI MI2S, SM8475, WSA855X, Realtek RT1321 VA1/2
   and RT766/7
 
 * HD-audio:
 - Support for AW88399 HD-audio side codec for Lenovo Legion laptops
 - Support for Hygon and Lisuan HDMI controllers
 - Robustness fixes for wild device binding
 - Lots of quirks/fixups: Realtek and Conexant codecs for ASUS, Lenovo,
   Acer, etc
 
 * USB-audio:
 - Support for Pioneer DJ DJM-S11
 - Scarlett2/FCP private URB notification fixes
 - Extended quirk_flags to 64bit
 - Hardening fixes for 6fire, bcd2000, usx2y
 - Device-specific quirks for Mackie, Valeton, SPACETOUCH
 
 * General:
 - Auto-cleanup for put_device() and firmware loading across multiple
   platforms
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmqEXisOHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE9H7g/7B1MuyObFnvkddyRlUP7tpXoHdMrRGP/1H9gD
 f5eczeXovv4X4tkw/nsZcaWAH+9hQrswP/2CbK3ZxjkZomq8kc4llCZCt7pCfU52
 FMLMRs+3/Rf0BLN+HJkjCRM1WPKaFcuo5ZFOCfkHrUTb0Wqs141Tl11891KGzUjg
 jSuDr9dfrEJdSYHBDTlpn/2+pau8sNapHkiKrOqU/B9Ky49ngb+R6NjcphP6q1l4
 bS8eoTsXi/XrKEK7eenq+0NX1FwYP1q8DXYSxE/zV2u6SAJDqmw4qEs1vziVUEtV
 APVX+4HhMEFCHByvDIGc5HqsFsa05Uvwyfb90wQQcic7d9xuAbNK1NyrtNiDoPna
 e/K6N3SddZSukXWNcTtbNGN1a7TMc0Y7cs+jOCqR6uw+SC3RdPF46LVmfpy5sFf+
 PT3YCrWcArGrgvkt6frOUI3XEl00d7dns8J8uwsSWXwm7X/aSwC1Fy0v+JJSJPvR
 taOOw2/zSXVR05G11YDdUcf9qDTkExM35j0AFrLViNj87m/U03oHRvQgAxGNgEPN
 /q8lqt/R2XUULYNrR/4cWMrFGl32/+lmMO52a5uFIuqPgnG3S7WrjPqxibmZmgrl
 k4hEPpU5jqstoByNHV4f8DbYBRwt906skgGGcVnku38XEaFilGZF4x5BkT7vvnxX
 7o0MEfE=
 =kp17
 -----END PGP SIGNATURE-----

Merge tag 'sound-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound updates from Takashi Iwai:
 "It was a fairly busy development cycle - the changes spread over from
  the core side to leaf drivers, with lots of cleanups and enhancements.
  Here we go, some highlights:

  ALSA core:
   - Extension of ALSA control component list ABI
   - Locking optimization and RCU conversion of ALSA sequencer core
   - A few hardening fixes for UMP and sequencer core
   - Drop __bitwise and __force prefix from UAPI definitions

  ASoC:
   - Automatic DAI format selection code deployment across many drivers
   - Sorting of register default tables to prevent ordering issues in
     many drivers
   - Lots of code cleanups and refactoring
   - Updates in Qualcomm driver stack
   - New platforms: AMD ACP7.B/F, Cirrus Logic CS35L62, Loongson
     2K0300, Meson GX, Qualcomm LPI MI2S, SM8475, WSA855X, Realtek
     RT1321 VA1/2 and RT766/7

  HD-audio:
   - Support for AW88399 HD-audio side codec for Lenovo Legion laptops
   - Support for Hygon and Lisuan HDMI controllers
   - Robustness fixes for wild device binding
   - Lots of quirks/fixups: Realtek and Conexant codecs for ASUS,
     Lenovo, Acer, etc

  USB-audio:
   - Support for Pioneer DJ DJM-S11
   - Scarlett2/FCP private URB notification fixes
   - Extended quirk_flags to 64bit
   - Hardening fixes for 6fire, bcd2000, usx2y
   - Device-specific quirks for Mackie, Valeton, SPACETOUCH

  General:
   - Auto-cleanup for put_device() and firmware loading across multiple
     platforms"

* tag 'sound-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (791 commits)
  ALSA: hda: Fix connection list comparison in proc output
  ALSA: docs: fix dead link to Intel HD-audio spec
  ALSA: usb-audio: Add delay quirk for SPACETOUCH USB Audio
  ALSA: hda: Add Lisuan HDMI controller and codec support
  ALSA: hda/realtek: Fix Lenovo Yoga Slim 7 14AKP10 quirk ordering
  ALSA: hda/tas2781: Add hardware stabilization delay during firmware load retries
  ALSA: hda/realtek: Fix mute LED for HP Victus 15-fa1xxx (MB 8C3F)
  ALSA: hda/realtek: Add micmute LED quirk for Acer Aspire A515-57
  ASoC: tas2783-sdw: do not treat read-only Controls as writable
  ASoC: SOF: validate topology volume range before allocation
  ASoC: cs35l56: Use IRQ provided by the SoundWire core
  soundwire: bus_type: Create IRQ mapping before calling driver probe()
  ASoC: cs35l56: Move cs35l56_irq_request() after cs35l56_irq()
  ASoC: cs35l56: Request IRQ in cs35l56_common_probe()
  ALSA: core: Fix use-after-free in snd_card_do_free()
  ALSA: hda/realtek: Drop duplicate quirk for Lenovo 0x17aa:0x38df
  ALSA: usb-audio: Rename the Audient iD14 monitor mix volume control
  ASoC: tas2781: Refactor calibration start kcontrol creation to separate helper
  ASoC: dt-bindings: es8316: Fix supply property constraints
  ALSA: seq: midi: Serialize input teardown with event_input
  ...
This commit is contained in:
Linus Torvalds 2026-08-19 10:04:59 -07:00
commit e5c91aac49
628 changed files with 20569 additions and 10121 deletions

View File

@ -30,7 +30,7 @@ properties:
minItems: 1
maxItems: 3
description:
Base PLL clocks of audio susbsytem, used to configure base clock
Base PLL clocks of audio subsystem, used to configure base clock
frequencies for different audio use-cases.
patternProperties:

View File

@ -31,7 +31,7 @@ properties:
minItems: 1
maxItems: 3
description:
Base PLL clocks of audio susbsytem, used to configure base clock
Base PLL clocks of audio subsystem, used to configure base clock
frequencies for different audio use-cases.
patternProperties:

View File

@ -0,0 +1,240 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/cirrus,cs35l36.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Cirrus Logic CS35L36 Speaker Amplifier
maintainers:
- David Rhodes <drhodes@opensource.cirrus.com>
- patches@opensource.cirrus.com
description:
CS35L36 is a boosted mono Class D amplifier
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
enum:
- cirrus,cs35l36
reg:
maxItems: 1
interrupts:
maxItems: 1
VA-supply:
description: Voltage regulator of analog internal section
VP-supply:
description: Voltage regulator of boost converter
reset-gpios:
maxItems: 1
cirrus,boost-ctl-millivolt:
description: Boost converter output voltage (step 50)
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 2550
maximum: 12000
cirrus,boost-peak-milliamp:
description: Boost-converter peak current limit (step 50)
$ref: /schemas/types.yaml#/definitions/uint32
default: 4500
minimum: 1600
maximum: 4500
cirrus,boost-ind-nanohenry:
description: Initial inductor estimation reference value (1000=1μH, 1200=1.2μH)
$ref: /schemas/types.yaml#/definitions/uint32
default: 1000
cirrus,multi-amp-mode:
description: Hi-Z ASP port when more than one amplifier in system
type: boolean
cirrus,boost-ctl-select:
description: Boost converter control source selection
$ref: /schemas/types.yaml#/definitions/uint32
default: 1
enum:
- 0 # Control Port
- 1 # Class
- 2 # Sync
cirrus,amp-pcm-inv:
description: Invert incoming PCM data when true
type: boolean
cirrus,imon-pol-inv:
description: Invert polarity of outbound IMON feedback when true
type: boolean
cirrus,vmon-pol-inv:
description: Invert polarity of outbound VMON feedback when true
type: boolean
cirrus,dcm-mode-enable:
description: Enable boost converter automatic Discontinuous Conduction Mode
type: boolean
cirrus,weak-fet-disable:
description: Reduce output driver strength in Weak-FET Drive Mode when true
type: boolean
cirrus,classh-wk-fet-delay-ms:
description: Weak-FET entry delay
default: 100
enum: [0, 5, 10, 50, 100, 200, 500, 1000]
cirrus,classh-weak-fet-thld-millivolt:
description: Weak-FET drive threshold
$ref: /schemas/types.yaml#/definitions/uint32
enum: [50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700]
cirrus,temp-warn-threshold:
description: Overtemperature warning threshold
$ref: /schemas/types.yaml#/definitions/uint32
default: 2
enum:
- 0 # 105°C
- 1 # 115°C
- 2 # 125°C
- 3 # 135°C
cirrus,irq-drive-select:
description: Interrupt output driver type
$ref: /schemas/types.yaml#/definitions/uint32
default: 1
enum:
- 0 # open-drain
- 1 # push-pull
cirrus,irq-gpio-select:
description: Programmable IRQ pin selection
$ref: /schemas/types.yaml#/definitions/uint32
enum:
- 0 # PDM_DATA/SWIRE_SD/INT
- 1 # GPIO
cirrus,vpbr-config:
$ref: "#/$defs/vpbr-config"
$defs:
vpbr-config:
description: Brownout prevention configuration sub-node
type: object
additionalProperties: false
properties:
cirrus,vpbr-en:
description: VBST brownout prevention enable
$ref: /schemas/types.yaml#/definitions/uint32
default: 0
enum:
- 0 # disabled
- 1 # enabled
cirrus,vpbr-thld:
description: Initial VPBR threshold voltage
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 2
maximum: 31
cirrus,vpbr-atk-rate:
description: Attenuation attack step rate
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 7
cirrus,vpbr-atk-vol:
description: VP brownout prevention step size
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 7
cirrus,vpbr-max-attn:
description: Maximum attenuation during VP brownout prevention (dB)
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 15
cirrus,vpbr-wait:
description: Delay between brownout clearance and attenuation release (ms)
$ref: /schemas/types.yaml#/definitions/uint32
default: 1
enum:
- 0 # 10
- 1 # 100
- 2 # 250
- 3 # 500
cirrus,vpbr-rel-rate:
description: Attenuation release step rate
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 7
cirrus,vpbr-mute-en:
description: Mute audio if maximum attenuation reached
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 1
required:
- compatible
- reg
- interrupts
- VA-supply
- cirrus,boost-ctl-millivolt
- cirrus,boost-peak-milliamp
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
codec@40 {
compatible = "cirrus,cs35l36";
reg = <0x40>;
VA-supply = <&dummy_vreg>;
VP-supply = <&dummy_vreg>;
reset-gpios = <&gpio0 54 GPIO_ACTIVE_HIGH>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
cirrus,boost-ind-nanohenry = <1000>;
cirrus,boost-ctl-millivolt = <10000>;
cirrus,boost-peak-milliamp = <4500>;
cirrus,boost-ctl-select = <0>;
cirrus,classh-wk-fet-delay-ms = <100>;
cirrus,classh-weak-fet-thld-millivolt = <100>;
cirrus,temp-warn-threshold = <1>;
cirrus,multi-amp-mode;
cirrus,irq-drive-select = <1>;
cirrus,irq-gpio-select = <1>;
cirrus,vpbr-config {
cirrus,vpbr-en = <0>;
cirrus,vpbr-thld = <5>;
cirrus,vpbr-atk-rate = <2>;
cirrus,vpbr-atk-vol = <1>;
cirrus,vpbr-max-attn = <9>;
cirrus,vpbr-wait = <1>;
cirrus,vpbr-rel-rate = <5>;
cirrus,vpbr-mute-en = <0>;
};
};
};
...

View File

@ -27,6 +27,7 @@ properties:
enum:
- cirrus,cs42l43
- cirrus,cs42l43b
- cirrus,cs42l44
reg:
maxItems: 1

View File

@ -1,168 +0,0 @@
CS35L36 Speaker Amplifier
Required properties:
- compatible : "cirrus,cs35l36"
- reg : the I2C address of the device for I2C
- VA-supply, VP-supply : power supplies for the device,
as covered in
Documentation/devicetree/bindings/regulator/regulator.txt.
- cirrus,boost-ctl-millivolt : Boost Voltage Value. Configures the boost
converter's output voltage in mV. The range is from 2550mV to 12000mV with
increments of 50mV.
(Default) VP
- cirrus,boost-peak-milliamp : Boost-converter peak current limit in mA.
Configures the peak current by monitoring the current through the boost FET.
Range starts at 1600mA and goes to a maximum of 4500mA with increments of
50mA.
(Default) 4.50 Amps
- cirrus,boost-ind-nanohenry : Inductor estimation LBST reference value.
Seeds the digital boost converter's inductor estimation block with the initial
inductance value to reference.
1000 = 1uH (Default)
1200 = 1.2uH
Optional properties:
- cirrus,multi-amp-mode : Boolean to determine if there are more than
one amplifier in the system. If more than one it is best to Hi-Z the ASP
port to prevent bus contention on the output signal
- cirrus,boost-ctl-select : Boost converter control source selection.
Selects the source of the BST_CTL target VBST voltage for the boost
converter to generate.
0x00 - Control Port Value
0x01 - Class H Tracking (Default)
0x10 - MultiDevice Sync Value
- cirrus,amp-pcm-inv : Boolean to determine Amplifier will invert incoming
PCM data
- cirrus,imon-pol-inv : Boolean to determine Amplifier will invert the
polarity of outbound IMON feedback data
- cirrus,vmon-pol-inv : Boolean to determine Amplifier will invert the
polarity of outbound VMON feedback data
- cirrus,dcm-mode-enable : Boost converter automatic DCM Mode enable.
This enables the digital boost converter to operate in a low power
(Discontinuous Conduction) mode during low loading conditions.
- cirrus,weak-fet-disable : Boolean : The strength of the output drivers is
reduced when operating in a Weak-FET Drive Mode and must not be used to drive
a large load.
- cirrus,classh-wk-fet-delay : Weak-FET entry delay. Controls the delay
(in ms) before the Class H algorithm switches to the weak-FET voltage
(after the audio falls and remains below the value specified in WKFET_AMP_THLD).
0 = 0ms
1 = 5ms
2 = 10ms
3 = 50ms
4 = 100ms (Default)
5 = 200ms
6 = 500ms
7 = 1000ms
- cirrus,classh-weak-fet-thld-millivolt : Weak-FET amplifier drive threshold.
Configures the signal threshold at which the PWM output stage enters
weak-FET operation. The range is 50mV to 700mV in 50mV increments.
- cirrus,temp-warn-threshold : Amplifier overtemperature warning threshold.
Configures the threshold at which the overtemperature warning condition occurs.
When the threshold is met, the overtemperature warning attenuation is applied
and the TEMP_WARN_EINT interrupt status bit is set.
If TEMP_WARN_MASK = 0, INTb is asserted.
0 = 105C
1 = 115C
2 = 125C (Default)
3 = 135C
- cirrus,irq-drive-select : Selects the driver type of the selected interrupt
output.
0 = Open-drain
1 = Push-pull (Default)
- cirrus,irq-gpio-select : Selects the pin to serve as the programmable
interrupt output.
0 = PDM_DATA / SWIRE_SD / INT (Default)
1 = GPIO
Optional properties for the "cirrus,vpbr-config" Sub-node
- cirrus,vpbr-en : VBST brownout prevention enable. Configures whether the
VBST brownout prevention algorithm is enabled or disabled.
0 = VBST brownout prevention disabled (default)
1 = VBST brownout prevention enabled
See Section 7.31.1 VPBR Config for configuration options & further details
- cirrus,vpbr-thld : Initial VPBR threshold. Configures the VP brownout
threshold voltage
- cirrus,cirrus,vpbr-atk-rate : Attenuation attack step rate. Configures the
amount delay between consecutive volume attenuation steps when a brownout
condition is present and the VP brownout condition is in an attacking state.
- cirrus,vpbr-atk-vol : VP brownout prevention step size. Configures the VP
brownout prevention attacking attenuation step size when operating in either
digital volume or analog gain modes.
- cirrus,vpbr-max-attn : Maximum attenuation that the VP brownout prevention
can apply to the audio signal.
- cirrus,vpbr-wait : Configures the delay time between a brownout condition
no longer being present and the VP brownout prevention entering an attenuation
release state.
- cirrus,vpbr-rel-rate : Attenuation release step rate. Configures the delay
between consecutive volume attenuation release steps when a brownout condition
is not longer present and the VP brownout is in an attenuation release state.
- cirrus,vpbr-mute-en : During the attack state, if the vpbr-max-attn value
is reached, the error condition still remains, and this bit is set, the audio
is muted.
Example:
cs35l36: cs35l36@40 {
compatible = "cirrus,cs35l36";
reg = <0x40>;
VA-supply = <&dummy_vreg>;
VP-supply = <&dummy_vreg>;
reset-gpios = <&gpio0 54 0>;
interrupt-parent = <&gpio8>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
cirrus,boost-ind-nanohenry = <1000>;
cirrus,boost-ctl-millivolt = <10000>;
cirrus,boost-peak-milliamp = <4500>;
cirrus,boost-ctl-select = <0x00>;
cirrus,weak-fet-delay = <0x04>;
cirrus,weak-fet-thld = <0x01>;
cirrus,temp-warn-threshold = <0x01>;
cirrus,multi-amp-mode;
cirrus,irq-drive-select = <0x01>;
cirrus,irq-gpio-select = <0x01>;
cirrus,vpbr-config {
cirrus,vpbr-en = <0x00>;
cirrus,vpbr-thld = <0x05>;
cirrus,vpbr-atk-rate = <0x02>;
cirrus,vpbr-atk-vol = <0x01>;
cirrus,vpbr-max-attn = <0x09>;
cirrus,vpbr-wait = <0x01>;
cirrus,vpbr-rel-rate = <0x05>;
cirrus,vpbr-mute-en = <0x00>;
};
};

View File

@ -39,6 +39,10 @@ properties:
wakeup-delay-ms:
description: Delay (in ms) after enabling the DMIC
port:
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
required:
- compatible

View File

@ -0,0 +1,61 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/eukrea,asoc-tlv320.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Audio complex for Eukrea boards with tlv320aic23 codec.
maintainers:
- Frank Li <Frank.Li@nxp.com>
properties:
compatible:
const: eukrea,asoc-tlv320
eukrea,model:
$ref: /schemas/types.yaml#/definitions/string
description:
The user-visible name of this sound complex.
ssi-controller:
$ref: /schemas/types.yaml#/definitions/phandle
description:
The phandle of the SSI controller.
fsl,mux-int-port:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
The internal port of the i.MX audio muxer (AUDMUX).
Note: The AUDMUX port numbering should start at 1, which is consistent with
hardware manual.
minimum: 1
maximum: 8
fsl,mux-ext-port:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
The external port of the i.MX audio muxer.
Note: The AUDMUX port numbering should start at 1, which is consistent with
hardware manual.
minimum: 1
maximum: 8
required:
- compatible
- eukrea,model
- ssi-controller
- fsl,mux-int-port
- fsl,mux-ext-port
additionalProperties: false
examples:
- |
sound {
compatible = "eukrea,asoc-tlv320";
eukrea,model = "imx51-eukrea-tlv320aic23";
ssi-controller = <&ssi2>;
fsl,mux-int-port = <2>;
fsl,mux-ext-port = <3>;
};

View File

@ -1,26 +0,0 @@
Audio complex for Eukrea boards with tlv320aic23 codec.
Required properties:
- compatible : "eukrea,asoc-tlv320"
- eukrea,model : The user-visible name of this sound complex.
- ssi-controller : The phandle of the SSI controller.
- fsl,mux-int-port : The internal port of the i.MX audio muxer (AUDMUX).
- fsl,mux-ext-port : The external port of the i.MX audio muxer.
Note: The AUDMUX port numbering should start at 1, which is consistent with
hardware manual.
Example:
sound {
compatible = "eukrea,asoc-tlv320";
eukrea,model = "imx51-eukrea-tlv320aic23";
ssi-controller = <&ssi2>;
fsl,mux-int-port = <2>;
fsl,mux-ext-port = <3>;
};

View File

@ -30,6 +30,18 @@ description: |
allOf:
- $ref: dai-common.yaml#
- if:
properties:
compatible:
not:
contains:
const: everest,es8316
then:
properties:
avdd-supply: false
cpvdd-supply: false
dvdd-supply: false
pvdd-supply: false
properties:
compatible:
@ -49,6 +61,18 @@ properties:
items:
- const: mclk
avdd-supply:
description: Regulator providing the analog supply, from 2.0 V to 3.6 V
cpvdd-supply:
description: Regulator providing the charge pump supply, from 1.6 V to 2.0 V
dvdd-supply:
description: Regulator providing the digital core supply, from 1.6 V to 3.6 V
pvdd-supply:
description: Regulator providing the digital I/O supply, from 1.6 V to 3.6 V
interrupts:
maxItems: 1
description: Headphone detect interrupt
@ -77,6 +101,10 @@ examples:
reg = <0x11>;
clocks = <&clks 10>;
clock-names = "mclk";
avdd-supply = <&reg_3p3v>;
cpvdd-supply = <&reg_1p8v>;
dvdd-supply = <&reg_1p8v>;
pvdd-supply = <&reg_1p8v>;
#sound-dai-cells = <0>;
};
};

View File

@ -66,6 +66,10 @@ properties:
"#sound-dai-cells":
const: 0
port:
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
required:
- compatible
- reg

View File

@ -8,19 +8,22 @@ title: Loongson 7axxx/2kxxx ASoC audio sound card driver
maintainers:
- Yingkun Meng <mengyingkun@loongson.cn>
- Binbin Zhou <zhoubinbin@loongson.cn>
description:
The binding describes the sound card present in loongson
7axxx/2kxxx platform. The sound card is an ASoC component
which uses Loongson I2S controller to transfer the audio data.
allOf:
- $ref: sound-card-common.yaml#
properties:
compatible:
const: loongson,ls-audio-card
model:
$ref: /schemas/types.yaml#/definitions/string
description: User specified audio sound card name
enum:
- loongson,ls-audio-card # Loongson-2K1000/Loongson-2K2000/LS7A
- loongson,ls2k0300-forever-pi-audio-card # CTCISZ Forever Pi
- loongson,ls2k0300-dl2k0300b-audio-card # ATK-DL2K0300B
mclk-fs:
$ref: simple-card.yaml#/definitions/mclk-fs
@ -45,14 +48,25 @@ properties:
required:
- sound-dai
spkr-en-gpios:
maxItems: 1
description: The GPIO that enables the speakers
hp-ctl-gpios:
maxItems: 1
description: The GPIO that control the headphones
hp-det-gpios:
maxItems: 1
description: The GPIO that detect headphones are plugged in
required:
- compatible
- model
- mclk-fs
- cpu
- codec
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@ -68,3 +82,28 @@ examples:
sound-dai = <&es8323>;
};
};
- |
#include <dt-bindings/gpio/gpio.h>
sound {
compatible = "loongson,ls2k0300-dl2k0300b-audio-card";
model = "loongson-audio";
mclk-fs = <512>;
hp-det-gpios = <&gpio 81 GPIO_ACTIVE_HIGH>;
spkr-en-gpios = <&gpio 86 GPIO_ACTIVE_HIGH>;
hp-ctl-gpios = <&gpio 87 GPIO_ACTIVE_HIGH>;
audio-routing =
"Headphone", "LOUT1",
"Headphone", "ROUT1",
"Speaker", "LOUT2",
"Speaker", "ROUT2";
cpu {
sound-dai = <&i2s>;
};
codec {
sound-dai = <&es8388>;
};
};

View File

@ -14,9 +14,12 @@ allOf:
properties:
compatible:
const: loongson,ls2k1000-i2s
enum:
- loongson,ls2k0300-i2s
- loongson,ls2k1000-i2s
reg:
minItems: 1
items:
- description: Loongson I2S controller Registers.
- description: APB DMA config register for Loongson I2S controller.
@ -49,6 +52,23 @@ required:
unevaluatedProperties: false
if:
properties:
compatible:
contains:
enum:
- loongson,ls2k1000-i2s
then:
properties:
reg:
minItems: 2
else:
properties:
reg:
maxItems: 1
examples:
- |
#include <dt-bindings/clock/loongson,ls2k-clk.h>

View File

@ -0,0 +1,59 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/mediatek,mtk-btcvsd-snd.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek ALSA BT SCO CVSD/MSBC
maintainers:
- Luca Leonardo Scorcia <l.scorcia@gmail.com>
properties:
compatible:
const: mediatek,mtk-btcvsd-snd
reg:
items:
- description: PKV region
- description: SRAM_BANK2 region
interrupts:
items:
- description: BT-SCO interrupt
mediatek,infracfg:
$ref: /schemas/types.yaml#/definitions/phandle
description: The phandle of the infracfg controller
mediatek,offset:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: Array of register offsets and masks
items:
- description: infra_misc_offset
- description: infra_conn_bt_cvsd_mask
- description: cvsd_mcu_read_offset
- description: cvsd_mcu_write_offset
- description: cvsd_packet_indicator_offset
required:
- compatible
- reg
- interrupts
- mediatek,infracfg
- mediatek,offset
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
mtk-btcvsd-snd@18000000 {
compatible = "mediatek,mtk-btcvsd-snd";
reg = <0x18000000 0x1000>,
<0x18080000 0x8000>;
interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_LOW>;
mediatek,infracfg = <&infrasys>;
mediatek,offset = <0xf00 0x800 0xfd0 0xfd4 0xfd8>;
};

View File

@ -1,24 +0,0 @@
Mediatek ALSA BT SCO CVSD/MSBC Driver
Required properties:
- compatible = "mediatek,mtk-btcvsd-snd";
- reg: register location and size of PKV and SRAM_BANK2
- interrupts: should contain BTSCO interrupt
- mediatek,infracfg: the phandles of INFRASYS
- mediatek,offset: Array contains of register offset and mask
infra_misc_offset,
infra_conn_bt_cvsd_mask,
cvsd_mcu_read_offset,
cvsd_mcu_write_offset,
cvsd_packet_indicator_offset
Example:
mtk-btcvsd-snd@18000000 {
compatible = "mediatek,mtk-btcvsd-snd";
reg=<0 0x18000000 0 0x1000>,
<0 0x18080000 0 0x8000>;
interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_LOW>;
mediatek,infracfg = <&infrasys>;
mediatek,offset = <0xf00 0x800 0xfd0 0xfd4 0xfd8>;
};

View File

@ -66,7 +66,7 @@ examples:
#sound-dai-cells = <0>;
reg = <0x2a>;
clocks = <&clkc 150>, <&clkc 151>, <&clkc 152>;
clock-names = "wck", "scl", "bck";
clock-names = "wck", "scl", "bck";
reset-gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
};
};

View File

@ -1,20 +0,0 @@
* Texas Instruments OMAP4+ Digital Microphone Module
Required properties:
- compatible: "ti,omap4-dmic"
- reg: Register location and size as an array:
<MPU access base address, size>,
<L3 interconnect address, size>;
- interrupts: Interrupt number for DMIC
- ti,hwmods: Name of the hwmod associated with OMAP dmic IP
Example:
dmic: dmic@4012e000 {
compatible = "ti,omap4-dmic";
reg = <0x4012e000 0x7f>, /* MPU private access */
<0x4902e000 0x7f>; /* L3 Interconnect */
interrupts = <0 114 0x4>;
interrupt-parent = <&gic>;
ti,hwmods = "dmic";
};

View File

@ -14,7 +14,13 @@ description:
properties:
compatible:
const: qcom,msm8916-wcd-digital-codec
oneOf:
- items:
- enum:
- qcom,sdm660-wcd-digital-codec
- const: qcom,msm8916-wcd-digital-codec
- const: qcom,msm8916-wcd-digital-codec
reg:
maxItems: 1

View File

@ -14,7 +14,16 @@ description:
properties:
compatible:
const: qcom,pm8916-wcd-analog-codec
oneOf:
- items:
- enum:
- qcom,pm660l-wcd-analog-codec
- const: qcom,pm8953-wcd-analog-codec
- enum:
- qcom,pm8916-wcd-analog-codec
- qcom,pm8950-wcd-analog-codec
- qcom,pm8953-wcd-analog-codec
reg:
maxItems: 1

View File

@ -21,6 +21,43 @@ properties:
'#sound-dai-cells':
const: 1
'#address-cells':
const: 1
'#size-cells':
const: 0
# Digital Audio Interfaces
patternProperties:
'^dai@[0-9a-f]+$':
type: object
description:
Q6DSP Digital Audio Interfaces.
properties:
reg:
maxItems: 1
description:
Digital Audio Interface ID
clocks:
minItems: 1
maxItems: 2
clock-names:
minItems: 1
items:
- enum: [bclk, mclk]
- const: mclk
dependencies:
clocks: [clock-names]
required:
- reg
additionalProperties: false
required:
- compatible
- '#sound-dai-cells'
@ -29,7 +66,20 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/sound/qcom,q6afe.h>
dais {
compatible = "qcom,q6apm-lpass-dais";
#sound-dai-cells = <1>;
#address-cells = <1>;
#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";
};
};

View File

@ -127,7 +127,7 @@ patternProperties:
contains:
# MI2S DAI ID range PRIMARY_MI2S_RX - QUATERNARY_MI2S_TX and
# QUINARY_MI2S_RX - QUINARY_MI2S_TX and
# LPI_MI2S_RX_0 - SENARY_MI2S_TX
# LPI_MI2S_RX_0 - LPI_MI2S_TX_6
items:
oneOf:
- minimum: 16
@ -135,7 +135,7 @@ patternProperties:
- minimum: 127
maximum: 128
- minimum: 137
maximum: 148
maximum: 152
then:
required:
- qcom,sd-lines

View File

@ -24,12 +24,16 @@ properties:
- items:
- enum:
- qcom,eliza-sndcard
- qcom,hawi-sndcard
- qcom,kaanapali-sndcard
- qcom,maili-sndcard
- qcom,sm8475-sndcard
- qcom,sm8550-sndcard
- qcom,sm8650-sndcard
- qcom,sm8750-sndcard
- const: qcom,sm8450-sndcard
- enum:
- ayaneo,pocket-s2-sndcard
- fairphone,fp4-sndcard
- fairphone,fp5-sndcard
- qcom,apq8096-sndcard
@ -45,6 +49,7 @@ properties:
- qcom,qrb5165-rb5-sndcard
- qcom,sc7180-qdsp6-sndcard
- qcom,sc8280xp-sndcard
- qcom,sdm660-sndcard
- qcom,sdm845-sndcard
- qcom,sm8250-sndcard
- qcom,sm8450-sndcard
@ -91,6 +96,19 @@ patternProperties:
sound-dai:
maxItems: 1
dai-tdm-slot-num:
$ref: /schemas/types.yaml#/definitions/uint32
description: Number of slots in use
dai-tdm-slot-width:
$ref: /schemas/types.yaml#/definitions/uint32
description: Width, in bits, of each slot
patternProperties:
'^dai-tdm-slot-[rt]x-mask$':
$ref: /schemas/types.yaml#/definitions/uint32-array
description: Slot mask for active TDM slots
platform:
description: Holds subnode which indicates platform dai.
type: object
@ -110,6 +128,19 @@ patternProperties:
minItems: 1
maxItems: 8
dai-tdm-slot-num:
$ref: /schemas/types.yaml#/definitions/uint32
description: Number of slots in use
dai-tdm-slot-width:
$ref: /schemas/types.yaml#/definitions/uint32
description: Width, in bits, of each slot
patternProperties:
'^dai-tdm-slot-[rt]x-mask$':
$ref: /schemas/types.yaml#/definitions/uint32-array
description: Slot mask for active TDM slots
required:
- link-name
- cpu

View File

@ -0,0 +1,93 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/qcom,wsa8855.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm WSA8855 stereo smart speaker amplifier
maintainers:
- Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
- Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
description:
WSA885X is a Qualcomm Aqstic stereo smart speaker amplifier. It uses a PCM
audio interface, an I2C control interface, and a Class-H amplifier path for
high efficiency, low output noise, and low idle power consumption.
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
const: qcom,wsa8855
reg:
maxItems: 1
'#sound-dai-cells':
const: 0
powerdown-gpios:
description: GPIO controlling the SD_N powerdown pin.
maxItems: 1
reset-gpios:
description: GPIO controlling the SD_N powerdown pin.
maxItems: 1
interrupts:
maxItems: 1
vdd-1p8-supply: true
vdd-io-supply: true
qcom,battery-config:
description:
Battery topology connected to the speaker amplifier. 1S indicates one
battery cell in series, while 2S indicates two battery cells in series.
$ref: /schemas/types.yaml#/definitions/string
default: 1s
enum:
- 1s
- 2s
required:
- compatible
- reg
- '#sound-dai-cells'
- interrupts
- vdd-1p8-supply
- vdd-io-supply
oneOf:
- required:
- powerdown-gpios
- required:
- reset-gpios
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
speaker@c {
compatible = "qcom,wsa8855";
reg = <0x0c>;
#sound-dai-cells = <0>;
powerdown-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>;
interrupt-parent = <&tlmm>;
interrupts = <77 IRQ_TYPE_EDGE_FALLING>;
vdd-1p8-supply = <&vreg_l2g_1p8>;
vdd-io-supply = <&vreg_l1g_1p2>;
qcom,battery-config = "1s";
};
};
...

View File

@ -19,7 +19,7 @@ properties:
realtek,power-up-delay-ms:
description: Set a delay time for flush work to be completed,
this vlaue is adjustable depending on platform.
this value is adjustable depending on platform.
maxItems: 1
required:

View File

@ -793,7 +793,7 @@ examples:
bitclock-master = <&rsnd_endpoint0>;
frame-master = <&rsnd_endpoint0>;
playback = <&ssi3>, <&src1>, <&dvc1>;
capture = <&ssi4>, <&src0>, <&dvc0>;
capture = <&ssi4>, <&src0>, <&dvc0>;
};
};
};

View File

@ -23,9 +23,9 @@ allOf:
then:
properties:
clocks:
minItems: 7
minItems: 6
clock-names:
minItems: 7
minItems: 6
else:
properties:
clocks:
@ -43,26 +43,50 @@ properties:
maxItems: 1
clocks:
minItems: 4
items:
- description: clock for I2S sysclk
- description: clock for I2S bclk
- description: clock for I2S bus
- description: clock for I2S controller
- description: clock for I2S sysclk divider
- description: clock for I2S common sysclk
- description: clock for I2S common bclk
oneOf:
- items:
- description: clock for I2S sysclk
- description: clock for I2S bclk
- description: clock for I2S bus
- description: clock for I2S controller
- items:
- description: clock for I2S sysclk
- description: clock for I2S bclk
- description: clock for I2S bus
- description: clock for I2S controller
- description: clock for I2S common sysclk
- description: clock for I2S common bclk
- items:
- description: clock for I2S sysclk
- description: clock for I2S bclk
- description: clock for I2S bus
- description: clock for I2S controller
- description: clock for I2S sysclk divider
- description: clock for I2S common sysclk
- description: clock for I2S common bclk
clock-names:
minItems: 4
items:
- const: sysclk
- const: bclk
- const: bus
- const: func
- const: sysclk_div
- const: c_sysclk
- const: c_bclk
oneOf:
- items:
- const: sysclk
- const: bclk
- const: bus
- const: func
- items:
- const: sysclk
- const: bclk
- const: bus
- const: func
- const: c_sysclk
- const: c_bclk
- items:
- const: sysclk
- const: bclk
- const: bus
- const: func
- const: sysclk_div
- const: c_sysclk
- const: c_bclk
dmas:
minItems: 1

View File

@ -73,7 +73,7 @@ Optional properties:
- st,odd-pwm-speed-mode:
If present, PWM speed mode run on odd speed mode (341.3 kHz) on all
channels. If not present, normal PWM spped mode (384 kHz) will be used.
channels. If not present, normal PWM speed mode (384 kHz) will be used.
- st,invalid-input-detect-mute:
If present, automatic invalid input detect mute is enabled.

View File

@ -0,0 +1,58 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/ti,omap4-dmic.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments OMAP4+ Digital Microphone Module
maintainers:
- Peter Ujfalusi <peter.ujfalusi@ti.com>
properties:
compatible:
const: ti,omap4-dmic
reg:
items:
- description: MPU access base address
- description: L3 interconnect address
reg-names:
items:
- const: mpu
- const: dma
interrupts:
maxItems: 1
dmas:
maxItems: 1
dma-names:
items:
- const: up_link
required:
- compatible
- reg
- reg-names
- interrupts
- dmas
- dma-names
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
dmic@0 {
compatible = "ti,omap4-dmic";
reg = <0x0 0x7f>, /* MPU private access */
<0x4902e000 0x7f>; /* L3 Interconnect */
reg-names = "mpu", "dma";
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&sdma 67>;
dma-names = "up_link";
};

View File

@ -24,6 +24,10 @@ properties:
description:
a GPIO spec for the MUTE pin.
port:
$ref: audio-graph-port.yaml#
unevaluatedProperties: false
required:
- compatible
- wlf,mute-gpios

View File

@ -2401,6 +2401,11 @@ quirk_flags
disabling GET_CUR instead of the whole mixer. The current volume will
then be provided by the internal cache that stores the last set
volume
* bit 31: ``playback_urb_fixup``
Some devices show the stuttering at playback, and this quirk
works around it by enforcing the fixed max URBs (12) instead of
the dynamic calculation from the buffer size, and passing the
`URB_ISO_ASAP` URB flag.
This module supports multiple devices, autoprobe and hotplugging.

View File

@ -42,7 +42,7 @@ If you are interested in the deep debugging of HD-audio, read the
HD-audio specification at first. The specification is found on
Intel's web page, for example:
* https://www.intel.com/content/www/us/en/standards/high-definition-audio-specification.html
* https://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/high-definition-audio-specification.pdf
HD-Audio Controller

View File

@ -1749,6 +1749,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
* by the drivers/platform/x86/serial-multi-instantiate.c driver, which
* knows which client device id to use for each resource.
*/
{"AWDZ8399", },
{"BSG1160", },
{"BSG2150", },
{"CSC3551", },

View File

@ -147,7 +147,7 @@ static const struct reg_default halo_register_defaults[] = {
{ 0x2b805c0, 0 }, /* HALO_SCRATCH1 */
{ 0x2b805c8, 0 }, /* HALO_SCRATCH2 */
{ 0x2b805d0, 0 }, /* HALO_SCRATCH3 */
{ 0x2b805c8, 0 }, /* HALO_SCRATCH4 */
{ 0x2b805d8, 0 }, /* HALO_SCRATCH4 */
{ 0x2bc1000, 0 }, /* HALO_CCM_CORE_CONTROL */
{ 0x2bc7000, 0 }, /* HALO_WDT_CONTROL */

View File

@ -307,6 +307,15 @@ static void smi_remove(struct platform_device *pdev)
smi_devs_unregister(smi);
}
static const struct smi_node aw88399_hda = {
.instances = {
{ "aw88399-hda", IRQ_RESOURCE_AUTO, 0 },
{ "aw88399-hda", IRQ_RESOURCE_AUTO, 0 },
{}
},
.bus_type = SMI_AUTO_DETECT,
};
static const struct smi_node bsg1160_data = {
.instances = {
{ "bmc150_accel", IRQ_RESOURCE_GPIO, 0 },
@ -405,6 +414,7 @@ static const struct smi_node tas2781_hda = {
* drivers/acpi/scan.c: acpi_device_enumeration_by_parent().
*/
static const struct acpi_device_id smi_acpi_ids[] = {
{ "AWDZ8399", (unsigned long)&aw88399_hda },
{ "BSG1160", (unsigned long)&bsg1160_data },
{ "BSG2150", (unsigned long)&bsg2150_data },
{ "CSC3551", (unsigned long)&cs35l41_hda },

View File

@ -105,6 +105,9 @@ static int sdw_bus_probe(struct device *dev)
}
slave->index = ret;
/* Create IRQ mapping now so the driver can get it in probe() */
sdw_irq_create_mapping(slave);
ret = drv->probe(slave, id);
if (ret) {
ida_free(&slave->bus->slave_ida, slave->index);
@ -117,9 +120,6 @@ static int sdw_bus_probe(struct device *dev)
if (drv->ops && drv->ops->read_prop)
drv->ops->read_prop(slave);
if (slave->prop.use_domain_irq)
sdw_irq_create_mapping(slave);
/* init the dynamic sysfs attributes we need */
ret = sdw_slave_sysfs_dpn_init(slave);
if (ret < 0)

View File

@ -152,6 +152,10 @@
#define LPI_MI2S_TX_4 146
#define SENARY_MI2S_RX 147
#define SENARY_MI2S_TX 148
#define LPI_MI2S_RX_5 149
#define LPI_MI2S_TX_5 150
#define LPI_MI2S_RX_6 151
#define LPI_MI2S_TX_6 152
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2
@ -233,11 +237,39 @@
/* Clock ID for RX CORE MCLK2 2X MCLK */
#define LPASS_CLK_ID_RX_CORE_MCLK2_2X_MCLK 70
#define LAPSS_CLK_ID_QAIF_IF0_IBIT 71
#define LAPSS_CLK_ID_QAIF_IF0_EBIT 72
#define LAPSS_CLK_ID_QAIF_IF1_IBIT 73
#define LAPSS_CLK_ID_QAIF_IF1_EBIT 74
#define LAPSS_CLK_ID_QAIF_IF2_IBIT 75
#define LAPSS_CLK_ID_QAIF_IF2_EBIT 76
#define LAPSS_CLK_ID_QAIF_IF3_IBIT 77
#define LAPSS_CLK_ID_QAIF_IF3_EBIT 78
#define LAPSS_CLK_ID_QAIF_IF4_IBIT 79
#define LAPSS_CLK_ID_QAIF_IF4_EBIT 80
#define LAPSS_CLK_ID_QAIF_IF5_IBIT 81
#define LAPSS_CLK_ID_QAIF_IF5_EBIT 82
#define LAPSS_CLK_ID_QAIF_IF6_IBIT 83
#define LAPSS_CLK_ID_QAIF_IF6_EBIT 84
#define LAPSS_CLK_ID_QAIF_IF7_IBIT 85
#define LAPSS_CLK_ID_QAIF_IF7_EBIT 86
#define LAPSS_CLK_ID_QAIF_IF8_IBIT 87
#define LAPSS_CLK_ID_QAIF_IF8_EBIT 88
#define LAPSS_CLK_ID_QAIF_IF9_IBIT 89
#define LAPSS_CLK_ID_QAIF_IF9_EBIT 90
#define LAPSS_CLK_ID_QAIF_IF10_IBIT 91
#define LAPSS_CLK_ID_QAIF_IF10_EBIT 92
#define LAPSS_CLK_ID_QAIF_IF11_IBIT 93
#define LAPSS_CLK_ID_QAIF_IF11_EBIT 94
#define LAPSS_CLK_ID_QAIF_IF12_IBIT 95
#define LAPSS_CLK_ID_QAIF_IF12_EBIT 96
#define LAPSS_CLK_ID_VA_QAIF_IF0_IBIT 97
#define LAPSS_CLK_ID_VA_QAIF_IF0_EBIT 98
#define LPASS_HW_AVTIMER_VOTE 101
#define LPASS_HW_MACRO_VOTE 102
#define LPASS_HW_DCODEC_VOTE 103
#define Q6AFE_MAX_CLK_ID 104
#define LPASS_HW_LPR_VOTE 104
#define LPASS_CLK_ATTRIBUTE_INVALID 0x0
#define LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1

View File

@ -1,42 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/**
* omap-twl4030.h - ASoC machine driver for TI SoC based boards with twl4030
* codec, header.
*
* Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com
* All rights reserved.
*
* Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
*/
#ifndef _OMAP_TWL4030_H_
#define _OMAP_TWL4030_H_
/* To select if only one channel is connected in a stereo port */
#define OMAP_TWL4030_LEFT (1 << 0)
#define OMAP_TWL4030_RIGHT (1 << 1)
struct omap_tw4030_pdata {
const char *card_name;
/* Voice port is connected to McBSP3 */
bool voice_connected;
/* The driver will parse the connection flags if this flag is set */
bool custom_routing;
/* Flags to indicate connected audio ports. */
u8 has_hs;
u8 has_hf;
u8 has_predriv;
u8 has_carkit;
bool has_ear;
bool has_mainmic;
bool has_submic;
bool has_hsmic;
bool has_carkitmic;
bool has_digimic0;
bool has_digimic1;
u8 has_linein;
};
#endif /* _OMAP_TWL4030_H_ */

View File

@ -33,7 +33,7 @@ struct ac97_id {
};
/**
* ac97_codec_device - a ac97 codec
* struct ac97_codec_device - a ac97 codec
* @dev: the core device
* @vendor_id: the vendor_id of the codec, as sensed on the AC-link
* @num: the codec number, 0 is primary, 1 is first slave, etc ...
@ -53,7 +53,7 @@ struct ac97_codec_device {
};
/**
* ac97_codec_driver - a ac97 codec driver
* struct ac97_codec_driver - a ac97 codec driver
* @driver: the device driver structure
* @probe: the function called when a ac97_codec_device is matched
* @remove: the function called when the device is unbound/removed

View File

@ -11,9 +11,6 @@
#include <sound/asound.h>
#include <uapi/sound/asequencer.h>
/* helper macro */
#define snd_seq_event_bounce_ext_data(ev) ((void*)((char *)(ev)->data.ext.ptr + sizeof(struct snd_seq_event_bounce)))
/*
* type check macros
*/

621
include/sound/aw88399.h Normal file
View File

@ -0,0 +1,621 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* linux/sound/aw88399.h -- Platform data for AW88399
*
* Copyright (c) 2023 AWINIC Technology CO., LTD
*
* Author: Weidong Wang <wangweidong.a@awinic.com>
*/
#ifndef __SOUND_AW88399_H
#define __SOUND_AW88399_H
#include <linux/mutex.h>
#include <linux/workqueue.h>
/* registers list */
#define AW88399_ID_REG (0x00)
#define AW88399_SYSST_REG (0x01)
#define AW88399_SYSINT_REG (0x02)
#define AW88399_SYSINTM_REG (0x03)
#define AW88399_SYSCTRL_REG (0x04)
#define AW88399_SYSCTRL2_REG (0x05)
#define AW88399_I2SCTRL1_REG (0x06)
#define AW88399_I2SCTRL2_REG (0x07)
#define AW88399_I2SCTRL3_REG (0x08)
#define AW88399_DACCFG1_REG (0x09)
#define AW88399_DACCFG2_REG (0x0A)
#define AW88399_DACCFG3_REG (0x0B)
#define AW88399_DACCFG4_REG (0x0C)
#define AW88399_DACCFG5_REG (0x0D)
#define AW88399_DACCFG6_REG (0x0E)
#define AW88399_DACCFG7_REG (0x0F)
#define AW88399_MPDCFG1_REG (0x10)
#define AW88399_MPDCFG2_REG (0x11)
#define AW88399_MPDCFG3_REG (0x12)
#define AW88399_MPDCFG4_REG (0x13)
#define AW88399_PWMCTRL1_REG (0x14)
#define AW88399_PWMCTRL2_REG (0x15)
#define AW88399_PWMCTRL3_REG (0x16)
#define AW88399_I2SCFG1_REG (0x17)
#define AW88399_DBGCTRL_REG (0x18)
#define AW88399_HAGCST_REG (0x20)
#define AW88399_VBAT_REG (0x21)
#define AW88399_TEMP_REG (0x22)
#define AW88399_PVDD_REG (0x23)
#define AW88399_ISNDAT_REG (0x24)
#define AW88399_VSNDAT_REG (0x25)
#define AW88399_I2SINT_REG (0x26)
#define AW88399_I2SCAPCNT_REG (0x27)
#define AW88399_ANASTA1_REG (0x28)
#define AW88399_ANASTA2_REG (0x29)
#define AW88399_ANASTA3_REG (0x2A)
#define AW88399_TESTDET_REG (0x2B)
#define AW88399_DSMCFG1_REG (0x30)
#define AW88399_DSMCFG2_REG (0x31)
#define AW88399_DSMCFG3_REG (0x32)
#define AW88399_DSMCFG4_REG (0x33)
#define AW88399_DSMCFG5_REG (0x34)
#define AW88399_DSMCFG6_REG (0x35)
#define AW88399_DSMCFG7_REG (0x36)
#define AW88399_DSMCFG8_REG (0x37)
#define AW88399_TESTIN_REG (0x38)
#define AW88399_TESTOUT_REG (0x39)
#define AW88399_MEMTEST_REG (0x3A)
#define AW88399_VSNCTRL1_REG (0x3B)
#define AW88399_ISNCTRL1_REG (0x3C)
#define AW88399_ISNCTRL2_REG (0x3D)
#define AW88399_DSPMADD_REG (0x40)
#define AW88399_DSPMDAT_REG (0x41)
#define AW88399_WDT_REG (0x42)
#define AW88399_ACR1_REG (0x43)
#define AW88399_ACR2_REG (0x44)
#define AW88399_ASR1_REG (0x45)
#define AW88399_ASR2_REG (0x46)
#define AW88399_DSPCFG_REG (0x47)
#define AW88399_ASR3_REG (0x48)
#define AW88399_ASR4_REG (0x49)
#define AW88399_DSPVCALB_REG (0x4A)
#define AW88399_CRCCTRL_REG (0x4B)
#define AW88399_DSPDBG1_REG (0x4C)
#define AW88399_DSPDBG2_REG (0x4D)
#define AW88399_DSPDBG3_REG (0x4E)
#define AW88399_PLLCTRL1_REG (0x50)
#define AW88399_PLLCTRL2_REG (0x51)
#define AW88399_PLLCTRL3_REG (0x52)
#define AW88399_CDACTRL1_REG (0x53)
#define AW88399_CDACTRL2_REG (0x54)
#define AW88399_CDACTRL3_REG (0x55)
#define AW88399_SADCCTRL1_REG (0x56)
#define AW88399_SADCCTRL2_REG (0x57)
#define AW88399_BOPCTRL1_REG (0x58)
#define AW88399_BOPCTRL2_REG (0x5A)
#define AW88399_BOPCTRL3_REG (0x5B)
#define AW88399_BOPCTRL4_REG (0x5C)
#define AW88399_BOPCTRL5_REG (0x5D)
#define AW88399_BOPCTRL6_REG (0x5E)
#define AW88399_BOPCTRL7_REG (0x5F)
#define AW88399_BSTCTRL1_REG (0x60)
#define AW88399_BSTCTRL2_REG (0x61)
#define AW88399_BSTCTRL3_REG (0x62)
#define AW88399_BSTCTRL4_REG (0x63)
#define AW88399_BSTCTRL5_REG (0x64)
#define AW88399_BSTCTRL6_REG (0x65)
#define AW88399_BSTCTRL7_REG (0x66)
#define AW88399_BSTCTRL8_REG (0x67)
#define AW88399_BSTCTRL9_REG (0x68)
#define AW88399_BSTCTRL10_REG (0x69)
#define AW88399_CPCTRL_REG (0x6A)
#define AW88399_EFWH_REG (0x6C)
#define AW88399_EFWM2_REG (0x6D)
#define AW88399_EFWM1_REG (0x6E)
#define AW88399_EFWL_REG (0x6F)
#define AW88399_TESTCTRL1_REG (0x70)
#define AW88399_TESTCTRL2_REG (0x71)
#define AW88399_EFCTRL1_REG (0x72)
#define AW88399_EFCTRL2_REG (0x73)
#define AW88399_EFRH4_REG (0x74)
#define AW88399_EFRH3_REG (0x75)
#define AW88399_EFRH2_REG (0x76)
#define AW88399_EFRH1_REG (0x77)
#define AW88399_EFRL4_REG (0x78)
#define AW88399_EFRL3_REG (0x79)
#define AW88399_EFRL2_REG (0x7A)
#define AW88399_EFRL1_REG (0x7B)
#define AW88399_TM_REG (0x7C)
#define AW88399_TM2_REG (0x7D)
#define AW88399_REG_MAX (0x7E)
#define AW88399_MUTE_VOL (1023)
#define AW88399_DSP_CFG_ADDR (0x9B00)
#define AW88399_DSP_REG_CFG_ADPZ_RA (0x9B68)
#define AW88399_DSP_FW_ADDR (0x8980)
#define AW88399_DSP_ROM_CHECK_ADDR (0x1F40)
#define AW88399_DSP_ROM_CHECK_DATA (0x4638)
#define AW88399_CALI_RE_HBITS_MASK (~(0xFFFF0000))
#define AW88399_CALI_RE_HBITS_SHIFT (16)
#define AW88399_CALI_RE_LBITS_MASK (~(0xFFFF))
#define AW88399_CALI_RE_LBITS_SHIFT (0)
#define AW88399_I2STXEN_START_BIT (9)
#define AW88399_I2STXEN_BITS_LEN (1)
#define AW88399_I2STXEN_MASK \
(~(((1<<AW88399_I2STXEN_BITS_LEN)-1) << AW88399_I2STXEN_START_BIT))
#define AW88399_I2STXEN_DISABLE (0)
#define AW88399_I2STXEN_DISABLE_VALUE \
(AW88399_I2STXEN_DISABLE << AW88399_I2STXEN_START_BIT)
#define AW88399_I2STXEN_ENABLE (1)
#define AW88399_I2STXEN_ENABLE_VALUE \
(AW88399_I2STXEN_ENABLE << AW88399_I2STXEN_START_BIT)
#define AW88399_VOL_START_BIT (0)
#define AW88399_VOL_BITS_LEN (10)
#define AW88399_VOL_MASK \
(~(((1<<AW88399_VOL_BITS_LEN)-1) << AW88399_VOL_START_BIT))
#define AW88399_PWDN_START_BIT (0)
#define AW88399_PWDN_BITS_LEN (1)
#define AW88399_PWDN_MASK \
(~(((1<<AW88399_PWDN_BITS_LEN)-1) << AW88399_PWDN_START_BIT))
#define AW88399_PWDN_POWER_DOWN (1)
#define AW88399_PWDN_POWER_DOWN_VALUE \
(AW88399_PWDN_POWER_DOWN << AW88399_PWDN_START_BIT)
#define AW88399_PWDN_WORKING (0)
#define AW88399_PWDN_WORKING_VALUE \
(AW88399_PWDN_WORKING << AW88399_PWDN_START_BIT)
#define AW88399_DSPBY_START_BIT (2)
#define AW88399_DSPBY_BITS_LEN (1)
#define AW88399_DSPBY_MASK \
(~(((1<<AW88399_DSPBY_BITS_LEN)-1) << AW88399_DSPBY_START_BIT))
#define AW88399_DSPBY_WORKING (0)
#define AW88399_DSPBY_WORKING_VALUE \
(AW88399_DSPBY_WORKING << AW88399_DSPBY_START_BIT)
#define AW88399_DSPBY_BYPASS (1)
#define AW88399_DSPBY_BYPASS_VALUE \
(AW88399_DSPBY_BYPASS << AW88399_DSPBY_START_BIT)
#define AW88399_MEM_CLKSEL_START_BIT (3)
#define AW88399_MEM_CLKSEL_BITS_LEN (1)
#define AW88399_MEM_CLKSEL_MASK \
(~(((1<<AW88399_MEM_CLKSEL_BITS_LEN)-1) << AW88399_MEM_CLKSEL_START_BIT))
#define AW88399_MEM_CLKSEL_OSCCLK (0)
#define AW88399_MEM_CLKSEL_OSCCLK_VALUE \
(AW88399_MEM_CLKSEL_OSCCLK << AW88399_MEM_CLKSEL_START_BIT)
#define AW88399_MEM_CLKSEL_DAPHCLK (1)
#define AW88399_MEM_CLKSEL_DAPHCLK_VALUE \
(AW88399_MEM_CLKSEL_DAPHCLK << AW88399_MEM_CLKSEL_START_BIT)
#define AW88399_DITHER_EN_START_BIT (15)
#define AW88399_DITHER_EN_BITS_LEN (1)
#define AW88399_DITHER_EN_MASK \
(~(((1<<AW88399_DITHER_EN_BITS_LEN)-1) << AW88399_DITHER_EN_START_BIT))
#define AW88399_DITHER_EN_DISABLE (0)
#define AW88399_DITHER_EN_DISABLE_VALUE \
(AW88399_DITHER_EN_DISABLE << AW88399_DITHER_EN_START_BIT)
#define AW88399_DITHER_EN_ENABLE (1)
#define AW88399_DITHER_EN_ENABLE_VALUE \
(AW88399_DITHER_EN_ENABLE << AW88399_DITHER_EN_START_BIT)
#define AW88399_HMUTE_START_BIT (8)
#define AW88399_HMUTE_BITS_LEN (1)
#define AW88399_HMUTE_MASK \
(~(((1<<AW88399_HMUTE_BITS_LEN)-1) << AW88399_HMUTE_START_BIT))
#define AW88399_HMUTE_DISABLE (0)
#define AW88399_HMUTE_DISABLE_VALUE \
(AW88399_HMUTE_DISABLE << AW88399_HMUTE_START_BIT)
#define AW88399_HMUTE_ENABLE (1)
#define AW88399_HMUTE_ENABLE_VALUE \
(AW88399_HMUTE_ENABLE << AW88399_HMUTE_START_BIT)
#define AW88399_EF_DBMD_START_BIT (2)
#define AW88399_EF_DBMD_BITS_LEN (1)
#define AW88399_EF_DBMD_MASK \
(~(((1<<AW88399_EF_DBMD_BITS_LEN)-1) << AW88399_EF_DBMD_START_BIT))
#define AW88399_EF_DBMD_OR (1)
#define AW88399_EF_DBMD_OR_VALUE \
(AW88399_EF_DBMD_OR << AW88399_EF_DBMD_START_BIT)
#define AW88399_VDSEL_START_BIT (5)
#define AW88399_VDSEL_BITS_LEN (1)
#define AW88399_VDSEL_MASK \
(~(((1<<AW88399_VDSEL_BITS_LEN)-1) << AW88399_VDSEL_START_BIT))
#define AW88399_EF_ISN_GESLP_H_START_BIT (0)
#define AW88399_EF_ISN_GESLP_H_BITS_LEN (10)
#define AW88399_EF_ISN_GESLP_H_MASK \
(~(((1<<AW88399_EF_ISN_GESLP_H_BITS_LEN)-1) << AW88399_EF_ISN_GESLP_H_START_BIT))
/* EF_VSN_GESLP_H bit 9:0 (EFRH3 0x75) */
#define AW88399_EF_VSN_GESLP_H_START_BIT (0)
#define AW88399_EF_VSN_GESLP_H_BITS_LEN (10)
#define AW88399_EF_VSN_GESLP_H_MASK \
(~(((1<<AW88399_EF_VSN_GESLP_H_BITS_LEN)-1) << AW88399_EF_VSN_GESLP_H_START_BIT))
#define AW88399_EF_ISN_GESLP_L_START_BIT (0)
#define AW88399_EF_ISN_GESLP_L_BITS_LEN (10)
#define AW88399_EF_ISN_GESLP_L_MASK \
(~(((1<<AW88399_EF_ISN_GESLP_L_BITS_LEN)-1) << AW88399_EF_ISN_GESLP_L_START_BIT))
/* EF_VSN_GESLP_L bit 9:0 (EFRL3 0x79) */
#define AW88399_EF_VSN_GESLP_L_START_BIT (0)
#define AW88399_EF_VSN_GESLP_L_BITS_LEN (10)
#define AW88399_EF_VSN_GESLP_L_MASK \
(~(((1<<AW88399_EF_VSN_GESLP_L_BITS_LEN)-1) << AW88399_EF_VSN_GESLP_L_START_BIT))
#define AW88399_INTERNAL_VSN_TRIM_H_START_BIT (9)
#define AW88399_INTERNAL_VSN_TRIM_H_BITS_LEN (6)
#define AW88399_INTERNAL_VSN_TRIM_H_MASK \
(~(((1<<AW88399_INTERNAL_VSN_TRIM_H_BITS_LEN)-1) << AW88399_INTERNAL_VSN_TRIM_H_START_BIT))
#define AW88399_INTERNAL_VSN_TRIM_L_START_BIT (9)
#define AW88399_INTERNAL_VSN_TRIM_L_BITS_LEN (6)
#define AW88399_INTERNAL_VSN_TRIM_L_MASK \
(~(((1<<AW88399_INTERNAL_VSN_TRIM_L_BITS_LEN)-1) << AW88399_INTERNAL_VSN_TRIM_L_START_BIT))
#define AW88399_RCV_MODE_START_BIT (7)
#define AW88399_RCV_MODE_BITS_LEN (1)
#define AW88399_RCV_MODE_MASK \
(~(((1<<AW88399_RCV_MODE_BITS_LEN)-1) << AW88399_RCV_MODE_START_BIT))
#define AW88399_CLKI_START_BIT (4)
#define AW88399_NOCLKI_START_BIT (5)
#define AW88399_PLLI_START_BIT (0)
#define AW88399_PLLI_INT_VALUE (1)
#define AW88399_PLLI_INT_INTERRUPT \
(AW88399_PLLI_INT_VALUE << AW88399_PLLI_START_BIT)
#define AW88399_CLKI_INT_VALUE (1)
#define AW88399_CLKI_INT_INTERRUPT \
(AW88399_CLKI_INT_VALUE << AW88399_CLKI_START_BIT)
#define AW88399_NOCLKI_INT_VALUE (1)
#define AW88399_NOCLKI_INT_INTERRUPT \
(AW88399_NOCLKI_INT_VALUE << AW88399_NOCLKI_START_BIT)
#define AW88399_BIT_SYSINT_CHECK \
(AW88399_PLLI_INT_INTERRUPT | \
AW88399_CLKI_INT_INTERRUPT | \
AW88399_NOCLKI_INT_INTERRUPT)
#define AW88399_CRC_CHECK_START_BIT (12)
#define AW88399_CRC_CHECK_BITS_LEN (3)
#define AW88399_CRC_CHECK_BITS_MASK \
(~(((1<<AW88399_CRC_CHECK_BITS_LEN)-1) << AW88399_CRC_CHECK_START_BIT))
#define AW88399_RCV_MODE_RECEIVER (1)
#define AW88399_RCV_MODE_RECEIVER_VALUE \
(AW88399_RCV_MODE_RECEIVER << AW88399_RCV_MODE_START_BIT)
#define AW88399_AMPPD_START_BIT (1)
#define AW88399_AMPPD_BITS_LEN (1)
#define AW88399_AMPPD_MASK \
(~(((1<<AW88399_AMPPD_BITS_LEN)-1) << AW88399_AMPPD_START_BIT))
#define AW88399_AMPPD_WORKING (0)
#define AW88399_AMPPD_WORKING_VALUE \
(AW88399_AMPPD_WORKING << AW88399_AMPPD_START_BIT)
#define AW88399_AMPPD_POWER_DOWN (1)
#define AW88399_AMPPD_POWER_DOWN_VALUE \
(AW88399_AMPPD_POWER_DOWN << AW88399_AMPPD_START_BIT)
#define AW88399_RAM_CG_BYP_START_BIT (0)
#define AW88399_RAM_CG_BYP_BITS_LEN (1)
#define AW88399_RAM_CG_BYP_MASK \
(~(((1<<AW88399_RAM_CG_BYP_BITS_LEN)-1) << AW88399_RAM_CG_BYP_START_BIT))
#define AW88399_RAM_CG_BYP_WORK (0)
#define AW88399_RAM_CG_BYP_WORK_VALUE \
(AW88399_RAM_CG_BYP_WORK << AW88399_RAM_CG_BYP_START_BIT)
#define AW88399_RAM_CG_BYP_BYPASS (1)
#define AW88399_RAM_CG_BYP_BYPASS_VALUE \
(AW88399_RAM_CG_BYP_BYPASS << AW88399_RAM_CG_BYP_START_BIT)
#define AW88399_CRC_END_ADDR_START_BIT (0)
#define AW88399_CRC_END_ADDR_BITS_LEN (12)
#define AW88399_CRC_END_ADDR_MASK \
(~(((1<<AW88399_CRC_END_ADDR_BITS_LEN)-1) << AW88399_CRC_END_ADDR_START_BIT))
#define AW88399_CRC_CODE_EN_START_BIT (13)
#define AW88399_CRC_CODE_EN_BITS_LEN (1)
#define AW88399_CRC_CODE_EN_MASK \
(~(((1<<AW88399_CRC_CODE_EN_BITS_LEN)-1) << AW88399_CRC_CODE_EN_START_BIT))
#define AW88399_CRC_CODE_EN_DISABLE (0)
#define AW88399_CRC_CODE_EN_DISABLE_VALUE \
(AW88399_CRC_CODE_EN_DISABLE << AW88399_CRC_CODE_EN_START_BIT)
#define AW88399_CRC_CODE_EN_ENABLE (1)
#define AW88399_CRC_CODE_EN_ENABLE_VALUE \
(AW88399_CRC_CODE_EN_ENABLE << AW88399_CRC_CODE_EN_START_BIT)
#define AW88399_CRC_CFG_EN_START_BIT (12)
#define AW88399_CRC_CFG_EN_BITS_LEN (1)
#define AW88399_CRC_CFG_EN_MASK \
(~(((1<<AW88399_CRC_CFG_EN_BITS_LEN)-1) << AW88399_CRC_CFG_EN_START_BIT))
#define AW88399_CRC_CFG_EN_DISABLE (0)
#define AW88399_CRC_CFG_EN_DISABLE_VALUE \
(AW88399_CRC_CFG_EN_DISABLE << AW88399_CRC_CFG_EN_START_BIT)
#define AW88399_CRC_CFG_EN_ENABLE (1)
#define AW88399_CRC_CFG_EN_ENABLE_VALUE \
(AW88399_CRC_CFG_EN_ENABLE << AW88399_CRC_CFG_EN_START_BIT)
#define AW88399_OCDS_START_BIT (3)
#define AW88399_OCDS_OC (1)
#define AW88399_OCDS_OC_VALUE \
(AW88399_OCDS_OC << AW88399_OCDS_START_BIT)
#define AW88399_NOCLKS_START_BIT (5)
#define AW88399_NOCLKS_NO_CLOCK (1)
#define AW88399_NOCLKS_NO_CLOCK_VALUE \
(AW88399_NOCLKS_NO_CLOCK << AW88399_NOCLKS_START_BIT)
#define AW88399_SWS_START_BIT (8)
#define AW88399_SWS_SWITCHING (1)
#define AW88399_SWS_SWITCHING_VALUE \
(AW88399_SWS_SWITCHING << AW88399_SWS_START_BIT)
#define AW88399_BSTS_START_BIT (9)
#define AW88399_BSTS_FINISHED (1)
#define AW88399_BSTS_FINISHED_VALUE \
(AW88399_BSTS_FINISHED << AW88399_BSTS_START_BIT)
#define AW88399_UVLS_START_BIT (14)
#define AW88399_UVLS_NORMAL (0)
#define AW88399_UVLS_NORMAL_VALUE \
(AW88399_UVLS_NORMAL << AW88399_UVLS_START_BIT)
#define AW88399_BSTOCS_START_BIT (11)
#define AW88399_BSTOCS_OVER_CURRENT (1)
#define AW88399_BSTOCS_OVER_CURRENT_VALUE \
(AW88399_BSTOCS_OVER_CURRENT << AW88399_BSTOCS_START_BIT)
#define AW88399_OTHS_START_BIT (1)
#define AW88399_OTHS_OT (1)
#define AW88399_OTHS_OT_VALUE \
(AW88399_OTHS_OT << AW88399_OTHS_START_BIT)
#define AW88399_PLLS_START_BIT (0)
#define AW88399_PLLS_LOCKED (1)
#define AW88399_PLLS_LOCKED_VALUE \
(AW88399_PLLS_LOCKED << AW88399_PLLS_START_BIT)
#define AW88399_CLKS_START_BIT (4)
#define AW88399_CLKS_STABLE (1)
#define AW88399_CLKS_STABLE_VALUE \
(AW88399_CLKS_STABLE << AW88399_CLKS_START_BIT)
#define AW88399_BIT_PLL_CHECK \
(AW88399_CLKS_STABLE_VALUE | \
AW88399_PLLS_LOCKED_VALUE)
#define AW88399_BIT_SYSST_CHECK_MASK \
(~(AW88399_UVLS_NORMAL_VALUE | \
AW88399_BSTOCS_OVER_CURRENT_VALUE | \
AW88399_BSTS_FINISHED_VALUE | \
AW88399_SWS_SWITCHING_VALUE | \
AW88399_NOCLKS_NO_CLOCK_VALUE | \
AW88399_CLKS_STABLE_VALUE | \
AW88399_OCDS_OC_VALUE | \
AW88399_OTHS_OT_VALUE | \
AW88399_PLLS_LOCKED_VALUE))
#define AW88399_BIT_SYSST_NOSWS_CHECK \
(AW88399_BSTS_FINISHED_VALUE | \
AW88399_CLKS_STABLE_VALUE | \
AW88399_PLLS_LOCKED_VALUE)
#define AW88399_BIT_SYSST_SWS_CHECK \
(AW88399_BSTS_FINISHED_VALUE | \
AW88399_CLKS_STABLE_VALUE | \
AW88399_PLLS_LOCKED_VALUE | \
AW88399_SWS_SWITCHING_VALUE)
#define AW88399_CCO_MUX_START_BIT (14)
#define AW88399_CCO_MUX_BITS_LEN (1)
#define AW88399_CCO_MUX_MASK \
(~(((1<<AW88399_CCO_MUX_BITS_LEN)-1) << AW88399_CCO_MUX_START_BIT))
#define AW88399_CCO_MUX_DIVIDED (0)
#define AW88399_CCO_MUX_DIVIDED_VALUE \
(AW88399_CCO_MUX_DIVIDED << AW88399_CCO_MUX_START_BIT)
#define AW88399_CCO_MUX_BYPASS (1)
#define AW88399_CCO_MUX_BYPASS_VALUE \
(AW88399_CCO_MUX_BYPASS << AW88399_CCO_MUX_START_BIT)
#define AW88399_NOISE_GATE_EN_START_BIT (13)
#define AW88399_NOISE_GATE_EN_BITS_LEN (1)
#define AW88399_NOISE_GATE_EN_MASK \
(~(((1<<AW88399_NOISE_GATE_EN_BITS_LEN)-1) << AW88399_NOISE_GATE_EN_START_BIT))
#define AW88399_WDT_CNT_START_BIT (0)
#define AW88399_WDT_CNT_BITS_LEN (8)
#define AW88399_WDT_CNT_MASK \
(~(((1<<AW88399_WDT_CNT_BITS_LEN)-1) << AW88399_WDT_CNT_START_BIT))
#define AW88399_REABS_START_BIT (3)
#define AW88399_REABS_BITS_LEN (1)
#define AW88399_REABS_MASK \
(~(((1<<AW88399_REABS_BITS_LEN)-1) << AW88399_REABS_START_BIT))
#define AW88399_DSP_VOL_START_BIT (8)
#define AW88399_DSP_VOL_BITS_LEN (8)
#define AW88399_DSP_VOL_MASK \
(~(((1<<AW88399_DSP_VOL_BITS_LEN)-1) << AW88399_DSP_VOL_START_BIT))
#define AW883XX_DSP_NG_EN_START (13)
#define AW883XX_DSP_NG_EN_LEN (1)
#define AW883XX_DSP_NG_EN_MASK \
(~(((1 << AW883XX_DSP_NG_EN_LEN) - 1) << AW883XX_DSP_NG_EN_START))
#define AW883XX_DSP_NG_EN_DISABLE (0)
#define AW883XX_DSP_NG_EN_DISABLE_VALUE \
(AW883XX_DSP_NG_EN_DISABLE << AW883XX_DSP_NG_EN_START)
#define AW88399_VOLUME_STEP_DB (64)
#define AW88399_VOL_DEFAULT_VALUE (0)
#define AW88399_DSP_ODD_NUM_BIT_TEST (0x5555)
#define AW88399_EF_ISN_GESLP_SIGN_MASK (~(1 << 9))
#define AW88399_EF_ISN_GESLP_SIGN_NEG (0xfe00)
#define AW88399_EF_VSN_GESLP_SIGN_MASK (~(1 << 9))
#define AW88399_EF_VSN_GESLP_SIGN_NEG (0xfe00)
#define AW88399_TEM4_SIGN_MASK (~(1 << 5))
#define AW88399_TEM4_SIGN_NEG (0xffc0)
#define AW88399_ICABLK_FACTOR (1)
#define AW88399_VCABLK_FACTOR (1)
#define AW88399_VCABLK_DAC_FACTOR (2)
#define AW88399_VCALB_ADJ_FACTOR (12)
#define AW88399_VCALB_ACCURACY (1 << 12)
#define AW88399_ISCAL_FACTOR (3125)
#define AW88399_VSCAL_FACTOR (18875)
#define AW88399_ISCAL_DAC_FACTOR (3125)
#define AW88399_VSCAL_DAC_FACTOR (12600)
#define AW88399_CABL_BASE_VALUE (1000)
#define AW88399_DEV_DEFAULT_CH (0)
#define AW88399_DEV_DSP_CHECK_MAX (5)
#define AW88399_MAX_RAM_WRITE_BYTE_SIZE (128)
#define AW88399_DSP_RE_SHIFT (12)
#define AW88399_CALI_RE_MAX (15000)
#define AW88399_CALI_RE_MIN (4000)
#define AW_FW_ADDR_LEN (4)
#define AW88399_DSP_RE_TO_SHOW_RE(re, shift) (((re) * (1000)) >> (shift))
#define AW88399_SHOW_RE_TO_DSP_RE(re, shift) (((re) << shift) / (1000))
#define AW88399_CRC_CHECK_PASS_VAL (0x4)
#define AW88399_CRC_CFG_BASE_ADDR (0xD80)
#define AW88399_CRC_FW_BASE_ADDR (0x4C0)
#define AW88399_ACF_FILE "aw88399_acf.bin"
#define AW88399_DEV_SYSST_CHECK_MAX (10)
#define AW88399_CHIP_ID 0x2183
#define AW88399_START_RETRIES (5)
#define AW88399_START_WORK_DELAY_MS (0)
enum {
AW_EF_AND_CHECK = 0,
AW_EF_OR_CHECK,
};
enum {
AW88399_DEV_VDSEL_DAC = 0,
AW88399_DEV_VDSEL_VSENSE = 32,
};
enum {
AW88399_DSP_CRC_NA = 0,
AW88399_DSP_CRC_OK = 1,
};
enum {
AW88399_DSP_FW_UPDATE_OFF = 0,
AW88399_DSP_FW_UPDATE_ON = 1,
};
enum {
AW88399_FORCE_UPDATE_OFF = 0,
AW88399_FORCE_UPDATE_ON = 1,
};
enum {
AW88399_1000_US = 1000,
AW88399_2000_US = 2000,
AW88399_3000_US = 3000,
AW88399_4000_US = 4000,
};
enum AW88399_DEV_STATUS {
AW88399_DEV_PW_OFF = 0,
AW88399_DEV_PW_ON,
};
enum AW88399_DEV_FW_STATUS {
AW88399_DEV_FW_FAILED = 0,
AW88399_DEV_FW_OK,
};
enum AW88399_DEV_MEMCLK {
AW88399_DEV_MEMCLK_OSC = 0,
AW88399_DEV_MEMCLK_PLL = 1,
};
enum AW88399_DEV_DSP_CFG {
AW88399_DEV_DSP_WORK = 0,
AW88399_DEV_DSP_BYPASS = 1,
};
enum {
AW88399_NOT_RCV_MODE = 0,
AW88399_RCV_MODE = 1,
};
enum {
AW88399_SYNC_START = 0,
AW88399_ASYNC_START,
};
struct aw_device;
struct aw_container;
struct aw_cali_desc;
struct gpio_desc;
struct i2c_client;
struct regmap;
struct aw88399 {
struct aw_device *aw_pa;
struct mutex lock;
struct gpio_desc *reset_gpio;
struct delayed_work start_work;
struct regmap *regmap;
struct aw_container *aw_cfg;
unsigned int check_val;
unsigned int crc_init_val;
unsigned int vcalb_init_val;
unsigned int dither_st;
bool bsts_unreliable;
bool fw_needs_reload;
};
int aw_dev_check_syspll(struct aw_device *aw_dev);
void aw_dev_dsp_enable(struct aw_device *aw_dev, bool is_enable);
int aw_dev_get_dsp_status(struct aw_device *aw_dev);
int aw_dev_set_volume(struct aw_device *aw_dev, unsigned int value);
int aw_dev_update_cali_re(struct aw_cali_desc *cali_desc);
int aw88399_dev_get_prof_name(struct aw_device *aw_dev, int index, char **prof_name);
void aw88399_dev_mute(struct aw_device *aw_dev, bool is_mute);
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);
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);
#endif /* __SOUND_AW88399_H */

View File

@ -7,6 +7,7 @@
* Copyright (c) by Jaroslav Kysela <perex@perex.cz>
*/
#include <linux/rwsem.h>
#include <linux/wait.h>
#include <linux/nospec.h>
#include <sound/asound.h>
@ -167,6 +168,8 @@ snd_ctl_find_id_mixer(struct snd_card *card, const char *name)
int snd_ctl_create(struct snd_card *card);
extern struct rw_semaphore snd_ioctl_rwsem;
int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn);
int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn);
#ifdef CONFIG_COMPAT

View File

@ -108,8 +108,8 @@ struct snd_card {
char longname[80]; /* name of this soundcard */
char irq_descr[32]; /* Interrupt description */
char mixername[80]; /* mixer name */
char components[128]; /* card components delimited with
space */
char *components; /* card components, space-delimited */
unsigned int components_alloc_size; /* current allocation size of components */
struct module *module; /* top-level module */
void *private_data; /* private data for soundcard */

View File

@ -417,7 +417,6 @@ void cs35l56_wait_control_port_ready(void);
void cs35l56_wait_min_reset_pulse(void);
void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire);
int cs35l56_irq_request(struct cs35l56_base *cs35l56_base, int irq);
irqreturn_t cs35l56_irq(int irq, void *data);
int cs35l56_is_fw_reload_needed(struct cs35l56_base *cs35l56_base);
int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base);
int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_soundwire);

View File

@ -175,12 +175,6 @@ int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
struct dmaengine_pcm {
struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
const struct snd_dmaengine_pcm_config *config;
struct snd_soc_component component;
unsigned int flags;
};
static inline struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p)
{
return container_of(p, struct dmaengine_pcm, component);
}
#endif

View File

@ -9,6 +9,22 @@
struct hdac_bus;
struct hdac_ext_link;
/**
* enum hda_bus_ml_link_type - mlink link type, used by SOF link DMA
* allocator constraints (see struct sof_intel_hda_dev).
*
* @HDA_BUS_ML_LINK_HDA: non-alt link, i.e. HDA codec or iDisp
* @HDA_BUS_ML_LINK_SDW: alt link, SoundWire
* @HDA_BUS_ML_LINK_UAOL: alt link, USB Audio Offload
* @HDA_BUS_ML_LINK_OTHER: alt link, SSP or DMIC
*/
enum hda_bus_ml_link_type {
HDA_BUS_ML_LINK_HDA,
HDA_BUS_ML_LINK_SDW,
HDA_BUS_ML_LINK_UAOL,
HDA_BUS_ML_LINK_OTHER,
};
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_MLINK)
int hda_bus_ml_init(struct hdac_bus *bus);
@ -49,11 +65,12 @@ int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num);
int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
int channel_mask, int stream_id, int dir);
void hda_bus_ml_put_all(struct hdac_bus *bus);
void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
int hda_bus_ml_resume(struct hdac_bus *bus);
int hda_bus_ml_suspend(struct hdac_bus *bus);
enum hda_bus_ml_link_type hda_bus_ml_link_get_type(struct hdac_ext_link *hlink);
struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus);
struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus);
struct hdac_ext_link *hdac_bus_eml_sdw_get_hlink(struct hdac_bus *bus);
@ -169,11 +186,13 @@ hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
return 0;
}
static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { }
static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; }
static inline int hda_bus_ml_suspend(struct hdac_bus *bus) { return 0; }
static inline enum hda_bus_ml_link_type
hda_bus_ml_link_get_type(struct hdac_ext_link *hlink) { return HDA_BUS_ML_LINK_HDA; }
static inline struct hdac_ext_link *
hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus) { return NULL; }

View File

@ -256,6 +256,7 @@ struct hda_codec {
unsigned int link_down_at_suspend:1; /* link down at runtime suspend */
unsigned int relaxed_resume:1; /* don't resume forcibly for jack */
unsigned int forced_resume:1; /* forced resume for jack */
unsigned int acomp_requested_resume:1; /* resume requested by acomp */
unsigned int no_stream_clean_at_suspend:1; /* do not clean streams at suspend */
unsigned int ctl_dev_id:1; /* old control element id build behaviour */
unsigned int eld_jack_detect:1; /* Machine jack-detection by ELD */

View File

@ -69,11 +69,14 @@ void snd_hdac_regmap_sync(struct hdac_device *codec);
/**
* snd_hdac_regmap_write - Write a verb with caching
* @codec: HD-audio codec base device
* @nid: codec NID
* @reg: verb to write
* @verb: verb to write
* @val: value to write
*
* For writing an amp value, use snd_hdac_regmap_update_amp().
*
* Returns: %0 if successful or a negative error code.
*/
static inline int
snd_hdac_regmap_write(struct hdac_device *codec, hda_nid_t nid,
@ -85,13 +88,16 @@ snd_hdac_regmap_write(struct hdac_device *codec, hda_nid_t nid,
}
/**
* snd_hda_regmap_update - Update a verb value with caching
* snd_hdac_regmap_update - Update a verb value with caching
* @codec: HD-audio codec
* @nid: codec NID
* @verb: verb to update
* @mask: bit mask to update
* @val: value to update
*
* For updating an amp value, use snd_hdac_regmap_update_amp().
*
* Returns: %0 if successful or a negative error code.
*/
static inline int
snd_hdac_regmap_update(struct hdac_device *codec, hda_nid_t nid,
@ -104,12 +110,15 @@ snd_hdac_regmap_update(struct hdac_device *codec, hda_nid_t nid,
}
/**
* snd_hda_regmap_read - Read a verb with caching
* snd_hdac_regmap_read - Read a verb with caching
* @codec: HD-audio codec
* @nid: codec NID
* @verb: verb to read
* @val: pointer to store the value
*
* For reading an amp value, use snd_hda_regmap_get_amp().
*
* Returns: %0 if successful or a negative error code.
*/
static inline int
snd_hdac_regmap_read(struct hdac_device *codec, hda_nid_t nid,
@ -125,12 +134,12 @@ snd_hdac_regmap_read(struct hdac_device *codec, hda_nid_t nid,
* @codec: HD-audio codec
* @nid: NID to read the AMP value
* @ch: channel (left=0 or right=1)
* @direction: #HDA_INPUT or #HDA_OUTPUT
* @index: the index value (only for input direction)
* @val: the pointer to store the value
* @dir: #HDA_INPUT or #HDA_OUTPUT
* @idx: the index value (only for input direction)
*
* Read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit.
* Returns the value or a negative error.
*
* Returns: the value or a negative error.
*/
static inline int
snd_hdac_regmap_get_amp(struct hdac_device *codec, hda_nid_t nid,
@ -148,13 +157,14 @@ snd_hdac_regmap_get_amp(struct hdac_device *codec, hda_nid_t nid,
* @codec: HD-audio codec
* @nid: NID to read the AMP value
* @ch: channel (left=0 or right=1)
* @direction: #HDA_INPUT or #HDA_OUTPUT
* @dir: #HDA_INPUT or #HDA_OUTPUT
* @idx: the index value (only for input direction)
* @mask: bit mask to set
* @val: the bits value to set
*
* Update the AMP value with a bit mask.
* Returns 0 if the value is unchanged, 1 if changed, or a negative error.
*
* Returns: 0 if the value is unchanged, 1 if changed, or a negative error.
*/
static inline int
snd_hdac_regmap_update_amp(struct hdac_device *codec, hda_nid_t nid,
@ -169,13 +179,12 @@ snd_hdac_regmap_update_amp(struct hdac_device *codec, hda_nid_t nid,
* snd_hdac_regmap_get_amp_stereo - Read stereo AMP values
* @codec: HD-audio codec
* @nid: NID to read the AMP value
* @ch: channel (left=0 or right=1)
* @direction: #HDA_INPUT or #HDA_OUTPUT
* @index: the index value (only for input direction)
* @val: the pointer to store the value
* @dir: #HDA_INPUT or #HDA_OUTPUT
* @idx: the index value (only for input direction)
*
* Read stereo AMP values. The lower byte is left, the upper byte is right.
* Returns the value or a negative error.
*
* Returns: the value or a negative error.
*/
static inline int
snd_hdac_regmap_get_amp_stereo(struct hdac_device *codec, hda_nid_t nid,
@ -192,14 +201,15 @@ snd_hdac_regmap_get_amp_stereo(struct hdac_device *codec, hda_nid_t nid,
* snd_hdac_regmap_update_amp_stereo - update the stereo AMP value
* @codec: HD-audio codec
* @nid: NID to read the AMP value
* @direction: #HDA_INPUT or #HDA_OUTPUT
* @dir: #HDA_INPUT or #HDA_OUTPUT
* @idx: the index value (only for input direction)
* @mask: bit mask to set
* @val: the bits value to set
*
* Update the stereo AMP value with a bit mask.
* The lower byte is left, the upper byte is right.
* Returns 0 if the value is unchanged, 1 if changed, or a negative error.
*
* Returns: 0 if the value is unchanged, 1 if changed, or a negative error.
*/
static inline int
snd_hdac_regmap_update_amp_stereo(struct hdac_device *codec, hda_nid_t nid,

View File

@ -145,61 +145,60 @@ struct snd_pcm_ops {
#define SNDRV_PCM_RATE_8000_768000 (SNDRV_PCM_RATE_8000_384000|\
SNDRV_PCM_RATE_705600|\
SNDRV_PCM_RATE_768000)
#define _SNDRV_PCM_FMTBIT(fmt) (1ULL << (__force int)SNDRV_PCM_FORMAT_##fmt)
#define SNDRV_PCM_FMTBIT_S8 _SNDRV_PCM_FMTBIT(S8)
#define SNDRV_PCM_FMTBIT_U8 _SNDRV_PCM_FMTBIT(U8)
#define SNDRV_PCM_FMTBIT_S16_LE _SNDRV_PCM_FMTBIT(S16_LE)
#define SNDRV_PCM_FMTBIT_S16_BE _SNDRV_PCM_FMTBIT(S16_BE)
#define SNDRV_PCM_FMTBIT_U16_LE _SNDRV_PCM_FMTBIT(U16_LE)
#define SNDRV_PCM_FMTBIT_U16_BE _SNDRV_PCM_FMTBIT(U16_BE)
#define SNDRV_PCM_FMTBIT_S24_LE _SNDRV_PCM_FMTBIT(S24_LE)
#define SNDRV_PCM_FMTBIT_S24_BE _SNDRV_PCM_FMTBIT(S24_BE)
#define SNDRV_PCM_FMTBIT_U24_LE _SNDRV_PCM_FMTBIT(U24_LE)
#define SNDRV_PCM_FMTBIT_U24_BE _SNDRV_PCM_FMTBIT(U24_BE)
#define SNDRV_PCM_FMTBIT_S8 (1ULL << SNDRV_PCM_FORMAT_S8)
#define SNDRV_PCM_FMTBIT_U8 (1ULL << SNDRV_PCM_FORMAT_U8)
#define SNDRV_PCM_FMTBIT_S16_LE (1ULL << SNDRV_PCM_FORMAT_S16_LE)
#define SNDRV_PCM_FMTBIT_S16_BE (1ULL << SNDRV_PCM_FORMAT_S16_BE)
#define SNDRV_PCM_FMTBIT_U16_LE (1ULL << SNDRV_PCM_FORMAT_U16_LE)
#define SNDRV_PCM_FMTBIT_U16_BE (1ULL << SNDRV_PCM_FORMAT_U16_BE)
#define SNDRV_PCM_FMTBIT_S24_LE (1ULL << SNDRV_PCM_FORMAT_S24_LE)
#define SNDRV_PCM_FMTBIT_S24_BE (1ULL << SNDRV_PCM_FORMAT_S24_BE)
#define SNDRV_PCM_FMTBIT_U24_LE (1ULL << SNDRV_PCM_FORMAT_U24_LE)
#define SNDRV_PCM_FMTBIT_U24_BE (1ULL << SNDRV_PCM_FORMAT_U24_BE)
// For S32/U32 formats, 'msbits' hardware parameter is often used to deliver information about the
// available bit count in most significant bit. It's for the case of so-called 'left-justified' or
// `right-padding` sample which has less width than 32 bit.
#define SNDRV_PCM_FMTBIT_S32_LE _SNDRV_PCM_FMTBIT(S32_LE)
#define SNDRV_PCM_FMTBIT_S32_BE _SNDRV_PCM_FMTBIT(S32_BE)
#define SNDRV_PCM_FMTBIT_U32_LE _SNDRV_PCM_FMTBIT(U32_LE)
#define SNDRV_PCM_FMTBIT_U32_BE _SNDRV_PCM_FMTBIT(U32_BE)
#define SNDRV_PCM_FMTBIT_FLOAT_LE _SNDRV_PCM_FMTBIT(FLOAT_LE)
#define SNDRV_PCM_FMTBIT_FLOAT_BE _SNDRV_PCM_FMTBIT(FLOAT_BE)
#define SNDRV_PCM_FMTBIT_FLOAT64_LE _SNDRV_PCM_FMTBIT(FLOAT64_LE)
#define SNDRV_PCM_FMTBIT_FLOAT64_BE _SNDRV_PCM_FMTBIT(FLOAT64_BE)
#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE _SNDRV_PCM_FMTBIT(IEC958_SUBFRAME_LE)
#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE _SNDRV_PCM_FMTBIT(IEC958_SUBFRAME_BE)
#define SNDRV_PCM_FMTBIT_MU_LAW _SNDRV_PCM_FMTBIT(MU_LAW)
#define SNDRV_PCM_FMTBIT_A_LAW _SNDRV_PCM_FMTBIT(A_LAW)
#define SNDRV_PCM_FMTBIT_IMA_ADPCM _SNDRV_PCM_FMTBIT(IMA_ADPCM)
#define SNDRV_PCM_FMTBIT_MPEG _SNDRV_PCM_FMTBIT(MPEG)
#define SNDRV_PCM_FMTBIT_GSM _SNDRV_PCM_FMTBIT(GSM)
#define SNDRV_PCM_FMTBIT_S20_LE _SNDRV_PCM_FMTBIT(S20_LE)
#define SNDRV_PCM_FMTBIT_U20_LE _SNDRV_PCM_FMTBIT(U20_LE)
#define SNDRV_PCM_FMTBIT_S20_BE _SNDRV_PCM_FMTBIT(S20_BE)
#define SNDRV_PCM_FMTBIT_U20_BE _SNDRV_PCM_FMTBIT(U20_BE)
#define SNDRV_PCM_FMTBIT_SPECIAL _SNDRV_PCM_FMTBIT(SPECIAL)
#define SNDRV_PCM_FMTBIT_S24_3LE _SNDRV_PCM_FMTBIT(S24_3LE)
#define SNDRV_PCM_FMTBIT_U24_3LE _SNDRV_PCM_FMTBIT(U24_3LE)
#define SNDRV_PCM_FMTBIT_S24_3BE _SNDRV_PCM_FMTBIT(S24_3BE)
#define SNDRV_PCM_FMTBIT_U24_3BE _SNDRV_PCM_FMTBIT(U24_3BE)
#define SNDRV_PCM_FMTBIT_S20_3LE _SNDRV_PCM_FMTBIT(S20_3LE)
#define SNDRV_PCM_FMTBIT_U20_3LE _SNDRV_PCM_FMTBIT(U20_3LE)
#define SNDRV_PCM_FMTBIT_S20_3BE _SNDRV_PCM_FMTBIT(S20_3BE)
#define SNDRV_PCM_FMTBIT_U20_3BE _SNDRV_PCM_FMTBIT(U20_3BE)
#define SNDRV_PCM_FMTBIT_S18_3LE _SNDRV_PCM_FMTBIT(S18_3LE)
#define SNDRV_PCM_FMTBIT_U18_3LE _SNDRV_PCM_FMTBIT(U18_3LE)
#define SNDRV_PCM_FMTBIT_S18_3BE _SNDRV_PCM_FMTBIT(S18_3BE)
#define SNDRV_PCM_FMTBIT_U18_3BE _SNDRV_PCM_FMTBIT(U18_3BE)
#define SNDRV_PCM_FMTBIT_G723_24 _SNDRV_PCM_FMTBIT(G723_24)
#define SNDRV_PCM_FMTBIT_G723_24_1B _SNDRV_PCM_FMTBIT(G723_24_1B)
#define SNDRV_PCM_FMTBIT_G723_40 _SNDRV_PCM_FMTBIT(G723_40)
#define SNDRV_PCM_FMTBIT_G723_40_1B _SNDRV_PCM_FMTBIT(G723_40_1B)
#define SNDRV_PCM_FMTBIT_DSD_U8 _SNDRV_PCM_FMTBIT(DSD_U8)
#define SNDRV_PCM_FMTBIT_DSD_U16_LE _SNDRV_PCM_FMTBIT(DSD_U16_LE)
#define SNDRV_PCM_FMTBIT_DSD_U32_LE _SNDRV_PCM_FMTBIT(DSD_U32_LE)
#define SNDRV_PCM_FMTBIT_DSD_U16_BE _SNDRV_PCM_FMTBIT(DSD_U16_BE)
#define SNDRV_PCM_FMTBIT_DSD_U32_BE _SNDRV_PCM_FMTBIT(DSD_U32_BE)
#define SNDRV_PCM_FMTBIT_S32_LE (1ULL << SNDRV_PCM_FORMAT_S32_LE)
#define SNDRV_PCM_FMTBIT_S32_BE (1ULL << SNDRV_PCM_FORMAT_S32_BE)
#define SNDRV_PCM_FMTBIT_U32_LE (1ULL << SNDRV_PCM_FORMAT_U32_LE)
#define SNDRV_PCM_FMTBIT_U32_BE (1ULL << SNDRV_PCM_FORMAT_U32_BE)
#define SNDRV_PCM_FMTBIT_FLOAT_LE (1ULL << SNDRV_PCM_FORMAT_FLOAT_LE)
#define SNDRV_PCM_FMTBIT_FLOAT_BE (1ULL << SNDRV_PCM_FORMAT_FLOAT_BE)
#define SNDRV_PCM_FMTBIT_FLOAT64_LE (1ULL << SNDRV_PCM_FORMAT_FLOAT64_LE)
#define SNDRV_PCM_FMTBIT_FLOAT64_BE (1ULL << SNDRV_PCM_FORMAT_FLOAT64_BE)
#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE (1ULL << SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE)
#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE (1ULL << SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE)
#define SNDRV_PCM_FMTBIT_MU_LAW (1ULL << SNDRV_PCM_FORMAT_MU_LAW)
#define SNDRV_PCM_FMTBIT_A_LAW (1ULL << SNDRV_PCM_FORMAT_A_LAW)
#define SNDRV_PCM_FMTBIT_IMA_ADPCM (1ULL << SNDRV_PCM_FORMAT_IMA_ADPCM)
#define SNDRV_PCM_FMTBIT_MPEG (1ULL << SNDRV_PCM_FORMAT_MPEG)
#define SNDRV_PCM_FMTBIT_GSM (1ULL << SNDRV_PCM_FORMAT_GSM)
#define SNDRV_PCM_FMTBIT_S20_LE (1ULL << SNDRV_PCM_FORMAT_S20_LE)
#define SNDRV_PCM_FMTBIT_U20_LE (1ULL << SNDRV_PCM_FORMAT_U20_LE)
#define SNDRV_PCM_FMTBIT_S20_BE (1ULL << SNDRV_PCM_FORMAT_S20_BE)
#define SNDRV_PCM_FMTBIT_U20_BE (1ULL << SNDRV_PCM_FORMAT_U20_BE)
#define SNDRV_PCM_FMTBIT_SPECIAL (1ULL << SNDRV_PCM_FORMAT_SPECIAL)
#define SNDRV_PCM_FMTBIT_S24_3LE (1ULL << SNDRV_PCM_FORMAT_S24_3LE)
#define SNDRV_PCM_FMTBIT_U24_3LE (1ULL << SNDRV_PCM_FORMAT_U24_3LE)
#define SNDRV_PCM_FMTBIT_S24_3BE (1ULL << SNDRV_PCM_FORMAT_S24_3BE)
#define SNDRV_PCM_FMTBIT_U24_3BE (1ULL << SNDRV_PCM_FORMAT_U24_3BE)
#define SNDRV_PCM_FMTBIT_S20_3LE (1ULL << SNDRV_PCM_FORMAT_S20_3LE)
#define SNDRV_PCM_FMTBIT_U20_3LE (1ULL << SNDRV_PCM_FORMAT_U20_3LE)
#define SNDRV_PCM_FMTBIT_S20_3BE (1ULL << SNDRV_PCM_FORMAT_S20_3BE)
#define SNDRV_PCM_FMTBIT_U20_3BE (1ULL << SNDRV_PCM_FORMAT_U20_3BE)
#define SNDRV_PCM_FMTBIT_S18_3LE (1ULL << SNDRV_PCM_FORMAT_S18_3LE)
#define SNDRV_PCM_FMTBIT_U18_3LE (1ULL << SNDRV_PCM_FORMAT_U18_3LE)
#define SNDRV_PCM_FMTBIT_S18_3BE (1ULL << SNDRV_PCM_FORMAT_S18_3BE)
#define SNDRV_PCM_FMTBIT_U18_3BE (1ULL << SNDRV_PCM_FORMAT_U18_3BE)
#define SNDRV_PCM_FMTBIT_G723_24 (1ULL << SNDRV_PCM_FORMAT_G723_24)
#define SNDRV_PCM_FMTBIT_G723_24_1B (1ULL << SNDRV_PCM_FORMAT_G723_24_1B)
#define SNDRV_PCM_FMTBIT_G723_40 (1ULL << SNDRV_PCM_FORMAT_G723_40)
#define SNDRV_PCM_FMTBIT_G723_40_1B (1ULL << SNDRV_PCM_FORMAT_G723_40_1B)
#define SNDRV_PCM_FMTBIT_DSD_U8 (1ULL << SNDRV_PCM_FORMAT_DSD_U8)
#define SNDRV_PCM_FMTBIT_DSD_U16_LE (1ULL << SNDRV_PCM_FORMAT_DSD_U16_LE)
#define SNDRV_PCM_FMTBIT_DSD_U32_LE (1ULL << SNDRV_PCM_FORMAT_DSD_U32_LE)
#define SNDRV_PCM_FMTBIT_DSD_U16_BE (1ULL << SNDRV_PCM_FORMAT_DSD_U16_BE)
#define SNDRV_PCM_FMTBIT_DSD_U32_BE (1ULL << SNDRV_PCM_FORMAT_DSD_U32_BE)
#ifdef SNDRV_LITTLE_ENDIAN
#define SNDRV_PCM_FMTBIT_S16 SNDRV_PCM_FMTBIT_S16_LE
@ -228,11 +227,10 @@ struct snd_pcm_ops {
#define SNDRV_PCM_FMTBIT_U20 SNDRV_PCM_FMTBIT_U20_BE
#endif
#define _SNDRV_PCM_SUBFMTBIT(fmt) BIT((__force int)SNDRV_PCM_SUBFORMAT_##fmt)
#define SNDRV_PCM_SUBFMTBIT_STD _SNDRV_PCM_SUBFMTBIT(STD)
#define SNDRV_PCM_SUBFMTBIT_MSBITS_MAX _SNDRV_PCM_SUBFMTBIT(MSBITS_MAX)
#define SNDRV_PCM_SUBFMTBIT_MSBITS_20 _SNDRV_PCM_SUBFMTBIT(MSBITS_20)
#define SNDRV_PCM_SUBFMTBIT_MSBITS_24 _SNDRV_PCM_SUBFMTBIT(MSBITS_24)
#define SNDRV_PCM_SUBFMTBIT_STD (1U << SNDRV_PCM_SUBFORMAT_STD)
#define SNDRV_PCM_SUBFMTBIT_MSBITS_MAX (1U << SNDRV_PCM_SUBFORMAT_MSBITS_MAX)
#define SNDRV_PCM_SUBFMTBIT_MSBITS_20 (1U << SNDRV_PCM_SUBFORMAT_MSBITS_20)
#define SNDRV_PCM_SUBFMTBIT_MSBITS_24 (1U << SNDRV_PCM_SUBFORMAT_MSBITS_24)
struct snd_pcm_file {
struct snd_pcm_substream *substream;
@ -1515,7 +1513,7 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
*/
static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format)
{
return 1ULL << (__force int) pcm_format;
return 1ULL << pcm_format;
}
/**
@ -1523,9 +1521,7 @@ static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format)
* @f: the iterator variable in snd_pcm_format_t type
*/
#define pcm_for_each_format(f) \
for ((f) = SNDRV_PCM_FORMAT_FIRST; \
(__force int)(f) <= (__force int)SNDRV_PCM_FORMAT_LAST; \
(f) = (__force snd_pcm_format_t)((__force int)(f) + 1))
for ((f) = SNDRV_PCM_FORMAT_FIRST; (f) <= SNDRV_PCM_FORMAT_LAST; (f)++)
/* printk helpers */
#define pcm_err(pcm, fmt, args...) \

View File

@ -71,7 +71,7 @@ static inline void snd_mask_set(struct snd_mask *mask, unsigned int val)
static inline void snd_mask_set_format(struct snd_mask *mask,
snd_pcm_format_t format)
{
snd_mask_set(mask, (__force unsigned int)format);
snd_mask_set(mask, format);
}
static inline void snd_mask_reset(struct snd_mask *mask, unsigned int val)
@ -132,7 +132,7 @@ static inline int snd_mask_test(const struct snd_mask *mask, unsigned int val)
static inline int snd_mask_test_format(const struct snd_mask *mask,
snd_pcm_format_t format)
{
return snd_mask_test(mask, (__force unsigned int)format);
return snd_mask_test(mask, format);
}
static inline int snd_mask_single(const struct snd_mask *mask)
@ -302,8 +302,7 @@ static inline int snd_interval_eq(const struct snd_interval *i1, const struct sn
*/
static inline snd_pcm_access_t params_access(const struct snd_pcm_hw_params *p)
{
return (__force snd_pcm_access_t)snd_mask_min(hw_param_mask_c(p,
SNDRV_PCM_HW_PARAM_ACCESS));
return snd_mask_min(hw_param_mask_c(p, SNDRV_PCM_HW_PARAM_ACCESS));
}
/**
@ -312,8 +311,7 @@ static inline snd_pcm_access_t params_access(const struct snd_pcm_hw_params *p)
*/
static inline snd_pcm_format_t params_format(const struct snd_pcm_hw_params *p)
{
return (__force snd_pcm_format_t)snd_mask_min(hw_param_mask_c(p,
SNDRV_PCM_HW_PARAM_FORMAT));
return snd_mask_min(hw_param_mask_c(p, SNDRV_PCM_HW_PARAM_FORMAT));
}
/**
@ -323,8 +321,7 @@ static inline snd_pcm_format_t params_format(const struct snd_pcm_hw_params *p)
static inline snd_pcm_subformat_t
params_subformat(const struct snd_pcm_hw_params *p)
{
return (__force snd_pcm_subformat_t)snd_mask_min(hw_param_mask_c(p,
SNDRV_PCM_HW_PARAM_SUBFORMAT));
return snd_mask_min(hw_param_mask_c(p, SNDRV_PCM_HW_PARAM_SUBFORMAT));
}
/**

View File

@ -176,8 +176,9 @@ int snd_rawmidi_proceed(struct snd_rawmidi_substream *substream);
/* main midi functions */
int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info);
int snd_rawmidi_kernel_open(struct snd_rawmidi *rmidi, int subdevice,
int mode, struct snd_rawmidi_file *rfile);
int snd_rawmidi_kernel_open_nested(struct snd_rawmidi *rmidi, int subdevice,
int mode, struct snd_rawmidi_file *rfile,
int depth);
int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile);
int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
struct snd_rawmidi_params *params);
@ -191,6 +192,15 @@ long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream,
long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream,
const unsigned char *buf, long count);
/* non-nested version */
static inline int snd_rawmidi_kernel_open(struct snd_rawmidi *rmidi,
int subdevice,
int mode,
struct snd_rawmidi_file *rfile)
{
return snd_rawmidi_kernel_open_nested(rmidi, subdevice, mode, rfile, 0);
}
/* set up the tied devices */
static inline void snd_rawmidi_tie_devices(struct snd_rawmidi *r1,
struct snd_rawmidi *r2)

View File

@ -25,6 +25,8 @@ struct snd_soc_dai_driver;
struct snd_soc_dai_ops;
struct snd_soc_dapm_route;
struct snd_soc_dapm_widget;
struct snd_soc_pcm_stream;
struct sdca_entity;
/* convenient macro to handle the mono volume in 7.8 fixed format representation */
#define SDCA_SINGLE_Q78_TLV(xname, xreg, xmin, xmax, xstep, tlv_array) \
@ -82,6 +84,11 @@ int sdca_asoc_populate_component(struct device *dev,
struct snd_soc_dai_driver **dai_drv, int *num_dai_drv,
const struct snd_soc_dai_ops *ops);
int sdca_asoc_populate_rate_format(struct device *dev,
struct sdca_function_data *function,
struct sdca_entity *entity,
struct snd_soc_pcm_stream *stream);
int sdca_asoc_set_constraints(struct device *dev, struct regmap *regmap,
struct sdca_function_data *function,
struct snd_pcm_substream *substream,
@ -100,9 +107,9 @@ int sdca_asoc_q78_put_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int sdca_asoc_q78_get_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int sdca_asoc_pde_poll_actual_ps(struct device *dev, struct regmap *regmap,
int sdca_asoc_pde_poll_actual_ps(struct regmap *regmap,
int function_id, int entity_id,
int from_ps, int to_ps,
const struct sdca_pde_delay *pde_delays,
int num_delays);
int from_ps, int to_ps,
const struct sdca_pde_delay *pde_delays,
int num_delays);
#endif // __SDCA_ASOC_H__

View File

@ -83,6 +83,10 @@ static inline int sdca_fdl_alloc_state(struct sdca_interrupt *interrupt)
return 0;
}
static inline void sdca_fdl_free_state(struct sdca_interrupt *interrupt)
{
}
static inline int sdca_fdl_process(struct sdca_interrupt *interrupt)
{
return 0;

View File

@ -298,7 +298,7 @@ enum sdca_xu_controls {
};
/**
* enum sdca_set_index_range - Column definitions UMP SetIndex
* enum sdca_fdl_set_index_range - Column definitions UMP SetIndex
*/
enum sdca_fdl_set_index_range {
SDCA_FDL_SET_INDEX_SET_NUMBER = 0,
@ -803,6 +803,8 @@ struct sdca_control_range {
* @mode: Access mode of the Control.
* @layers: Bitmask of access layers of the Control.
* @deferrable: Indicates if the access to the Control can be deferred.
* @is_volatile: Indicates the Control registers are forced to be treated
* as volatile.
* @has_default: Indicates the Control has a default value to be written.
* @has_reset: Indicates the Control has a defined reset value.
* @has_fixed: Indicates the Control only supports a single value.
@ -1116,7 +1118,6 @@ struct sdca_entity_ge {
/**
* struct sdca_entity_hide - information specific to HIDE Entities
* @hid: HID device structure
* @num_hidtx_ids: number of HIDTx Report ID
* @num_hidrx_ids: number of HIDRx Report ID
* @hidtx_ids: HIDTx Report ID
@ -1127,11 +1128,8 @@ struct sdca_entity_ge {
* within this Device
* @max_delay: the maximum time in microseconds allowed for the Device
* to change the ownership from Device to Host
* @hid_report_desc: HID Report Descriptor for the HIDE Entity
* @hid_desc: HID descriptor for the HIDE Entity
*/
struct sdca_entity_hide {
struct hid_device *hid;
unsigned int *hidtx_ids;
unsigned int *hidrx_ids;
int num_hidtx_ids;
@ -1139,12 +1137,10 @@ struct sdca_entity_hide {
unsigned int af_number_list[SDCA_MAX_FUNCTION_COUNT];
unsigned int hide_reside_function_num;
unsigned int max_delay;
unsigned char *hid_report_desc;
struct hid_descriptor hid_desc;
};
/**
* enum sdca_xu_reset_machanism - SDCA FDL Resets
* enum sdca_xu_reset_mechanism - SDCA FDL Resets
*/
enum sdca_xu_reset_mechanism {
SDCA_XU_RESET_FUNCTION = 0x0,
@ -1401,6 +1397,16 @@ struct sdca_fdl_data {
int num_sets;
};
/**
* struct sdca_function_hid - information about a function's HID descriptors
* @report_desc: HID Report Descriptor for the HID Function
* @desc: HID descriptor for the HID Function
*/
struct sdca_function_hid {
unsigned char *report_desc;
struct hid_descriptor desc;
};
/**
* struct sdca_function_data - top-level information for one SDCA function
* @desc: Pointer to short descriptor from initial parsing.
@ -1415,6 +1421,7 @@ struct sdca_fdl_data {
* @reset_max_delay: Maximum Function reset delay in microseconds, before an
* error should be reported.
* @fdl_data: FDL data for this Function, if available.
* @hid: HID data for this Function, if available.
*/
struct sdca_function_data {
struct sdca_function_desc *desc;
@ -1430,6 +1437,10 @@ struct sdca_function_data {
unsigned int reset_max_delay;
struct sdca_fdl_data fdl_data;
union {
struct sdca_function_hid hid;
};
};
static inline u32 sdca_range(struct sdca_control_range *range,
@ -1451,8 +1462,7 @@ static inline u32 sdca_range_search(struct sdca_control_range *range,
return 0;
}
int sdca_parse_function(struct device *dev, struct sdw_slave *sdw,
struct sdca_function_data *function);
int sdca_parse_function(struct device *dev, struct sdca_function_data *function);
const char *sdca_find_terminal_name(enum sdca_terminal_type type);
@ -1469,5 +1479,7 @@ struct sdca_control_range *sdca_selector_find_range(struct device *dev,
struct sdca_cluster *sdca_id_find_cluster(struct device *dev,
struct sdca_function_data *function,
const int id);
struct sdca_entity *sdca_find_entity_by_label(struct sdca_function_data *function,
const char *entity_label);
#endif

View File

@ -16,18 +16,21 @@ struct sdca_interrupt;
#if IS_ENABLED(CONFIG_SND_SOC_SDCA_HID)
int sdca_add_hid_device(struct device *dev, struct sdw_slave *sdw,
struct sdca_entity *entity);
int sdca_add_hid_device(struct sdca_interrupt *interrupt);
void sdca_destroy_hid_device(struct sdca_interrupt *interrupt);
int sdca_hid_process_report(struct sdca_interrupt *interrupt);
#else
static inline int sdca_add_hid_device(struct device *dev, struct sdw_slave *sdw,
struct sdca_entity *entity)
static inline int sdca_add_hid_device(struct sdca_interrupt *interrupt)
{
return 0;
}
static inline void sdca_destroy_hid_device(struct sdca_interrupt *interrupt)
{
}
static inline int sdca_hid_process_report(struct sdca_interrupt *interrupt)
{
return 0;

View File

@ -46,7 +46,6 @@ struct snd_virmidi_dev {
int client; /* created/attached client */
int port; /* created/attached port */
unsigned int flags; /* SNDRV_VIRMIDI_* */
rwlock_t filelist_lock;
struct rw_semaphore filelist_sem;
struct list_head filelist;
};

View File

@ -181,7 +181,7 @@ void simple_util_canonicalize_platform(struct snd_soc_dai_link_component *platfo
void simple_util_canonicalize_cpu(struct snd_soc_dai_link_component *cpus,
int is_single_links);
void simple_util_clean_reference(struct snd_soc_card *card);
void simple_util_clean_reference(struct simple_util_priv *priv);
void simple_util_parse_convert(struct device_node *np, char *prefix,
struct simple_util_data *data);
@ -189,18 +189,37 @@ bool simple_util_is_convert_required(const struct simple_util_data *data);
int simple_util_get_sample_fmt(struct simple_util_data *data);
int simple_util_parse_routing(struct snd_soc_card *card,
char *prefix);
int simple_util_parse_widgets(struct snd_soc_card *card,
char *prefix);
int simple_util_parse_pin_switches(struct snd_soc_card *card,
char *prefix);
int simple_util_parse_property(struct simple_util_priv *priv,
int (*func)(struct snd_soc_card *card, const char *propname),
char *prefix, char *property);
static inline int simple_util_parse_routing(struct simple_util_priv *priv, char *prefix)
{
return simple_util_parse_property(priv, snd_soc_of_parse_audio_routing,
prefix, "routing");
}
static inline int simple_util_parse_widgets(struct simple_util_priv *priv, char *prefix)
{
return simple_util_parse_property(priv, snd_soc_of_parse_audio_simple_widgets,
prefix, "widgets");
}
static inline int simple_util_parse_pin_switches(struct simple_util_priv *priv, char *prefix)
{
return simple_util_parse_property(priv, snd_soc_of_parse_pin_switches,
prefix, "pin-switches");
}
static inline int simple_util_parse_aux_devs(struct simple_util_priv *priv, char *prefix)
{
return simple_util_parse_property(priv, snd_soc_of_parse_aux_devs,
prefix, "aux-devs");
}
int simple_util_init_jack(struct snd_soc_card *card,
struct simple_util_jack *sjack,
int is_hp, char *prefix, char *pin);
int simple_util_init_aux_jacks(struct simple_util_priv *priv,
char *prefix);
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);

View File

@ -57,7 +57,7 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
#endif
/**
* snd_soc_acpi_mach_params: interface for machine driver configuration
* struct snd_soc_acpi_mach_params - interface for machine driver configuration
*
* @acpi_ipc_irq_index: used for BYT-CR detection
* @platform: string used for HDAudio codec support
@ -93,7 +93,7 @@ struct snd_soc_acpi_mach_params {
};
/**
* snd_soc_acpi_endpoint - endpoint descriptor
* struct snd_soc_acpi_endpoint - endpoint descriptor
* @num: endpoint number (mandatory, unique per device)
* @aggregated: 0 (independent) or 1 (logically grouped)
* @group_position: zero-based order (only when @aggregated is 1)
@ -107,7 +107,7 @@ struct snd_soc_acpi_endpoint {
};
/**
* snd_soc_acpi_adr_device - descriptor for _ADR-enumerated device
* struct snd_soc_acpi_adr_device - descriptor for _ADR-enumerated device
* @adr: 64 bit ACPI _ADR value
* @num_endpoints: number of endpoints for this device
* @endpoints: array of endpoints
@ -121,7 +121,7 @@ struct snd_soc_acpi_adr_device {
};
/**
* snd_soc_acpi_link_adr - ACPI-based list of _ADR enumerated devices
* struct snd_soc_acpi_link_adr - ACPI-based list of _ADR enumerated devices
* @mask: one bit set indicates the link this list applies to
* @num_adr: ARRAY_SIZE of devices
* @adr_d: array of devices
@ -167,8 +167,8 @@ struct snd_soc_acpi_link_adr {
#define SND_SOC_ACPI_TPLG_INTEL_CODEC_NAME BIT(4)
/**
* snd_soc_acpi_mach: ACPI-based machine descriptor. Most of the fields are
* related to the hardware, except for the firmware and topology file names.
* struct snd_soc_acpi_mach - ACPI-based machine descriptor. Most of the fields
* are related to the hardware, except for the firmware and topology file names.
* A platform supported by legacy and Sound Open Firmware (SOF) would expose
* all firmware/topology related fields.
*
@ -192,6 +192,7 @@ struct snd_soc_acpi_link_adr {
* the initial selection in the snd_soc_acpi_mach table.
* @pdata: intended for platform data or machine specific-ops. This structure
* is not constant since this field may be updated at run-time
* @mach_params: machine driver configuration
* @sof_tplg_filename: Sound Open Firmware topology file name, if enabled
* @tplg_quirk_mask: quirks to select different topology files dynamically
* @get_function_tplg_files: This is an optional callback, if specified then instead of
@ -199,11 +200,11 @@ struct snd_soc_acpi_link_adr {
* files to be loaded.
* Return value: The number of the files or negative ERRNO. 0 means that the single topology
* file should be used, no function topology split can be used on the machine.
* @card: the pointer of the card
* @mach: the pointer of the machine driver
* @prefix: the prefix of the topology file name. Typically, it is the path.
* @tplg_files: the pointer of the array of the topology file names.
* @best_effort: ignore non supported links and try to build the card in best effort
* card: the pointer of the card
* mach: the pointer of the machine driver
* prefix: the prefix of the topology file name. Typically, it is the path.
* tplg_files: the pointer of the array of the topology file names.
* best_effort: ignore non supported links and try to build the card in best effort
* with supported links
*/
/* Descriptor for SST ASoC machine driver */

View File

@ -253,6 +253,9 @@ struct snd_soc_component {
void *mark_pm;
struct dentry *debugfs_root;
/* Component private data */
void *priv;
};
#define for_each_component_dais(component, dai)\
@ -283,6 +286,14 @@ static inline int snd_soc_component_cache_sync(
return regcache_sync(component->regmap);
}
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);
void *snd_soc_component_to_priv(struct snd_soc_component *component);
void snd_soc_component_set_aux(struct snd_soc_component *component,
struct snd_soc_aux_dev *aux);
int snd_soc_component_init(struct snd_soc_component *component);

View File

@ -447,15 +447,16 @@ static inline int snd_soc_resume(struct device *dev)
}
#endif
int snd_soc_poweroff(struct device *dev);
int snd_soc_component_initialize(struct snd_soc_component *component,
const struct snd_soc_component_driver *driver,
struct device *dev);
int snd_soc_add_component(struct snd_soc_component *component,
struct snd_soc_dai_driver *dai_drv,
int num_dai);
int snd_soc_register_component(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,
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,
struct snd_soc_dai_driver *dai_drv, int num_dai);

View File

@ -44,6 +44,18 @@
struct asoc_sdw_codec_info;
struct asoc_sdw_mc_private {
struct snd_soc_card card;
struct snd_soc_jack sdw_headset;
struct device *headset_codec_dev; /* only one headset per card */
struct device *amp_dev1, *amp_dev2;
bool append_dai_type;
bool ignore_internal_dmic;
void *private;
unsigned long mc_quirk;
int codec_info_list_count;
};
struct asoc_sdw_dai_info {
const bool direction[2]; /* playback & capture support */
const char *codec_name;
@ -88,25 +100,13 @@ struct asoc_sdw_codec_info {
int (*codec_card_late_probe)(struct snd_soc_card *card);
int (*count_sidecar)(struct snd_soc_card *card,
int (*count_sidecar)(struct asoc_sdw_mc_private *ctx,
int *num_dais, int *num_devs);
int (*add_sidecar)(struct snd_soc_card *card,
struct snd_soc_dai_link **dai_links,
struct snd_soc_codec_conf **codec_conf);
};
struct asoc_sdw_mc_private {
struct snd_soc_card card;
struct snd_soc_jack sdw_headset;
struct device *headset_codec_dev; /* only one headset per card */
struct device *amp_dev1, *amp_dev2;
bool append_dai_type;
bool ignore_internal_dmic;
void *private;
unsigned long mc_quirk;
int codec_info_list_count;
};
struct asoc_sdw_endpoint {
struct list_head list;
@ -182,7 +182,8 @@ struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks
const struct snd_soc_acpi_endpoint *new);
int asoc_sdw_get_dai_type(u32 type);
int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
int asoc_sdw_parse_sdw_endpoints(struct device *dev,
struct asoc_sdw_mc_private *ctx,
struct snd_soc_aux_dev *soc_aux,
struct asoc_sdw_dailink *soc_dais,
struct asoc_sdw_endpoint *soc_ends,
@ -235,7 +236,7 @@ int asoc_sdw_es9356_amp_init(struct snd_soc_card *card,
int asoc_sdw_es9356_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
/* CS AMP support */
int asoc_sdw_bridge_cs35l56_count_sidecar(struct snd_soc_card *card,
int asoc_sdw_bridge_cs35l56_count_sidecar(struct asoc_sdw_mc_private *ctx,
int *num_dais, int *num_devs);
int asoc_sdw_bridge_cs35l56_add_sidecar(struct snd_soc_card *card,
struct snd_soc_dai_link **dai_links,

View File

@ -18,6 +18,7 @@ struct sof_ipc_dai_acp_params {
uint32_t fsync_rate; /* FSYNC frequency in Hz */
uint32_t tdm_slots;
uint32_t tdm_mode;
uint32_t format;
} __packed;
/* ACPDMIC Configuration Request - SOF_IPC_DAI_AMD_CONFIG */

View File

@ -90,6 +90,8 @@ enum sof_ipc_dai_type {
SOF_DAI_AMD_HS_VIRTUAL, /**< AMD ACP HS VIRTUAL */
SOF_DAI_IMX_MICFIL, /** < i.MX MICFIL PDM */
SOF_DAI_AMD_SDW, /**< AMD ACP SDW */
SOF_DAI_INTEL_UAOL, /**< Intel UAOL */
SOF_DAI_AMD_I2S, /**< AMD ACP I2S */
};
/* general purpose DAI configuration */
@ -121,6 +123,7 @@ struct sof_ipc_dai_config {
struct sof_ipc_dai_mtk_afe_params afe;
struct sof_ipc_dai_micfil_params micfil;
struct sof_ipc_dai_acp_sdw_params acp_sdw;
struct sof_ipc_dai_acp_params acp_i2s;
};
} __packed;

View File

@ -179,7 +179,7 @@ struct sof_ipc_compound_hdr {
uint32_t count; /**< count of 0 means end of compound sequence */
} __packed;
/**
/*
* OOPS header architecture specific data.
*/
struct sof_ipc_dsp_oops_arch_hdr {
@ -187,7 +187,7 @@ struct sof_ipc_dsp_oops_arch_hdr {
uint32_t totalsize; /* Total size of oops message */
} __packed;
/**
/*
* OOPS header platform specific data.
*/
struct sof_ipc_dsp_oops_plat_hdr {

View File

@ -187,6 +187,10 @@ enum sof_ipc4_pipeline_state {
#define SOF_IPC4_GLB_PIPE_EXT_CORE_ID_MASK GENMASK(23, 20)
#define SOF_IPC4_GLB_PIPE_EXT_CORE_ID(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_CORE_ID_SHIFT)
#define SOF_IPC4_GLB_PIPE_PAYLOAD_SHIFT 29
#define SOF_IPC4_GLB_PIPE_PAYLOAD_MASK BIT(29)
#define SOF_IPC4_GLB_PIPE_PAYLOAD(x) ((x) << SOF_IPC4_GLB_PIPE_PAYLOAD_SHIFT)
/* pipeline set state ipc msg */
#define SOF_IPC4_GLB_PIPE_STATE_ID_SHIFT 16
#define SOF_IPC4_GLB_PIPE_STATE_ID_MASK GENMASK(23, 16)
@ -536,12 +540,63 @@ enum sof_ipc4_notification_type {
SOF_IPC4_NOTIFY_TYPE_LAST,
};
enum sof_ipc4_resource_type {
SOF_IPC4_MODULE_INSTANCE,
SOF_IPC4_PIPELINE,
SOF_IPC4_GATEWAY,
SOF_IPC4_EDF_TASK,
SOF_IPC4_INVALID_RESOURCE_TYPE,
};
enum sof_ipc4_event_type {
/* Underrun detected by the Mixer */
SOF_IPC4_MIXER_UNDERRUN_DETECTED = 1,
/* Error caught during data processing */
SOF_IPC4_PROCESS_DATA_ERROR = 3,
/* Underrun detected by gateway. */
SOF_IPC4_GATEWAY_UNDERRUN_DETECTED = 6,
/* Overrun detected by gateway */
SOF_IPC4_GATEWAY_OVERRUN_DETECTED,
};
/**
* struct sof_ipc4_process_data_error_event_data - process data error event payload
* @error_code: Error code returned by data processing function
*/
struct sof_ipc4_process_data_error_event_data {
uint32_t error_code;
};
/**
* struct sof_ipc4_mixer_underrun_event_data - mixer underrun event payload
* @eos_flag: Indicates EndOfStream
* @data_mixed: Data processed by module (in bytes)
* @expected_data_mixed: Expected data to be processed (in bytes)
*/
struct sof_ipc4_mixer_underrun_event_data {
uint32_t eos_flag;
uint32_t data_mixed;
uint32_t expected_data_mixed;
};
/**
* union sof_ipc4_resource_event_data - resource event specific payload
* @dws: Raw event data payload as six dwords
* @process_data_error: SOF_IPC4_PROCESS_DATA_ERROR payload
* @mixer_underrun: SOF_IPC4_MIXER_UNDERRUN_DETECTED payload
*/
union sof_ipc4_resource_event_data {
uint32_t dws[6];
struct sof_ipc4_process_data_error_event_data process_data_error;
struct sof_ipc4_mixer_underrun_event_data mixer_underrun;
};
struct sof_ipc4_notify_resource_data {
uint32_t resource_type;
uint32_t resource_id;
uint32_t event_type;
uint32_t reserved;
uint32_t data[6];
union sof_ipc4_resource_event_data data;
} __packed __aligned(4);
#define SOF_IPC4_DEBUG_DESCRIPTOR_SIZE 12 /* 3 x u32 */
@ -654,11 +709,81 @@ enum sof_ipc4_mod_init_ext_obj_id {
SOF_IPC4_MOD_INIT_DATA_ID_MAX = SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA,
};
/* DP module memory configuration data object for ext_init object array */
/* DP module memory configuration data object for object array */
struct sof_ipc4_mod_init_ext_dp_memory_data {
u32 domain_id; /* userspace domain ID */
u32 stack_bytes; /* required stack size in bytes */
u32 heap_bytes; /* required heap size in bytes */
} __packed __aligned(4);
/*
* This set of macros are very similar to the set above, but these are
* for building payload to SOF_IPC4_GLB_CREATE_PIPELINE message.
*
* Macros for creating struct sof_ipc4_glb_pipe_payload payload with
* its associated data. struct sof_ipc4_glb_pipe_payload should be the
* first piece of payload following SOF_IPC4_GLB_CREATE_PIPELINE msg,
* and its existence is indicated with SOF_IPC4_GLB_PIPE_PAYLOAD bit.
*
* The macros below apply to sof_ipc4_glb_pipe_payload.word0
*/
#define SOF_IPC4_GLB_PIPE_PAYLOAD_WORDS_SHIFT 0
#define SOF_IPC4_GLB_PIPE_PAYLOAD_WORDS_MASK GENMASK(23, 0)
#define SOF_IPC4_GLB_PIPE_PAYLOAD_WORDS(x) ((x) << SOF_IPC4_GLB_PIPE_PAYLOAD_WORDS_SHIFT)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY_SHIFT 24
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY_MASK BIT(24)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY_SHIFT)
struct sof_ipc4_glb_pipe_payload {
u32 word0;
u32 rsvd1;
u32 rsvd2;
} __packed __aligned(4);
/*
* SOF_IPC4_GLB_CREATE_PIPELINE payload may be followed by arbitrary
* number of object array objects. SOF_IPC4_GLB_PIPE_EXT_OBJ_ARRAY-bit
* indicates that an array object follows struct
* sof_ipc4_glb_pipe_payload.
*
* The object header's SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST-bit in struct
* sof_ipc4_glb_pipe_ext_object indicates if the array is continued
* with another object. The header has also fields to identify the
* object, SOF_IPC4_GLB_PIPE_EXT_OBJ_ID, and to indicate the object's
* size in 32-bit words, SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS, not
* including the header itself.
*
* The macros below apply to sof_ipc4_glb_pipe_ext_object.header
*/
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST_SHIFT 0
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST_MASK BIT(0)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_OBJ_LAST_SHIFT)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_ID_SHIFT 1
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_ID_MASK GENMASK(15, 1)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_ID(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_OBJ_ID_SHIFT)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS_SHIFT 16
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS_MASK GENMASK(31, 16)
#define SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS(x) ((x) << SOF_IPC4_GLB_PIPE_EXT_OBJ_WORDS_SHIFT)
struct sof_ipc4_glb_pipe_ext_object {
u32 header;
u32 data[];
} __packed __aligned(4);
enum sof_ipc4_glb_pipe_ext_obj_id {
SOF_IPC4_GLB_PIPE_DATA_ID_INVALID = 0,
SOF_IPC4_GLB_PIPE_DATA_ID_MEM_DATA,
SOF_IPC4_GLB_PIPE_DATA_ID_MAX = SOF_IPC4_GLB_PIPE_DATA_ID_MEM_DATA,
};
/* Pipeline memory configuration data object for ext_init object array */
struct sof_ipc4_glb_pipe_ext_obj_memory_data {
u32 domain_id; /* userspace domain ID */
u32 stack_bytes; /* stack size in bytes, 0 means default size */
u32 heap_bytes; /* stack size in bytes, 0 means default size */
u32 stack_bytes; /* stack size in bytes */
u32 heap_bytes; /* heap size in bytes */
} __packed __aligned(4);
/** @}*/

View File

@ -201,6 +201,11 @@ struct tasdevice_rca {
int ncfgs;
struct tasdevice_config_info **cfg_info;
int profile_cfg_id;
/*
* Used among SmartAMP for PDM microphone recording or IV data
* capture.
*/
int capture_profile_id;
/*
* Since version 0x105, the keyword 'init' was introduced into the
* profile, which is used for chip initialization, particularly to
@ -222,7 +227,7 @@ void tasdevice_calbin_remove(void *context);
int tasdevice_select_tuningprm_cfg(void *context, int prm,
int cfg_no, int rca_conf_no);
int tasdevice_prmg_load(void *context, int prm_no);
void tasdevice_tuning_switch(void *context, int state);
void tasdevice_tuning_switch(void *context, int state, bool is_cap);
int tas2781_load_calibration(void *context, char *file_name,
unsigned short i);

View File

@ -1,43 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* tlv320aic32x4.h -- TLV320AIC32X4 Soc Audio driver platform data
*
* Copyright 2011 Vista Silicon S.L.
*
* Author: Javier Martin <javier.martin@vista-silicon.com>
*/
#ifndef _AIC32X4_PDATA_H
#define _AIC32X4_PDATA_H
#define AIC32X4_PWR_MICBIAS_2075_LDOIN 0x00000001
#define AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE 0x00000002
#define AIC32X4_PWR_AIC32X4_LDO_ENABLE 0x00000004
#define AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36 0x00000008
#define AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED 0x00000010
#define AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K 0x00000001
#define AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K 0x00000002
/* GPIO API */
#define AIC32X4_MFPX_DEFAULT_VALUE 0xff
#define AIC32X4_MFP1_DIN_DISABLED 0
#define AIC32X4_MFP1_DIN_ENABLED 0x2
#define AIC32X4_MFP1_GPIO_IN 0x4
#define AIC32X4_MFP2_GPIO_OUT_LOW 0x0
#define AIC32X4_MFP2_GPIO_OUT_HIGH 0x1
#define AIC32X4_MFP_GPIO_ENABLED 0x4
#define AIC32X4_MFP5_GPIO_DISABLED 0x0
#define AIC32X4_MFP5_GPIO_INPUT 0x8
#define AIC32X4_MFP5_GPIO_OUTPUT 0xc
#define AIC32X4_MFP5_GPIO_OUT_LOW 0x0
#define AIC32X4_MFP5_GPIO_OUT_HIGH 0x1
struct aic32x4_setup_data {
unsigned int gpio_func[5];
};
#endif

View File

@ -116,7 +116,7 @@
#define WM8904_DRC_REGS 4
#define WM8904_EQ_REGS 24
/**
/*
* DRC configurations are specified with a label and a set of register
* values to write (the enable bits will be ignored). At runtime an
* enumerated control will be presented for each DRC block allowing
@ -131,7 +131,7 @@ struct wm8904_drc_cfg {
u16 regs[WM8904_DRC_REGS];
};
/**
/*
* ReTune Mobile configurations are specified with a label, sample
* rate and set of values to write (the enable bits will be ignored).
*

View File

@ -308,16 +308,6 @@ struct snd_seq_ump_event {
};
};
/*
* bounce event - stored as variable size data
*/
struct snd_seq_event_bounce {
int err;
struct snd_seq_event event;
/* external data follows here. */
};
/* system information */
struct snd_seq_system_info {
int queues; /* maximum queues count */
@ -348,10 +338,10 @@ struct snd_seq_running_info {
/* client types */
typedef int __bitwise snd_seq_client_type_t;
#define NO_CLIENT ((__force snd_seq_client_type_t) 0)
#define USER_CLIENT ((__force snd_seq_client_type_t) 1)
#define KERNEL_CLIENT ((__force snd_seq_client_type_t) 2)
typedef int snd_seq_client_type_t;
#define NO_CLIENT 0
#define USER_CLIENT 1
#define KERNEL_CLIENT 2
/* event filter flags */
#define SNDRV_SEQ_FILTER_BROADCAST (1U<<0) /* accept broadcast messages */

View File

@ -169,72 +169,72 @@ enum {
SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE,
};
typedef int __bitwise snd_pcm_access_t;
#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ((__force snd_pcm_access_t) 0) /* interleaved mmap */
#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ((__force snd_pcm_access_t) 1) /* noninterleaved mmap */
#define SNDRV_PCM_ACCESS_MMAP_COMPLEX ((__force snd_pcm_access_t) 2) /* complex mmap */
#define SNDRV_PCM_ACCESS_RW_INTERLEAVED ((__force snd_pcm_access_t) 3) /* readi/writei */
#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ((__force snd_pcm_access_t) 4) /* readn/writen */
typedef int snd_pcm_access_t;
#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED 0 /* interleaved mmap */
#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED 1 /* noninterleaved mmap */
#define SNDRV_PCM_ACCESS_MMAP_COMPLEX 2 /* complex mmap */
#define SNDRV_PCM_ACCESS_RW_INTERLEAVED 3 /* readi/writei */
#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED 4 /* readn/writen */
#define SNDRV_PCM_ACCESS_LAST SNDRV_PCM_ACCESS_RW_NONINTERLEAVED
typedef int __bitwise snd_pcm_format_t;
#define SNDRV_PCM_FORMAT_S8 ((__force snd_pcm_format_t) 0)
#define SNDRV_PCM_FORMAT_U8 ((__force snd_pcm_format_t) 1)
#define SNDRV_PCM_FORMAT_S16_LE ((__force snd_pcm_format_t) 2)
#define SNDRV_PCM_FORMAT_S16_BE ((__force snd_pcm_format_t) 3)
#define SNDRV_PCM_FORMAT_U16_LE ((__force snd_pcm_format_t) 4)
#define SNDRV_PCM_FORMAT_U16_BE ((__force snd_pcm_format_t) 5)
#define SNDRV_PCM_FORMAT_S24_LE ((__force snd_pcm_format_t) 6) /* low three bytes */
#define SNDRV_PCM_FORMAT_S24_BE ((__force snd_pcm_format_t) 7) /* low three bytes */
#define SNDRV_PCM_FORMAT_U24_LE ((__force snd_pcm_format_t) 8) /* low three bytes */
#define SNDRV_PCM_FORMAT_U24_BE ((__force snd_pcm_format_t) 9) /* low three bytes */
typedef int snd_pcm_format_t;
#define SNDRV_PCM_FORMAT_S8 0
#define SNDRV_PCM_FORMAT_U8 1
#define SNDRV_PCM_FORMAT_S16_LE 2
#define SNDRV_PCM_FORMAT_S16_BE 3
#define SNDRV_PCM_FORMAT_U16_LE 4
#define SNDRV_PCM_FORMAT_U16_BE 5
#define SNDRV_PCM_FORMAT_S24_LE 6 /* low three bytes */
#define SNDRV_PCM_FORMAT_S24_BE 7 /* low three bytes */
#define SNDRV_PCM_FORMAT_U24_LE 8 /* low three bytes */
#define SNDRV_PCM_FORMAT_U24_BE 9 /* low three bytes */
/*
* For S32/U32 formats, 'msbits' hardware parameter is often used to deliver information about the
* available bit count in most significant bit. It's for the case of so-called 'left-justified' or
* `right-padding` sample which has less width than 32 bit.
*/
#define SNDRV_PCM_FORMAT_S32_LE ((__force snd_pcm_format_t) 10)
#define SNDRV_PCM_FORMAT_S32_BE ((__force snd_pcm_format_t) 11)
#define SNDRV_PCM_FORMAT_U32_LE ((__force snd_pcm_format_t) 12)
#define SNDRV_PCM_FORMAT_U32_BE ((__force snd_pcm_format_t) 13)
#define SNDRV_PCM_FORMAT_FLOAT_LE ((__force snd_pcm_format_t) 14) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
#define SNDRV_PCM_FORMAT_FLOAT_BE ((__force snd_pcm_format_t) 15) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
#define SNDRV_PCM_FORMAT_FLOAT64_LE ((__force snd_pcm_format_t) 16) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
#define SNDRV_PCM_FORMAT_FLOAT64_BE ((__force snd_pcm_format_t) 17) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((__force snd_pcm_format_t) 18) /* IEC-958 subframe, Little Endian */
#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((__force snd_pcm_format_t) 19) /* IEC-958 subframe, Big Endian */
#define SNDRV_PCM_FORMAT_MU_LAW ((__force snd_pcm_format_t) 20)
#define SNDRV_PCM_FORMAT_A_LAW ((__force snd_pcm_format_t) 21)
#define SNDRV_PCM_FORMAT_IMA_ADPCM ((__force snd_pcm_format_t) 22)
#define SNDRV_PCM_FORMAT_MPEG ((__force snd_pcm_format_t) 23)
#define SNDRV_PCM_FORMAT_GSM ((__force snd_pcm_format_t) 24)
#define SNDRV_PCM_FORMAT_S20_LE ((__force snd_pcm_format_t) 25) /* in four bytes, LSB justified */
#define SNDRV_PCM_FORMAT_S20_BE ((__force snd_pcm_format_t) 26) /* in four bytes, LSB justified */
#define SNDRV_PCM_FORMAT_U20_LE ((__force snd_pcm_format_t) 27) /* in four bytes, LSB justified */
#define SNDRV_PCM_FORMAT_U20_BE ((__force snd_pcm_format_t) 28) /* in four bytes, LSB justified */
#define SNDRV_PCM_FORMAT_S32_LE 10
#define SNDRV_PCM_FORMAT_S32_BE 11
#define SNDRV_PCM_FORMAT_U32_LE 12
#define SNDRV_PCM_FORMAT_U32_BE 13
#define SNDRV_PCM_FORMAT_FLOAT_LE 14 /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
#define SNDRV_PCM_FORMAT_FLOAT_BE 15 /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
#define SNDRV_PCM_FORMAT_FLOAT64_LE 16 /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
#define SNDRV_PCM_FORMAT_FLOAT64_BE 17 /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE 18 /* IEC-958 subframe, Little Endian */
#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE 19 /* IEC-958 subframe, Big Endian */
#define SNDRV_PCM_FORMAT_MU_LAW 20
#define SNDRV_PCM_FORMAT_A_LAW 21
#define SNDRV_PCM_FORMAT_IMA_ADPCM 22
#define SNDRV_PCM_FORMAT_MPEG 23
#define SNDRV_PCM_FORMAT_GSM 24
#define SNDRV_PCM_FORMAT_S20_LE 25 /* in four bytes, LSB justified */
#define SNDRV_PCM_FORMAT_S20_BE 26 /* in four bytes, LSB justified */
#define SNDRV_PCM_FORMAT_U20_LE 27 /* in four bytes, LSB justified */
#define SNDRV_PCM_FORMAT_U20_BE 28 /* in four bytes, LSB justified */
/* gap in the numbering for a future standard linear format */
#define SNDRV_PCM_FORMAT_SPECIAL ((__force snd_pcm_format_t) 31)
#define SNDRV_PCM_FORMAT_S24_3LE ((__force snd_pcm_format_t) 32) /* in three bytes */
#define SNDRV_PCM_FORMAT_S24_3BE ((__force snd_pcm_format_t) 33) /* in three bytes */
#define SNDRV_PCM_FORMAT_U24_3LE ((__force snd_pcm_format_t) 34) /* in three bytes */
#define SNDRV_PCM_FORMAT_U24_3BE ((__force snd_pcm_format_t) 35) /* in three bytes */
#define SNDRV_PCM_FORMAT_S20_3LE ((__force snd_pcm_format_t) 36) /* in three bytes */
#define SNDRV_PCM_FORMAT_S20_3BE ((__force snd_pcm_format_t) 37) /* in three bytes */
#define SNDRV_PCM_FORMAT_U20_3LE ((__force snd_pcm_format_t) 38) /* in three bytes */
#define SNDRV_PCM_FORMAT_U20_3BE ((__force snd_pcm_format_t) 39) /* in three bytes */
#define SNDRV_PCM_FORMAT_S18_3LE ((__force snd_pcm_format_t) 40) /* in three bytes */
#define SNDRV_PCM_FORMAT_S18_3BE ((__force snd_pcm_format_t) 41) /* in three bytes */
#define SNDRV_PCM_FORMAT_U18_3LE ((__force snd_pcm_format_t) 42) /* in three bytes */
#define SNDRV_PCM_FORMAT_U18_3BE ((__force snd_pcm_format_t) 43) /* in three bytes */
#define SNDRV_PCM_FORMAT_G723_24 ((__force snd_pcm_format_t) 44) /* 8 samples in 3 bytes */
#define SNDRV_PCM_FORMAT_G723_24_1B ((__force snd_pcm_format_t) 45) /* 1 sample in 1 byte */
#define SNDRV_PCM_FORMAT_G723_40 ((__force snd_pcm_format_t) 46) /* 8 Samples in 5 bytes */
#define SNDRV_PCM_FORMAT_G723_40_1B ((__force snd_pcm_format_t) 47) /* 1 sample in 1 byte */
#define SNDRV_PCM_FORMAT_DSD_U8 ((__force snd_pcm_format_t) 48) /* DSD, 1-byte samples DSD (x8) */
#define SNDRV_PCM_FORMAT_DSD_U16_LE ((__force snd_pcm_format_t) 49) /* DSD, 2-byte samples DSD (x16), little endian */
#define SNDRV_PCM_FORMAT_DSD_U32_LE ((__force snd_pcm_format_t) 50) /* DSD, 4-byte samples DSD (x32), little endian */
#define SNDRV_PCM_FORMAT_DSD_U16_BE ((__force snd_pcm_format_t) 51) /* DSD, 2-byte samples DSD (x16), big endian */
#define SNDRV_PCM_FORMAT_DSD_U32_BE ((__force snd_pcm_format_t) 52) /* DSD, 4-byte samples DSD (x32), big endian */
#define SNDRV_PCM_FORMAT_SPECIAL 31
#define SNDRV_PCM_FORMAT_S24_3LE 32 /* in three bytes */
#define SNDRV_PCM_FORMAT_S24_3BE 33 /* in three bytes */
#define SNDRV_PCM_FORMAT_U24_3LE 34 /* in three bytes */
#define SNDRV_PCM_FORMAT_U24_3BE 35 /* in three bytes */
#define SNDRV_PCM_FORMAT_S20_3LE 36 /* in three bytes */
#define SNDRV_PCM_FORMAT_S20_3BE 37 /* in three bytes */
#define SNDRV_PCM_FORMAT_U20_3LE 38 /* in three bytes */
#define SNDRV_PCM_FORMAT_U20_3BE 39 /* in three bytes */
#define SNDRV_PCM_FORMAT_S18_3LE 40 /* in three bytes */
#define SNDRV_PCM_FORMAT_S18_3BE 41 /* in three bytes */
#define SNDRV_PCM_FORMAT_U18_3LE 42 /* in three bytes */
#define SNDRV_PCM_FORMAT_U18_3BE 43 /* in three bytes */
#define SNDRV_PCM_FORMAT_G723_24 44 /* 8 samples in 3 bytes */
#define SNDRV_PCM_FORMAT_G723_24_1B 45 /* 1 sample in 1 byte */
#define SNDRV_PCM_FORMAT_G723_40 46 /* 8 Samples in 5 bytes */
#define SNDRV_PCM_FORMAT_G723_40_1B 47 /* 1 sample in 1 byte */
#define SNDRV_PCM_FORMAT_DSD_U8 48 /* DSD, 1-byte samples DSD (x8) */
#define SNDRV_PCM_FORMAT_DSD_U16_LE 49 /* DSD, 2-byte samples DSD (x16), little endian */
#define SNDRV_PCM_FORMAT_DSD_U32_LE 50 /* DSD, 4-byte samples DSD (x32), little endian */
#define SNDRV_PCM_FORMAT_DSD_U16_BE 51 /* DSD, 2-byte samples DSD (x16), big endian */
#define SNDRV_PCM_FORMAT_DSD_U32_BE 52 /* DSD, 4-byte samples DSD (x32), big endian */
#define SNDRV_PCM_FORMAT_LAST SNDRV_PCM_FORMAT_DSD_U32_BE
#define SNDRV_PCM_FORMAT_FIRST SNDRV_PCM_FORMAT_S8
@ -265,11 +265,11 @@ typedef int __bitwise snd_pcm_format_t;
#define SNDRV_PCM_FORMAT_U20 SNDRV_PCM_FORMAT_U20_BE
#endif
typedef int __bitwise snd_pcm_subformat_t;
#define SNDRV_PCM_SUBFORMAT_STD ((__force snd_pcm_subformat_t) 0)
#define SNDRV_PCM_SUBFORMAT_MSBITS_MAX ((__force snd_pcm_subformat_t) 1)
#define SNDRV_PCM_SUBFORMAT_MSBITS_20 ((__force snd_pcm_subformat_t) 2)
#define SNDRV_PCM_SUBFORMAT_MSBITS_24 ((__force snd_pcm_subformat_t) 3)
typedef int snd_pcm_subformat_t;
#define SNDRV_PCM_SUBFORMAT_STD 0
#define SNDRV_PCM_SUBFORMAT_MSBITS_MAX 1
#define SNDRV_PCM_SUBFORMAT_MSBITS_20 2
#define SNDRV_PCM_SUBFORMAT_MSBITS_24 3
#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_MSBITS_24
#define SNDRV_PCM_INFO_MMAP 0x00000001 /* hardware supports mmap */
@ -303,16 +303,16 @@ typedef int __bitwise snd_pcm_subformat_t;
#define __SND_STRUCT_TIME64
#endif
typedef int __bitwise snd_pcm_state_t;
#define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0) /* stream is open */
#define SNDRV_PCM_STATE_SETUP ((__force snd_pcm_state_t) 1) /* stream has a setup */
#define SNDRV_PCM_STATE_PREPARED ((__force snd_pcm_state_t) 2) /* stream is ready to start */
#define SNDRV_PCM_STATE_RUNNING ((__force snd_pcm_state_t) 3) /* stream is running */
#define SNDRV_PCM_STATE_XRUN ((__force snd_pcm_state_t) 4) /* stream reached an xrun */
#define SNDRV_PCM_STATE_DRAINING ((__force snd_pcm_state_t) 5) /* stream is draining */
#define SNDRV_PCM_STATE_PAUSED ((__force snd_pcm_state_t) 6) /* stream is paused */
#define SNDRV_PCM_STATE_SUSPENDED ((__force snd_pcm_state_t) 7) /* hardware is suspended */
#define SNDRV_PCM_STATE_DISCONNECTED ((__force snd_pcm_state_t) 8) /* hardware is disconnected */
typedef int snd_pcm_state_t;
#define SNDRV_PCM_STATE_OPEN 0 /* stream is open */
#define SNDRV_PCM_STATE_SETUP 1 /* stream has a setup */
#define SNDRV_PCM_STATE_PREPARED 2 /* stream is ready to start */
#define SNDRV_PCM_STATE_RUNNING 3 /* stream is running */
#define SNDRV_PCM_STATE_XRUN 4 /* stream reached an xrun */
#define SNDRV_PCM_STATE_DRAINING 5 /* stream is draining */
#define SNDRV_PCM_STATE_PAUSED 6 /* stream is paused */
#define SNDRV_PCM_STATE_SUSPENDED 7 /* hardware is suspended */
#define SNDRV_PCM_STATE_DISCONNECTED 8 /* hardware is disconnected */
#define SNDRV_PCM_STATE_LAST SNDRV_PCM_STATE_DISCONNECTED
enum {
@ -1058,7 +1058,7 @@ struct snd_timer_tread {
* *
****************************************************************************/
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 9)
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 10)
struct snd_ctl_card_info {
int card; /* card number */
@ -1072,24 +1072,43 @@ struct snd_ctl_card_info {
unsigned char components[128]; /* card components / fine identification, delimited with one space (AC97 etc..) */
};
typedef int __bitwise snd_ctl_elem_type_t;
#define SNDRV_CTL_ELEM_TYPE_NONE ((__force snd_ctl_elem_type_t) 0) /* invalid */
#define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1) /* boolean type */
#define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2) /* integer type */
#define SNDRV_CTL_ELEM_TYPE_ENUMERATED ((__force snd_ctl_elem_type_t) 3) /* enumerated type */
#define SNDRV_CTL_ELEM_TYPE_BYTES ((__force snd_ctl_elem_type_t) 4) /* byte array */
#define SNDRV_CTL_ELEM_TYPE_IEC958 ((__force snd_ctl_elem_type_t) 5) /* IEC958 (S/PDIF) setup */
#define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6) /* 64-bit integer type */
/*
* Card components can exceed the fixed 128 bytes in snd_ctl_card_info.
* Use SNDRV_CTL_IOCTL_CARD_BYTES with type SND_CTL_CARD_BTYPE_COMPONENTS
* to retrieve the full string.
*/
/* Type values for struct snd_ctl_card_bytes::type */
enum {
SND_CTL_CARD_BTYPE_COMPONENTS = 1, /* full card components string */
};
struct snd_ctl_card_bytes {
__u32 type; /* SND_CTL_CARD_BTYPE_* */
__u32 data_allocated; /* size of @data buffer in bytes */
__u32 data_len; /* in/out: actual data length in bytes */
__u32 reserved; /* explicit pad */
__u64 data; /* user buffer (pointer stored as __u64) */
};
typedef int snd_ctl_elem_type_t;
#define SNDRV_CTL_ELEM_TYPE_NONE 0 /* invalid */
#define SNDRV_CTL_ELEM_TYPE_BOOLEAN 1 /* boolean type */
#define SNDRV_CTL_ELEM_TYPE_INTEGER 2 /* integer type */
#define SNDRV_CTL_ELEM_TYPE_ENUMERATED 3 /* enumerated type */
#define SNDRV_CTL_ELEM_TYPE_BYTES 4 /* byte array */
#define SNDRV_CTL_ELEM_TYPE_IEC958 5 /* IEC958 (S/PDIF) setup */
#define SNDRV_CTL_ELEM_TYPE_INTEGER64 6 /* 64-bit integer type */
#define SNDRV_CTL_ELEM_TYPE_LAST SNDRV_CTL_ELEM_TYPE_INTEGER64
typedef int __bitwise snd_ctl_elem_iface_t;
#define SNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0) /* global control */
#define SNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1) /* hardware dependent device */
#define SNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2) /* virtual mixer device */
#define SNDRV_CTL_ELEM_IFACE_PCM ((__force snd_ctl_elem_iface_t) 3) /* PCM device */
#define SNDRV_CTL_ELEM_IFACE_RAWMIDI ((__force snd_ctl_elem_iface_t) 4) /* RawMidi device */
#define SNDRV_CTL_ELEM_IFACE_TIMER ((__force snd_ctl_elem_iface_t) 5) /* timer device */
#define SNDRV_CTL_ELEM_IFACE_SEQUENCER ((__force snd_ctl_elem_iface_t) 6) /* sequencer client */
typedef int snd_ctl_elem_iface_t;
#define SNDRV_CTL_ELEM_IFACE_CARD 0 /* global control */
#define SNDRV_CTL_ELEM_IFACE_HWDEP 1 /* hardware dependent device */
#define SNDRV_CTL_ELEM_IFACE_MIXER 2 /* virtual mixer device */
#define SNDRV_CTL_ELEM_IFACE_PCM 3 /* PCM device */
#define SNDRV_CTL_ELEM_IFACE_RAWMIDI 4 /* RawMidi device */
#define SNDRV_CTL_ELEM_IFACE_TIMER 5 /* timer device */
#define SNDRV_CTL_ELEM_IFACE_SEQUENCER 6 /* sequencer client */
#define SNDRV_CTL_ELEM_IFACE_LAST SNDRV_CTL_ELEM_IFACE_SEQUENCER
#define SNDRV_CTL_ELEM_ACCESS_READ (1<<0)
@ -1198,6 +1217,7 @@ struct snd_ctl_tlv {
#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct snd_ctl_card_info)
#define SNDRV_CTL_IOCTL_CARD_BYTES _IOWR('U', 0x02, struct snd_ctl_card_bytes)
#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct snd_ctl_elem_list)
#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct snd_ctl_elem_info)
#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct snd_ctl_elem_value)

View File

@ -79,11 +79,12 @@ struct snd_firewire_event_motu_register_dsp_change {
*
* @type: Fixed to SNDRV_FIREWIRE_EVENT_FF400_MESSAGE.
* @message_count: The number of messages.
* @messages: Array of @message_count messages
* @messages.message: The messages expressing hardware knob operation.
* @messages.tstamp: The isochronous cycle at which the request subaction of asynchronous
* transaction was sent to deliver the message. It has 16 bit unsigned integer
* transaction was sent to deliver the message. It has 16-bit unsigned integer
* value. The higher 3 bits of value expresses the lower three bits of second
* field in the format of CYCLE_TIME, up to 7. The rest 13 bits expresses cycle
* field in the format of CYCLE_TIME, up to 7. The remaining 13 bits express cycle
* field up to 7999.
*
* The structure expresses message transmitted by Fireface 400 when operating hardware knob.
@ -191,8 +192,9 @@ struct snd_firewire_motu_register_dsp_meter {
#define SNDRV_FIREWIRE_MOTU_REGISTER_DSP_ALIGNED_INPUT_COUNT (SNDRV_FIREWIRE_MOTU_REGISTER_DSP_INPUT_COUNT + 2)
/**
* snd_firewire_motu_register_dsp_parameter - the container for parameters of DSP controlled
* by register access.
* struct snd_firewire_motu_register_dsp_parameter - the container for parameters
* of DSP controlled by register access.
* @mixer: aggregate of @mixer.source and @mixer.output
* @mixer.source.gain: The gain of source to mixer.
* @mixer.source.pan: The L/R balance of source to mixer.
* @mixer.source.flag: The flag of source to mixer, including mute, solo.
@ -200,21 +202,25 @@ struct snd_firewire_motu_register_dsp_meter {
* Audio Express.
* @mixer.source.paired_width: The width of paired source to mixer, only for 4 pre and
* Audio Express.
* @mixer.output: FIXME
* @mixer.output.paired_volume: The volume of paired output from mixer.
* @mixer.output.paired_flag: The flag of paired output from mixer.
* @output: output parameters
* @output.main_paired_volume: The volume of paired main output.
* @output.hp_paired_volume: The volume of paired hp output.
* @output.hp_paired_assignment: The source assigned to paired hp output.
* @output.reserved: Padding for 32 bit alignment for future extension.
* @output.reserved: Padding for 32-bit alignment for future extension.
* @line_input: line input parameters
* @line_input.boost_flag: The flags of boost for line inputs, only for 828mk2 and Traveler.
* @line_input.nominal_level_flag: The flags of nominal level for line inputs, only for 828mk2 and
* Traveler.
* @line_input.reserved: Padding for 32 bit alignment for future extension.
* @line_input.reserved: Padding for 32-bit alignment for future extension.
* @input: input parameters
* @input.gain_and_invert: The value including gain and invert for input, only for Ultralite, 4 pre
* and Audio Express.
* @input.flag: The flag of input; e.g. jack detection, phantom power, and pad, only for Ultralite,
* 4 pre and Audio express.
* @reserved: Padding so that the size of structure is kept to 512 byte, but for future extension.
* @reserved: Padding so that the size of structure is kept to 512 bytes, but for future extension.
*
* The structure expresses the set of parameters for DSP controlled by register access.
*/
@ -272,8 +278,8 @@ struct snd_firewire_motu_register_dsp_parameter {
* controlled by command
* @data: Signal level meters. The mapping between position and signal channel is model-dependent.
*
* The structure expresses the part of DSP status for hardware meter. The 32 bit storage is
* estimated to include IEEE 764 32 bit single precision floating point (binary32) value. It is
* The structure expresses the part of DSP status for hardware meter. The 32-bit storage is
* estimated to include IEEE 764 32-bit single precision floating point (binary32) value. It is
* expected to be linear value (not logarithm) for audio signal level between 0.0 and +1.0.
*/
struct snd_firewire_motu_command_dsp_meter {

View File

@ -1,168 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* skl-tplg-interface.h - Intel DSP FW private data interface
*
* Copyright (C) 2015 Intel Corp
* Author: Jeeja KP <jeeja.kp@intel.com>
* Nilofer, Samreen <samreen.nilofer@intel.com>
*/
#ifndef __HDA_TPLG_INTERFACE_H__
#define __HDA_TPLG_INTERFACE_H__
#include <linux/types.h>
/*
* Default types range from 0~12. type can range from 0 to 0xff
* SST types start at higher to avoid any overlapping in future
*/
#define SKL_CONTROL_TYPE_BYTE_TLV 0x100
#define SKL_CONTROL_TYPE_MIC_SELECT 0x102
#define SKL_CONTROL_TYPE_MULTI_IO_SELECT 0x103
#define SKL_CONTROL_TYPE_MULTI_IO_SELECT_DMIC 0x104
#define HDA_SST_CFG_MAX 900 /* size of copier cfg*/
#define MAX_IN_QUEUE 8
#define MAX_OUT_QUEUE 8
#define SKL_UUID_STR_SZ 40
/* Event types goes here */
/* Reserve event type 0 for no event handlers */
enum skl_event_types {
SKL_EVENT_NONE = 0,
SKL_MIXER_EVENT,
SKL_MUX_EVENT,
SKL_VMIXER_EVENT,
SKL_PGA_EVENT
};
/**
* enum skl_ch_cfg - channel configuration
*
* @SKL_CH_CFG_MONO: One channel only
* @SKL_CH_CFG_STEREO: L & R
* @SKL_CH_CFG_2_1: L, R & LFE
* @SKL_CH_CFG_3_0: L, C & R
* @SKL_CH_CFG_3_1: L, C, R & LFE
* @SKL_CH_CFG_QUATRO: L, R, Ls & Rs
* @SKL_CH_CFG_4_0: L, C, R & Cs
* @SKL_CH_CFG_5_0: L, C, R, Ls & Rs
* @SKL_CH_CFG_5_1: L, C, R, Ls, Rs & LFE
* @SKL_CH_CFG_DUAL_MONO: One channel replicated in two
* @SKL_CH_CFG_I2S_DUAL_STEREO_0: Stereo(L,R) in 4 slots, 1st stream:[ L, R, -, - ]
* @SKL_CH_CFG_I2S_DUAL_STEREO_1: Stereo(L,R) in 4 slots, 2nd stream:[ -, -, L, R ]
* @SKL_CH_CFG_INVALID: Invalid
*/
enum skl_ch_cfg {
SKL_CH_CFG_MONO = 0,
SKL_CH_CFG_STEREO = 1,
SKL_CH_CFG_2_1 = 2,
SKL_CH_CFG_3_0 = 3,
SKL_CH_CFG_3_1 = 4,
SKL_CH_CFG_QUATRO = 5,
SKL_CH_CFG_4_0 = 6,
SKL_CH_CFG_5_0 = 7,
SKL_CH_CFG_5_1 = 8,
SKL_CH_CFG_DUAL_MONO = 9,
SKL_CH_CFG_I2S_DUAL_STEREO_0 = 10,
SKL_CH_CFG_I2S_DUAL_STEREO_1 = 11,
SKL_CH_CFG_7_1 = 12,
SKL_CH_CFG_4_CHANNEL = SKL_CH_CFG_7_1,
SKL_CH_CFG_INVALID
};
enum skl_module_type {
SKL_MODULE_TYPE_MIXER = 0,
SKL_MODULE_TYPE_COPIER,
SKL_MODULE_TYPE_UPDWMIX,
SKL_MODULE_TYPE_SRCINT,
SKL_MODULE_TYPE_ALGO,
SKL_MODULE_TYPE_BASE_OUTFMT,
SKL_MODULE_TYPE_KPB,
SKL_MODULE_TYPE_MIC_SELECT,
};
enum skl_core_affinity {
SKL_AFFINITY_CORE_0 = 0,
SKL_AFFINITY_CORE_1,
SKL_AFFINITY_CORE_MAX
};
enum skl_pipe_conn_type {
SKL_PIPE_CONN_TYPE_NONE = 0,
SKL_PIPE_CONN_TYPE_FE,
SKL_PIPE_CONN_TYPE_BE
};
enum skl_hw_conn_type {
SKL_CONN_NONE = 0,
SKL_CONN_SOURCE = 1,
SKL_CONN_SINK = 2
};
enum skl_dev_type {
SKL_DEVICE_BT = 0x0,
SKL_DEVICE_DMIC = 0x1,
SKL_DEVICE_I2S = 0x2,
SKL_DEVICE_SLIMBUS = 0x3,
SKL_DEVICE_HDALINK = 0x4,
SKL_DEVICE_HDAHOST = 0x5,
SKL_DEVICE_NONE
};
/**
* enum skl_interleaving - interleaving style
*
* @SKL_INTERLEAVING_PER_CHANNEL: [s1_ch1...s1_chN,...,sM_ch1...sM_chN]
* @SKL_INTERLEAVING_PER_SAMPLE: [s1_ch1...sM_ch1,...,s1_chN...sM_chN]
*/
enum skl_interleaving {
SKL_INTERLEAVING_PER_CHANNEL = 0,
SKL_INTERLEAVING_PER_SAMPLE = 1,
};
enum skl_sample_type {
SKL_SAMPLE_TYPE_INT_MSB = 0,
SKL_SAMPLE_TYPE_INT_LSB = 1,
SKL_SAMPLE_TYPE_INT_SIGNED = 2,
SKL_SAMPLE_TYPE_INT_UNSIGNED = 3,
SKL_SAMPLE_TYPE_FLOAT = 4
};
enum module_pin_type {
/* All pins of the module takes same PCM inputs or outputs
* e.g. mixout
*/
SKL_PIN_TYPE_HOMOGENEOUS,
/* All pins of the module takes different PCM inputs or outputs
* e.g mux
*/
SKL_PIN_TYPE_HETEROGENEOUS,
};
enum skl_module_param_type {
SKL_PARAM_DEFAULT = 0,
SKL_PARAM_INIT,
SKL_PARAM_SET,
SKL_PARAM_BIND
};
struct skl_dfw_algo_data {
__u32 set_params:2;
__u32 rsvd:30;
__u32 param_id;
__u32 max;
char params[];
} __packed;
enum skl_tkn_dir {
SKL_DIR_IN,
SKL_DIR_OUT
};
enum skl_tuple_type {
SKL_TYPE_TUPLE,
SKL_TYPE_DATA
};
#endif

View File

@ -58,7 +58,7 @@ enum ar_event_types {
#define SND_SOC_AR_TPLG_FE_BE_GRAPH_CTL_MIX 256
#define SND_SOC_AR_TPLG_VOL_CTL 257
/**
/*
* %AR_TKN_U32_SUB_GRAPH_INSTANCE_ID: Sub Graph Instance Id
*
* %AR_TKN_U32_SUB_GRAPH_PERF_MODE: Performance mode of subgraph
@ -168,6 +168,60 @@ enum ar_event_types {
* LOG_WAIT = 0,
* LOG_IMMEDIATELY = 1
*
* %AR_TKN_U16_MODULE_SYNC_SRC: Frame sync source
* AR_AUDIO_IF_SYNC_SRC_EXTERNAL = 0,
* AR_AUDIO_IF_SYNC_SRC_INTERNAL = 1
*
* %AR_TKN_U16_MODULE_CTRL_DATA_OUT_ENABLE: Enable data-out tri-state control
* AR_AUDIO_IF_CTRL_DATA_OE_DISABLE = 0,
* AR_AUDIO_IF_CTRL_DATA_OE_ENABLE = 1
*
* %AR_TKN_U32_MODULE_SLOT_MASK: Active TDM slot bitmask
*
* %AR_TKN_U16_MODULE_NSLOTS_PER_FRAME: Number of slots per TDM frame
*
* %AR_TKN_U16_MODULE_SLOT_WIDTH: Slot width in bits (16 or 32)
*
* %AR_TKN_U16_MODULE_SYNC_MODE: Frame sync mode
* AR_AUDIO_IF_FRAME_SYNC_MODE_SHORT = 0,
* AR_AUDIO_IF_FRAME_SYNC_MODE_ONE_SLOT = 1,
* AR_AUDIO_IF_FRAME_SYNC_MODE_LONG = 2
*
* %AR_TKN_U16_MODULE_CTRL_INVERT_SYNC_PULSE: Invert frame sync pulse polarity
* AR_AUDIO_IF_SYNC_NORMAL = 0,
* AR_AUDIO_IF_SYNC_INVERTED = 1
*
* %AR_TKN_U16_MODULE_CTRL_SYNC_DATA_DELAY: Data delay relative to frame sync
* AR_AUDIO_IF_DATA_DELAY_NONE = 0,
* AR_AUDIO_IF_DATA_DELAY_1_CYCLE = 1,
* AR_AUDIO_IF_DATA_DELAY_2_CYCLE = 2
*
* %AR_TKN_U16_MODULE_INTF_MODE: Audio IF interface mode
* AR_AUDIO_IF_INTF_MODE_TDM = 0,
* AR_AUDIO_IF_INTF_MODE_PCM = 1,
* AR_AUDIO_IF_INTF_MODE_I2S = 2
*
* %AR_TKN_U16_MODULE_QAIF_TYPE: QAIF hardware port type index
* AR_AUDIO_IF_QAIF = 0,
* AR_AUDIO_IF_QAIF_VA = 1
*
* %AR_TKN_U32_MODULE_ACTIVE_LANE_MASK: Active lane bitmask for multi-lane
*
* %AR_TKN_U32_MODULE_FRAME_SYNC_RATE: Frame sync rate in Hz
*
* %AR_TKN_U16_MODULE_BIT_CLK_TYPE: Bit clock type
* AR_AUDIO_IF_BIT_CLK_INTERNAL = 0,
* AR_AUDIO_IF_BIT_CLK_EXTERNAL = 1,
* AR_AUDIO_IF_BIT_CLK_SKIP = 2
*
* %AR_TKN_U8_MODULE_INV_INT_BIT_CLK: Invert internal bit clock
* AR_AUDIO_IF_CLK_NORMAL = 0,
* AR_AUDIO_IF_CLK_INVERTED = 1
*
* %AR_TKN_U8_MODULE_INV_EXT_BIT_CLK: Invert external bit clock
* AR_AUDIO_IF_CLK_NORMAL = 0,
* AR_AUDIO_IF_CLK_INVERTED = 1
*
* %AR_TKN_DAI_INDEX: dai index
*
*/
@ -240,6 +294,45 @@ enum ar_event_types {
#define AR_TKN_U32_MODULE_LOG_TAP_POINT_ID 260
#define AR_TKN_U32_MODULE_LOG_MODE 261
#define AR_TKN_U16_MODULE_SYNC_SRC 262
#define AR_TKN_U16_MODULE_CTRL_DATA_OUT_ENABLE 263
#define AR_TKN_U32_MODULE_SLOT_MASK 264
#define AR_TKN_U16_MODULE_NSLOTS_PER_FRAME 265
#define AR_TKN_U16_MODULE_SLOT_WIDTH 266
#define AR_TKN_U16_MODULE_SYNC_MODE 267
#define AR_TKN_U16_MODULE_CTRL_INVERT_SYNC_PULSE 268
#define AR_TKN_U16_MODULE_CTRL_SYNC_DATA_DELAY 269
#define AR_TKN_U16_MODULE_INTF_MODE 270
#define AR_TKN_U16_MODULE_QAIF_TYPE 271
#define AR_TKN_U32_MODULE_ACTIVE_LANE_MASK 272
#define AR_TKN_U32_MODULE_FRAME_SYNC_RATE 273
#define AR_TKN_U16_MODULE_BIT_CLK_TYPE 274
#define AR_TKN_U8_MODULE_INV_INT_BIT_CLK 275
#define AR_TKN_U8_MODULE_INV_EXT_BIT_CLK 276
#define AR_AUDIO_IF_SYNC_SRC_EXTERNAL 0
#define AR_AUDIO_IF_SYNC_SRC_INTERNAL 1
#define AR_AUDIO_IF_CTRL_DATA_OE_DISABLE 0
#define AR_AUDIO_IF_CTRL_DATA_OE_ENABLE 1
#define AR_AUDIO_IF_INTF_MODE_TDM 0
#define AR_AUDIO_IF_INTF_MODE_PCM 1
#define AR_AUDIO_IF_INTF_MODE_I2S 2
#define AR_AUDIO_IF_QAIF 0
#define AR_AUDIO_IF_QAIF_VA 1
#define AR_AUDIO_IF_FRAME_SYNC_MODE_SHORT 0
#define AR_AUDIO_IF_FRAME_SYNC_MODE_ONE_SLOT 1
#define AR_AUDIO_IF_FRAME_SYNC_MODE_LONG 2
#define AR_AUDIO_IF_SYNC_NORMAL 0
#define AR_AUDIO_IF_SYNC_INVERTED 1
#define AR_AUDIO_IF_DATA_DELAY_NONE 0
#define AR_AUDIO_IF_DATA_DELAY_1_CYCLE 1
#define AR_AUDIO_IF_DATA_DELAY_2_CYCLE 2
#define AR_AUDIO_IF_BIT_CLK_INTERNAL 0
#define AR_AUDIO_IF_BIT_CLK_EXTERNAL 1
#define AR_AUDIO_IF_BIT_CLK_SKIP 2
#define AR_AUDIO_IF_CLK_NORMAL 0
#define AR_AUDIO_IF_CLK_INVERTED 1
#define SND_SOC_AR_TPLG_MODULE_CFG_TYPE 0x01001006
struct audioreach_module_priv_data {
__le32 size; /* size in bytes of the array, including all elements */

View File

@ -1,324 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* snd_sst_tokens.h - Intel SST tokens definition
*
* Copyright (C) 2016 Intel Corp
* Author: Shreyas NC <shreyas.nc@intel.com>
*/
#ifndef __SND_SST_TOKENS_H__
#define __SND_SST_TOKENS_H__
/**
* %SKL_TKN_UUID: Module UUID
*
* %SKL_TKN_U8_BLOCK_TYPE: Type of the private data block.Can be:
* tuples, bytes, short and words
*
* %SKL_TKN_U8_IN_PIN_TYPE: Input pin type,
* homogenous=0, heterogenous=1
*
* %SKL_TKN_U8_OUT_PIN_TYPE: Output pin type,
* homogenous=0, heterogenous=1
* %SKL_TKN_U8_DYN_IN_PIN: Configure Input pin dynamically
* if true
*
* %SKL_TKN_U8_DYN_OUT_PIN: Configure Output pin dynamically
* if true
*
* %SKL_TKN_U8_IN_QUEUE_COUNT: Store the number of Input pins
*
* %SKL_TKN_U8_OUT_QUEUE_COUNT: Store the number of Output pins
*
* %SKL_TKN_U8_TIME_SLOT: TDM slot number
*
* %SKL_TKN_U8_CORE_ID: Stores module affinity value.Can take
* the values:
* SKL_AFFINITY_CORE_0 = 0,
* SKL_AFFINITY_CORE_1,
* SKL_AFFINITY_CORE_MAX
*
* %SKL_TKN_U8_MOD_TYPE: Module type value.
*
* %SKL_TKN_U8_CONN_TYPE: Module connection type can be a FE,
* BE or NONE as defined :
* SKL_PIPE_CONN_TYPE_NONE = 0,
* SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA)
* SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA)
*
* %SKL_TKN_U8_DEV_TYPE: Type of device to which the module is
* connected
* Can take the values:
* SKL_DEVICE_BT = 0x0,
* SKL_DEVICE_DMIC = 0x1,
* SKL_DEVICE_I2S = 0x2,
* SKL_DEVICE_SLIMBUS = 0x3,
* SKL_DEVICE_HDALINK = 0x4,
* SKL_DEVICE_HDAHOST = 0x5,
* SKL_DEVICE_NONE
*
* %SKL_TKN_U8_HW_CONN_TYPE: Connection type of the HW to which the
* module is connected
* SKL_CONN_NONE = 0,
* SKL_CONN_SOURCE = 1,
* SKL_CONN_SINK = 2
*
* %SKL_TKN_U16_PIN_INST_ID: Stores the pin instance id
*
* %SKL_TKN_U16_MOD_INST_ID: Stores the mdule instance id
*
* %SKL_TKN_U32_MAX_MCPS: Module max mcps value
*
* %SKL_TKN_U32_MEM_PAGES: Module resource pages
*
* %SKL_TKN_U32_OBS: Stores Output Buffer size
*
* %SKL_TKN_U32_IBS: Stores input buffer size
*
* %SKL_TKN_U32_VBUS_ID: Module VBUS_ID. PDM=0, SSP0=0,
* SSP1=1,SSP2=2,
* SSP3=3, SSP4=4,
* SSP5=5, SSP6=6,INVALID
*
* %SKL_TKN_U32_PARAMS_FIXUP: Module Params fixup mask
* %SKL_TKN_U32_CONVERTER: Module params converter mask
* %SKL_TKN_U32_PIPE_ID: Stores the pipe id
*
* %SKL_TKN_U32_PIPE_CONN_TYPE: Type of the token to which the pipe is
* connected to. It can be
* SKL_PIPE_CONN_TYPE_NONE = 0,
* SKL_PIPE_CONN_TYPE_FE = 1 (HOST_DMA),
* SKL_PIPE_CONN_TYPE_BE = 2 (LINK_DMA),
*
* %SKL_TKN_U32_PIPE_PRIORITY: Pipe priority value
* %SKL_TKN_U32_PIPE_MEM_PGS: Pipe resource pages
*
* %SKL_TKN_U32_DIR_PIN_COUNT: Value for the direction to set input/output
* formats and the pin count.
* The first 4 bits have the direction
* value and the next 4 have
* the pin count value.
* SKL_DIR_IN = 0, SKL_DIR_OUT = 1.
* The input and output formats
* share the same set of tokens
* with the distinction between input
* and output made by reading direction
* token.
*
* %SKL_TKN_U32_FMT_CH: Supported channel count
*
* %SKL_TKN_U32_FMT_FREQ: Supported frequency/sample rate
*
* %SKL_TKN_U32_FMT_BIT_DEPTH: Supported container size
*
* %SKL_TKN_U32_FMT_SAMPLE_SIZE:Number of samples in the container
*
* %SKL_TKN_U32_FMT_CH_CONFIG: Supported channel configurations for the
* input/output.
*
* %SKL_TKN_U32_FMT_INTERLEAVE: Interleaving style which can be per
* channel or per sample. The values can be :
* SKL_INTERLEAVING_PER_CHANNEL = 0,
* SKL_INTERLEAVING_PER_SAMPLE = 1,
*
* %SKL_TKN_U32_FMT_SAMPLE_TYPE:
* Specifies the sample type. Can take the
* values: SKL_SAMPLE_TYPE_INT_MSB = 0,
* SKL_SAMPLE_TYPE_INT_LSB = 1,
* SKL_SAMPLE_TYPE_INT_SIGNED = 2,
* SKL_SAMPLE_TYPE_INT_UNSIGNED = 3,
* SKL_SAMPLE_TYPE_FLOAT = 4
*
* %SKL_TKN_U32_CH_MAP: Channel map values
* %SKL_TKN_U32_MOD_SET_PARAMS: It can take these values:
* SKL_PARAM_DEFAULT, SKL_PARAM_INIT,
* SKL_PARAM_SET, SKL_PARAM_BIND
*
* %SKL_TKN_U32_MOD_PARAM_ID: ID of the module params
*
* %SKL_TKN_U32_CAPS_SET_PARAMS:
* Set params value
*
* %SKL_TKN_U32_CAPS_PARAMS_ID: Params ID
*
* %SKL_TKN_U32_CAPS_SIZE: Caps size
*
* %SKL_TKN_U32_PROC_DOMAIN: Specify processing domain
*
* %SKL_TKN_U32_LIB_COUNT: Specifies the number of libraries
*
* %SKL_TKN_STR_LIB_NAME: Specifies the library name
*
* %SKL_TKN_U32_PMODE: Specifies the power mode for pipe
*
* %SKL_TKL_U32_D0I3_CAPS: Specifies the D0i3 capability for module
*
* %SKL_TKN_U32_DMA_BUF_SIZE: DMA buffer size in millisec
*
* %SKL_TKN_U32_PIPE_DIR: Specifies pipe direction. Can be
* playback/capture.
*
* %SKL_TKN_U32_NUM_CONFIGS: Number of pipe configs
*
* %SKL_TKN_U32_PATH_MEM_PGS: Size of memory (in pages) required for pipeline
* and its data
*
* %SKL_TKN_U32_PIPE_CONFIG_ID: Config id for the modules in the pipe
* and PCM params supported by that pipe
* config. This is used as index to fill
* up the pipe config and module config
* structure.
*
* %SKL_TKN_U32_CFG_FREQ:
* %SKL_TKN_U8_CFG_CHAN:
* %SKL_TKN_U8_CFG_BPS: PCM params (freq, channels, bits per sample)
* supported for each of the pipe configs.
*
* %SKL_TKN_CFG_MOD_RES_ID: Module's resource index for each of the
* pipe config
*
* %SKL_TKN_CFG_MOD_FMT_ID: Module's interface index for each of the
* pipe config
*
* %SKL_TKN_U8_NUM_MOD: Number of modules in the manifest
*
* %SKL_TKN_MM_U8_MOD_IDX: Current index of the module in the manifest
*
* %SKL_TKN_MM_U8_NUM_RES: Number of resources for the module
*
* %SKL_TKN_MM_U8_NUM_INTF: Number of interfaces for the module
*
* %SKL_TKN_MM_U32_RES_ID: Resource index for the resource info to
* be filled into.
* A module can support multiple resource
* configuration and is represnted as a
* resource table. This index is used to
* fill information into appropriate index.
*
* %SKL_TKN_MM_U32_CPS: DSP cycles per second
*
* %SKL_TKN_MM_U32_DMA_SIZE: Allocated buffer size for gateway DMA
*
* %SKL_TKN_MM_U32_CPC: DSP cycles allocated per frame
*
* %SKL_TKN_MM_U32_RES_PIN_ID: Resource pin index in the module
*
* %SKL_TKN_MM_U32_INTF_PIN_ID: Interface index in the module
*
* %SKL_TKN_MM_U32_PIN_BUF: Buffer size of the module pin
*
* %SKL_TKN_MM_U32_FMT_ID: Format index for each of the interface/
* format information to be filled into.
*
* %SKL_TKN_MM_U32_NUM_IN_FMT: Number of input formats
* %SKL_TKN_MM_U32_NUM_OUT_FMT: Number of output formats
*
* %SKL_TKN_U32_ASTATE_IDX: Table Index for the A-State entry to be filled
* with kcps and clock source
*
* %SKL_TKN_U32_ASTATE_COUNT: Number of valid entries in A-State table
*
* %SKL_TKN_U32_ASTATE_KCPS: Specifies the core load threshold (in kilo
* cycles per second) below which DSP is clocked
* from source specified by clock source.
*
* %SKL_TKN_U32_ASTATE_CLK_SRC: Clock source for A-State entry
*
* %SKL_TKN_U32_FMT_CFG_IDX: Format config index
*
* module_id and loadable flags dont have tokens as these values will be
* read from the DSP FW manifest
*
* Tokens defined can be used either in the manifest or widget private data.
*
* SKL_TKN_MM is used as a suffix for all tokens that represent
* module data in the manifest.
*/
enum SKL_TKNS {
SKL_TKN_UUID = 1,
SKL_TKN_U8_NUM_BLOCKS,
SKL_TKN_U8_BLOCK_TYPE,
SKL_TKN_U8_IN_PIN_TYPE,
SKL_TKN_U8_OUT_PIN_TYPE,
SKL_TKN_U8_DYN_IN_PIN,
SKL_TKN_U8_DYN_OUT_PIN,
SKL_TKN_U8_IN_QUEUE_COUNT,
SKL_TKN_U8_OUT_QUEUE_COUNT,
SKL_TKN_U8_TIME_SLOT,
SKL_TKN_U8_CORE_ID,
SKL_TKN_U8_MOD_TYPE,
SKL_TKN_U8_CONN_TYPE,
SKL_TKN_U8_DEV_TYPE,
SKL_TKN_U8_HW_CONN_TYPE,
SKL_TKN_U16_MOD_INST_ID,
SKL_TKN_U16_BLOCK_SIZE,
SKL_TKN_U32_MAX_MCPS,
SKL_TKN_U32_MEM_PAGES,
SKL_TKN_U32_OBS,
SKL_TKN_U32_IBS,
SKL_TKN_U32_VBUS_ID,
SKL_TKN_U32_PARAMS_FIXUP,
SKL_TKN_U32_CONVERTER,
SKL_TKN_U32_PIPE_ID,
SKL_TKN_U32_PIPE_CONN_TYPE,
SKL_TKN_U32_PIPE_PRIORITY,
SKL_TKN_U32_PIPE_MEM_PGS,
SKL_TKN_U32_DIR_PIN_COUNT,
SKL_TKN_U32_FMT_CH,
SKL_TKN_U32_FMT_FREQ,
SKL_TKN_U32_FMT_BIT_DEPTH,
SKL_TKN_U32_FMT_SAMPLE_SIZE,
SKL_TKN_U32_FMT_CH_CONFIG,
SKL_TKN_U32_FMT_INTERLEAVE,
SKL_TKN_U32_FMT_SAMPLE_TYPE,
SKL_TKN_U32_FMT_CH_MAP,
SKL_TKN_U32_PIN_MOD_ID,
SKL_TKN_U32_PIN_INST_ID,
SKL_TKN_U32_MOD_SET_PARAMS,
SKL_TKN_U32_MOD_PARAM_ID,
SKL_TKN_U32_CAPS_SET_PARAMS,
SKL_TKN_U32_CAPS_PARAMS_ID,
SKL_TKN_U32_CAPS_SIZE,
SKL_TKN_U32_PROC_DOMAIN,
SKL_TKN_U32_LIB_COUNT,
SKL_TKN_STR_LIB_NAME,
SKL_TKN_U32_PMODE,
SKL_TKL_U32_D0I3_CAPS, /* Typo added at v4.10 */
SKL_TKN_U32_D0I3_CAPS = SKL_TKL_U32_D0I3_CAPS,
SKL_TKN_U32_DMA_BUF_SIZE,
SKL_TKN_U32_PIPE_DIRECTION,
SKL_TKN_U32_PIPE_CONFIG_ID,
SKL_TKN_U32_NUM_CONFIGS,
SKL_TKN_U32_PATH_MEM_PGS,
SKL_TKN_U32_CFG_FREQ,
SKL_TKN_U8_CFG_CHAN,
SKL_TKN_U8_CFG_BPS,
SKL_TKN_CFG_MOD_RES_ID,
SKL_TKN_CFG_MOD_FMT_ID,
SKL_TKN_U8_NUM_MOD,
SKL_TKN_MM_U8_MOD_IDX,
SKL_TKN_MM_U8_NUM_RES,
SKL_TKN_MM_U8_NUM_INTF,
SKL_TKN_MM_U32_RES_ID,
SKL_TKN_MM_U32_CPS,
SKL_TKN_MM_U32_DMA_SIZE,
SKL_TKN_MM_U32_CPC,
SKL_TKN_MM_U32_RES_PIN_ID,
SKL_TKN_MM_U32_INTF_PIN_ID,
SKL_TKN_MM_U32_PIN_BUF,
SKL_TKN_MM_U32_FMT_ID,
SKL_TKN_MM_U32_NUM_IN_FMT,
SKL_TKN_MM_U32_NUM_OUT_FMT,
SKL_TKN_U32_ASTATE_IDX,
SKL_TKN_U32_ASTATE_COUNT,
SKL_TKN_U32_ASTATE_KCPS,
SKL_TKN_U32_ASTATE_CLK_SRC,
SKL_TKN_U32_FMT_CFG_IDX = 96,
SKL_TKN_MAX = SKL_TKN_U32_FMT_CFG_IDX,
};
#endif

View File

@ -111,8 +111,8 @@
#define SOF_TKN_COMP_SCHED_DOMAIN 418
#define SOF_TKN_COMP_DOMAIN_ID 419
#define SOF_TKN_COMP_HEAP_BYTES_REQUIREMENT 420
#define SOF_TKN_COMP_STACK_BYTES_REQUIREMENT 421
#define SOF_TKN_COMP_STACK_BYTES_REQUIREMENT 420
#define SOF_TKN_COMP_HEAP_BYTES_REQUIREMENT 421
/* SSP */
#define SOF_TKN_INTEL_SSP_CLKS_CONTROL 500
@ -223,6 +223,7 @@
#define SOF_TKN_AMD_ACPI2S_RATE 1700
#define SOF_TKN_AMD_ACPI2S_CH 1701
#define SOF_TKN_AMD_ACPI2S_TDM_MODE 1702
#define SOF_TKN_AMD_ACPI2S_FORMAT 1703
/* MICFIL PDM */
#define SOF_TKN_IMX_MICFIL_RATE 2000

View File

@ -693,7 +693,7 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct snd_card *card;
struct atmel_ac97c *chip;
struct resource *regs;
void __iomem *regs;
struct clk *pclk;
static const struct snd_ac97_bus_ops ops = {
.write = atmel_ac97c_write,
@ -702,42 +702,34 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
int retval;
int irq;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
dev_dbg(&pdev->dev, "no memory resource\n");
return -ENXIO;
}
regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(regs))
return PTR_ERR(regs);
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_dbg(&pdev->dev, "could not get irq: %d\n", irq);
if (irq < 0)
return irq;
}
pclk = clk_get(&pdev->dev, "ac97_clk");
pclk = devm_clk_get_enabled(&pdev->dev, "ac97_clk");
if (IS_ERR(pclk)) {
dev_dbg(&pdev->dev, "no peripheral clock\n");
return PTR_ERR(pclk);
}
retval = clk_prepare_enable(pclk);
if (retval)
goto err_prepare_enable;
retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1,
retval = snd_devm_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1,
SNDRV_DEFAULT_STR1, THIS_MODULE,
sizeof(struct atmel_ac97c), &card);
if (retval) {
dev_dbg(&pdev->dev, "could not create sound card device\n");
goto err_snd_card_new;
return retval;
}
chip = get_chip(card);
retval = request_irq(irq, atmel_ac97c_interrupt, 0, "AC97C", chip);
if (retval) {
dev_dbg(&pdev->dev, "unable to request irq %d\n", irq);
goto err_request_irq;
}
retval = devm_request_irq(&pdev->dev, irq, atmel_ac97c_interrupt, 0, "AC97C", chip);
if (retval)
return retval;
chip->irq = irq;
spin_lock_init(&chip->lock);
@ -749,13 +741,7 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
chip->card = card;
chip->pclk = pclk;
chip->pdev = pdev;
chip->regs = ioremap(regs->start, resource_size(regs));
if (!chip->regs) {
dev_dbg(&pdev->dev, "could not remap register memory\n");
retval = -ENOMEM;
goto err_ioremap;
}
chip->regs = regs;
chip->reset_pin = devm_gpiod_get_index(dev, "ac97", 2, GPIOD_OUT_HIGH);
if (IS_ERR(chip->reset_pin))
@ -770,25 +756,25 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
retval = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus);
if (retval) {
dev_dbg(&pdev->dev, "could not register on ac97 bus\n");
goto err_ac97_bus;
return retval;
}
retval = atmel_ac97c_mixer_new(chip);
if (retval) {
dev_dbg(&pdev->dev, "could not register ac97 mixer\n");
goto err_ac97_bus;
return retval;
}
retval = atmel_ac97c_pcm_new(chip);
if (retval) {
dev_dbg(&pdev->dev, "could not register ac97 pcm device\n");
goto err_ac97_bus;
return retval;
}
retval = snd_card_register(card);
if (retval) {
dev_dbg(&pdev->dev, "could not register sound card\n");
goto err_ac97_bus;
return retval;
}
platform_set_drvdata(pdev, card);
@ -797,18 +783,6 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
chip->regs, irq);
return 0;
err_ac97_bus:
iounmap(chip->regs);
err_ioremap:
free_irq(irq, chip);
err_request_irq:
snd_card_free(card);
err_snd_card_new:
clk_disable_unprepare(pclk);
err_prepare_enable:
clk_put(pclk);
return retval;
}
static int atmel_ac97c_suspend(struct device *pdev)
@ -839,13 +813,6 @@ static void atmel_ac97c_remove(struct platform_device *pdev)
ac97c_writel(chip, CAMR, 0);
ac97c_writel(chip, COMR, 0);
ac97c_writel(chip, MR, 0);
clk_disable_unprepare(chip->pclk);
clk_put(chip->pclk);
iounmap(chip->regs);
free_irq(chip->irq, chip);
snd_card_free(card);
}
static struct platform_driver atmel_ac97c_driver = {

View File

@ -1393,17 +1393,17 @@ static long snd_compr_ioctl_compat(struct file *file, unsigned int cmd,
#endif
static const struct file_operations snd_compr_file_ops = {
.owner = THIS_MODULE,
.open = snd_compr_open,
.release = snd_compr_free,
.write = snd_compr_write,
.read = snd_compr_read,
.unlocked_ioctl = snd_compr_ioctl,
.owner = THIS_MODULE,
.open = snd_compr_open,
.release = snd_compr_free,
.write = snd_compr_write,
.read = snd_compr_read,
.unlocked_ioctl = snd_compr_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = snd_compr_ioctl_compat,
.compat_ioctl = snd_compr_ioctl_compat,
#endif
.mmap = snd_compr_mmap,
.poll = snd_compr_poll,
.mmap = snd_compr_mmap,
.poll = snd_compr_poll,
};
static int snd_compress_dev_register(struct snd_device *device)

View File

@ -38,7 +38,7 @@ struct snd_kctl_ioctl {
snd_kctl_ioctl_func_t fioctl;
};
static DECLARE_RWSEM(snd_ioctl_rwsem);
DECLARE_RWSEM(snd_ioctl_rwsem);
static DECLARE_RWSEM(snd_ctl_layer_rwsem);
static LIST_HEAD(snd_control_ioctls);
#ifdef CONFIG_COMPAT
@ -55,9 +55,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
struct snd_ctl_file *ctl;
int i, err;
err = stream_open(inode, file);
if (err < 0)
return err;
stream_open(inode, file);
card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL);
if (!card) {
@ -65,12 +63,10 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
goto __error1;
}
err = snd_card_file_add(card, file);
if (err < 0) {
err = -ENODEV;
if (err < 0)
goto __error1;
}
if (!try_module_get(card->module)) {
err = -EFAULT;
err = -ENODEV;
goto __error2;
}
ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
@ -876,23 +872,81 @@ static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
{
struct snd_ctl_card_info *info __free(kfree) =
kzalloc(sizeof(*info), GFP_KERNEL);
ssize_t n;
if (! info)
return -ENOMEM;
static_assert(sizeof(info->components) >= 2);
scoped_guard(rwsem_read, &snd_ioctl_rwsem) {
const char *components = card->components;
if (!components)
components = "";
info->card = card->number;
strscpy(info->id, card->id, sizeof(info->id));
strscpy(info->driver, card->driver, sizeof(info->driver));
strscpy(info->name, card->shortname, sizeof(info->name));
strscpy(info->longname, card->longname, sizeof(info->longname));
strscpy(info->mixername, card->mixername, sizeof(info->mixername));
strscpy(info->components, card->components, sizeof(info->components));
n = strscpy(info->components, components, sizeof(info->components));
if (n < 0) // mark the truncation with '>' before NULL terminator
info->components[sizeof(info->components) - 2] = '>';
}
if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info)))
return -EFAULT;
return 0;
}
static int snd_ctl_card_bytes(struct snd_card *card,
struct snd_ctl_card_bytes *info,
unsigned int __user *data_len_out)
{
unsigned int data_len;
switch (info->type) {
case SND_CTL_CARD_BTYPE_COMPONENTS:
scoped_guard(rwsem_read, &snd_ioctl_rwsem) {
const char *components = card->components;
if (!components)
components = "";
data_len = strlen(components) + 1;
if (!info->data || info->data_allocated == 0)
break;
if (info->data_allocated < data_len)
return -ENOMEM;
if (copy_to_user(u64_to_user_ptr(info->data), components, data_len))
return -EFAULT;
}
break;
default:
return -EINVAL;
}
if (put_user(data_len, data_len_out))
return -EFAULT;
return 0;
}
static int snd_ctl_card_bytes_user(struct snd_card *card,
struct snd_ctl_card_bytes __user *_info)
{
struct snd_ctl_card_bytes info;
if (copy_from_user(&info, _info, sizeof(info)))
return -EFAULT;
return snd_ctl_card_bytes(card, &info, &_info->data_len);
}
static int snd_ctl_elem_list(struct snd_card *card,
struct snd_ctl_elem_list *list)
{
@ -1990,6 +2044,8 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0;
case SNDRV_CTL_IOCTL_CARD_INFO:
return snd_ctl_card_info(card, ctl, cmd, argp);
case SNDRV_CTL_IOCTL_CARD_BYTES:
return snd_ctl_card_bytes_user(card, argp);
case SNDRV_CTL_IOCTL_ELEM_LIST:
return snd_ctl_elem_list_user(card, argp);
case SNDRV_CTL_IOCTL_ELEM_INFO:
@ -2339,16 +2395,15 @@ EXPORT_SYMBOL_GPL(snd_ctl_disconnect_layer);
* INIT PART
*/
static const struct file_operations snd_ctl_f_ops =
{
.owner = THIS_MODULE,
.read = snd_ctl_read,
.open = snd_ctl_open,
.release = snd_ctl_release,
.poll = snd_ctl_poll,
.unlocked_ioctl = snd_ctl_ioctl,
.compat_ioctl = snd_ctl_ioctl_compat,
.fasync = snd_ctl_fasync,
static const struct file_operations snd_ctl_f_ops = {
.owner = THIS_MODULE,
.read = snd_ctl_read,
.open = snd_ctl_open,
.release = snd_ctl_release,
.poll = snd_ctl_poll,
.unlocked_ioctl = snd_ctl_ioctl,
.compat_ioctl = snd_ctl_ioctl_compat,
.fasync = snd_ctl_fasync,
};
/* call lops under rwsems; called from snd_ctl_dev_*() below() */

View File

@ -226,8 +226,8 @@ static int copy_ctl_value_from_user(struct snd_card *card,
if (type < 0)
return type;
if (type == (__force int)SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
type == (__force int)SNDRV_CTL_ELEM_TYPE_INTEGER) {
if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
for (i = 0; i < count; i++) {
s32 __user *intp = valuep;
int val;
@ -236,7 +236,7 @@ static int copy_ctl_value_from_user(struct snd_card *card,
data->value.integer.value[i] = val;
}
} else {
size = get_elem_size((__force snd_ctl_elem_type_t)type, count);
size = get_elem_size(type, count);
if (size < 0) {
dev_err(card->dev, "snd_ioctl32_ctl_elem_value: unknown type %d\n", type);
return -EINVAL;
@ -259,8 +259,8 @@ static int copy_ctl_value_to_user(void __user *userdata,
struct snd_ctl_elem_value32 __user *data32 = userdata;
int i, size;
if (type == (__force int)SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
type == (__force int)SNDRV_CTL_ELEM_TYPE_INTEGER) {
if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
for (i = 0; i < count; i++) {
s32 __user *intp = valuep;
int val;
@ -269,7 +269,7 @@ static int copy_ctl_value_to_user(void __user *userdata,
return -EFAULT;
}
} else {
size = get_elem_size((__force snd_ctl_elem_type_t)type, count);
size = get_elem_size(type, count);
if (copy_to_user(valuep, data->value.bytes.data, size))
return -EFAULT;
}
@ -417,7 +417,7 @@ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
break;
}
return snd_ctl_elem_add(file, data, replace);
}
}
enum {
SNDRV_CTL_IOCTL_ELEM_LIST32 = _IOWR('U', 0x10, struct snd_ctl_elem_list32),
@ -446,6 +446,7 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns
switch (cmd) {
case SNDRV_CTL_IOCTL_PVERSION:
case SNDRV_CTL_IOCTL_CARD_INFO:
case SNDRV_CTL_IOCTL_CARD_BYTES:
case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
case SNDRV_CTL_IOCTL_POWER:
case SNDRV_CTL_IOCTL_POWER_STATE:

View File

@ -87,7 +87,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
if (!try_module_get(hw->card->module)) {
snd_card_unref(hw->card);
return -EFAULT;
return -ENODEV;
}
init_waitqueue_entry(&wait, current);
@ -323,18 +323,17 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
*/
static const struct file_operations snd_hwdep_f_ops =
{
.owner = THIS_MODULE,
.llseek = snd_hwdep_llseek,
.read = snd_hwdep_read,
.write = snd_hwdep_write,
.open = snd_hwdep_open,
.release = snd_hwdep_release,
.poll = snd_hwdep_poll,
.unlocked_ioctl = snd_hwdep_ioctl,
.compat_ioctl = snd_hwdep_ioctl_compat,
.mmap = snd_hwdep_mmap,
static const struct file_operations snd_hwdep_f_ops = {
.owner = THIS_MODULE,
.llseek = snd_hwdep_llseek,
.read = snd_hwdep_read,
.write = snd_hwdep_write,
.open = snd_hwdep_open,
.release = snd_hwdep_release,
.poll = snd_hwdep_poll,
.unlocked_ioctl = snd_hwdep_ioctl,
.compat_ioctl = snd_hwdep_ioctl_compat,
.mmap = snd_hwdep_mmap,
};
static void snd_hwdep_free(struct snd_hwdep *hwdep)

View File

@ -78,7 +78,7 @@ static int alloc_info_private(struct snd_info_entry *entry,
if (!entry || !entry->p)
return -ENODEV;
if (!try_module_get(entry->module))
return -EFAULT;
return -ENODEV;
data = kzalloc_obj(*data);
if (!data) {
module_put(entry->module);

View File

@ -466,20 +466,19 @@ static int snd_disconnect_fasync(int fd, struct file *file, int on)
return -ENODEV;
}
static const struct file_operations snd_shutdown_f_ops =
{
.owner = THIS_MODULE,
.llseek = snd_disconnect_llseek,
.read = snd_disconnect_read,
.write = snd_disconnect_write,
.release = snd_disconnect_release,
.poll = snd_disconnect_poll,
.unlocked_ioctl = snd_disconnect_ioctl,
static const struct file_operations snd_shutdown_f_ops = {
.owner = THIS_MODULE,
.llseek = snd_disconnect_llseek,
.read = snd_disconnect_read,
.write = snd_disconnect_write,
.release = snd_disconnect_release,
.poll = snd_disconnect_poll,
.unlocked_ioctl = snd_disconnect_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = snd_disconnect_ioctl,
.compat_ioctl = snd_disconnect_ioctl,
#endif
.mmap = snd_disconnect_mmap,
.fasync = snd_disconnect_fasync
.mmap = snd_disconnect_mmap,
.fasync = snd_disconnect_fasync
};
/**
@ -584,12 +583,17 @@ EXPORT_SYMBOL_GPL(snd_card_disconnect_sync);
static int snd_card_do_free(struct snd_card *card)
{
bool managed = card->managed;
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);
#endif
snd_device_free_all(card);
kfree(card->components);
card->components = NULL;
card->components_alloc_size = 0;
if (card->private_free)
card->private_free(card);
#ifdef CONFIG_SND_CTL_DEBUG
@ -601,7 +605,7 @@ static int snd_card_do_free(struct snd_card *card)
}
if (card->release_completion)
complete(card->release_completion);
if (!card->managed)
if (!managed)
kfree(card);
return 0;
}
@ -722,7 +726,7 @@ static void snd_card_set_id_no_lock(struct snd_card *card, const char *src,
int len, loops;
bool is_default = false;
char *id;
copy_valid_id_string(card, src, nid);
id = card->id;
@ -1031,21 +1035,44 @@ int __init snd_card_info_init(void)
*
* Return: Zero otherwise a negative error code.
*/
int snd_component_add(struct snd_card *card, const char *component)
{
char *ptr;
int len = strlen(component);
unsigned int cur_len, need_len;
ptr = strstr(card->components, component);
if (ptr != NULL) {
if (ptr[len] == '\0' || ptr[len] == ' ') /* already there */
return 1;
guard(rwsem_write)(&snd_ioctl_rwsem);
if (card->components) {
ptr = strstr(card->components, component);
if (ptr) {
if (ptr[len] == '\0' || ptr[len] == ' ') /* already there */
return 1;
}
cur_len = strlen(card->components) + 1;
} else {
cur_len = 0;
}
if (strlen(card->components) + 1 + len + 1 > sizeof(card->components)) {
need_len = cur_len + len + 1;
if (need_len > 512) {
snd_BUG();
return -ENOMEM;
}
if (need_len > card->components_alloc_size) {
unsigned int new_alloc = roundup(need_len, 32);
ptr = krealloc(card->components, new_alloc, GFP_KERNEL);
if (!ptr)
return -ENOMEM;
if (!card->components)
ptr[0] = '\0';
card->components = ptr;
card->components_alloc_size = new_alloc;
}
if (card->components[0] != '\0')
strcat(card->components, " ");
strcat(card->components, component);

View File

@ -303,41 +303,41 @@ static ssize_t jack_type_read(struct file *file,
}
static const struct file_operations jack_type_fops = {
.open = simple_open,
.read = jack_type_read,
.llseek = default_llseek,
.open = simple_open,
.read = jack_type_read,
.llseek = default_llseek,
};
#endif
static const struct file_operations sw_inject_enable_fops = {
.open = simple_open,
.read = sw_inject_enable_read,
.write = sw_inject_enable_write,
.llseek = default_llseek,
.open = simple_open,
.read = sw_inject_enable_read,
.write = sw_inject_enable_write,
.llseek = default_llseek,
};
static const struct file_operations jackin_inject_fops = {
.open = simple_open,
.write = jackin_inject_write,
.llseek = default_llseek,
.open = simple_open,
.write = jackin_inject_write,
.llseek = default_llseek,
};
static const struct file_operations jack_kctl_id_fops = {
.open = simple_open,
.read = jack_kctl_id_read,
.llseek = default_llseek,
.open = simple_open,
.read = jack_kctl_id_read,
.llseek = default_llseek,
};
static const struct file_operations jack_kctl_mask_bits_fops = {
.open = simple_open,
.read = jack_kctl_mask_bits_read,
.llseek = default_llseek,
.open = simple_open,
.read = jack_kctl_mask_bits_read,
.llseek = default_llseek,
};
static const struct file_operations jack_kctl_status_fops = {
.open = simple_open,
.read = jack_kctl_status_read,
.llseek = default_llseek,
.open = simple_open,
.read = jack_kctl_status_read,
.llseek = default_llseek,
};
static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack,

View File

@ -30,9 +30,7 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
struct snd_mixer_oss_file *fmixer;
int err;
err = nonseekable_open(inode, file);
if (err < 0)
return err;
nonseekable_open(inode, file);
card = snd_lookup_oss_minor_data(iminor(inode),
SNDRV_OSS_DEVICE_TYPE_MIXER);
@ -60,7 +58,7 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
kfree(fmixer);
snd_card_file_remove(card, file);
snd_card_unref(card);
return -EFAULT;
return -ENODEV;
}
snd_card_unref(card);
return 0;
@ -407,13 +405,12 @@ static long snd_mixer_oss_ioctl_compat(struct file *file, unsigned int cmd,
* REGISTRATION PART
*/
static const struct file_operations snd_mixer_oss_f_ops =
{
.owner = THIS_MODULE,
.open = snd_mixer_oss_open,
.release = snd_mixer_oss_release,
.unlocked_ioctl = snd_mixer_oss_ioctl,
.compat_ioctl = snd_mixer_oss_ioctl_compat,
static const struct file_operations snd_mixer_oss_f_ops = {
.owner = THIS_MODULE,
.open = snd_mixer_oss_open,
.release = snd_mixer_oss_release,
.unlocked_ioctl = snd_mixer_oss_ioctl,
.compat_ioctl = snd_mixer_oss_ioctl_compat,
};
/*

View File

@ -879,11 +879,11 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
_snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0);
snd_mask_none(&mask);
if (atomic_read(&substream->mmap_count))
snd_mask_set(&mask, (__force int)SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
snd_mask_set(&mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
else {
snd_mask_set(&mask, (__force int)SNDRV_PCM_ACCESS_RW_INTERLEAVED);
snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_INTERLEAVED);
if (!direct)
snd_mask_set(&mask, (__force int)SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
snd_mask_set(&mask, SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
}
err = snd_pcm_hw_param_mask(substream, sparams, SNDRV_PCM_HW_PARAM_ACCESS, &mask);
if (err < 0) {
@ -909,7 +909,7 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
else
sformat = snd_pcm_plug_slave_format(format, sformat_mask);
if ((__force int)sformat < 0 ||
if (sformat < 0 ||
!snd_mask_test_format(sformat_mask, sformat)) {
pcm_for_each_format(sformat) {
if (snd_mask_test_format(sformat_mask, sformat) &&
@ -921,7 +921,7 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
goto failure;
}
format_found:
err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, (__force int)sformat, 0);
err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, sformat, 0);
if (err < 0)
goto failure;
@ -930,9 +930,9 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
} else {
_snd_pcm_hw_params_any(params);
_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS,
(__force int)SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0);
SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0);
_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT,
(__force int)snd_pcm_oss_format_from(runtime->oss.format), 0);
snd_pcm_oss_format_from(runtime->oss.format), 0);
_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS,
runtime->oss.channels, 0);
_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE,
@ -1875,7 +1875,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
for (fmt = 0; fmt < 32; ++fmt) {
if (snd_mask_test(format_mask, fmt)) {
int f = snd_pcm_oss_format_to((__force snd_pcm_format_t)fmt);
int f = snd_pcm_oss_format_to(fmt);
if (f >= 0)
formats |= f;
}
@ -2495,9 +2495,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
int nonblock;
wait_queue_entry_t wait;
err = nonseekable_open(inode, file);
if (err < 0)
return err;
nonseekable_open(inode, file);
pcm = snd_lookup_oss_minor_data(iminor(inode),
SNDRV_OSS_DEVICE_TYPE_PCM);
@ -2509,7 +2507,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
if (err < 0)
goto __error1;
if (!try_module_get(pcm->card->module)) {
err = -EFAULT;
err = -ENODEV;
goto __error2;
}
if (snd_task_name(current, task_name, sizeof(task_name)) < 0) {
@ -3129,17 +3127,16 @@ static inline void snd_pcm_oss_proc_done(struct snd_pcm *pcm)
* ENTRY functions
*/
static const struct file_operations snd_pcm_oss_f_reg =
{
.owner = THIS_MODULE,
.read = snd_pcm_oss_read,
.write = snd_pcm_oss_write,
.open = snd_pcm_oss_open,
.release = snd_pcm_oss_release,
.poll = snd_pcm_oss_poll,
.unlocked_ioctl = snd_pcm_oss_ioctl,
.compat_ioctl = snd_pcm_oss_ioctl_compat,
.mmap = snd_pcm_oss_mmap,
static const struct file_operations snd_pcm_oss_f_reg = {
.owner = THIS_MODULE,
.read = snd_pcm_oss_read,
.write = snd_pcm_oss_write,
.open = snd_pcm_oss_open,
.release = snd_pcm_oss_release,
.poll = snd_pcm_oss_poll,
.unlocked_ioctl = snd_pcm_oss_ioctl,
.compat_ioctl = snd_pcm_oss_ioctl_compat,
.mmap = snd_pcm_oss_mmap,
};
static void register_oss_dsp(struct snd_pcm *pcm, int index)

View File

@ -272,13 +272,13 @@ static int snd_pcm_plug_formats(const struct snd_mask *mask,
SNDRV_PCM_FMTBIT_U24_3BE | SNDRV_PCM_FMTBIT_S24_3BE |
SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE |
SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE);
snd_mask_set(&formats, (__force int)SNDRV_PCM_FORMAT_MU_LAW);
snd_mask_set(&formats, SNDRV_PCM_FORMAT_MU_LAW);
if (formats.bits[0] & lower_32_bits(linfmts))
formats.bits[0] |= lower_32_bits(linfmts);
if (formats.bits[1] & upper_32_bits(linfmts))
formats.bits[1] |= upper_32_bits(linfmts);
return snd_mask_test(&formats, (__force int)format);
return snd_mask_test(&formats, format);
}
static const snd_pcm_format_t preferred_formats[] = {
@ -307,20 +307,20 @@ snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format,
{
int i;
if (snd_mask_test(format_mask, (__force int)format))
if (snd_mask_test(format_mask, format))
return format;
if (!snd_pcm_plug_formats(format_mask, format))
return (__force snd_pcm_format_t)-EINVAL;
return -EINVAL;
if (snd_pcm_format_linear(format)) {
unsigned int width = snd_pcm_format_width(format);
int unsignd = snd_pcm_format_unsigned(format) > 0;
int big = snd_pcm_format_big_endian(format) > 0;
unsigned int badness, best = -1;
snd_pcm_format_t best_format = (__force snd_pcm_format_t)-1;
snd_pcm_format_t best_format = -1;
for (i = 0; i < ARRAY_SIZE(preferred_formats); i++) {
snd_pcm_format_t f = preferred_formats[i];
unsigned int w;
if (!snd_mask_test(format_mask, (__force int)f))
if (!snd_mask_test(format_mask, f))
continue;
w = snd_pcm_format_width(f);
if (w >= width)
@ -334,21 +334,21 @@ snd_pcm_format_t snd_pcm_plug_slave_format(snd_pcm_format_t format,
best = badness;
}
}
if ((__force int)best_format >= 0)
if (best_format >= 0)
return best_format;
else
return (__force snd_pcm_format_t)-EINVAL;
return -EINVAL;
} else {
switch (format) {
case SNDRV_PCM_FORMAT_MU_LAW:
for (i = 0; i < ARRAY_SIZE(preferred_formats); ++i) {
snd_pcm_format_t format1 = preferred_formats[i];
if (snd_mask_test(format_mask, (__force int)format1))
if (snd_mask_test(format_mask, format1))
return format1;
}
fallthrough;
default:
return (__force snd_pcm_format_t)-EINVAL;
return -EINVAL;
}
}
}

View File

@ -211,11 +211,9 @@ static const char * const snd_pcm_format_names[] = {
*/
const char *snd_pcm_format_name(snd_pcm_format_t format)
{
unsigned int format_num = (__force unsigned int)format;
if (format_num >= ARRAY_SIZE(snd_pcm_format_names) || !snd_pcm_format_names[format_num])
if (format >= ARRAY_SIZE(snd_pcm_format_names) || !snd_pcm_format_names[format])
return "Unknown";
return snd_pcm_format_names[format_num];
return snd_pcm_format_names[format];
}
EXPORT_SYMBOL_GPL(snd_pcm_format_name);
@ -275,12 +273,12 @@ static const char *snd_pcm_stream_name(int stream)
static const char *snd_pcm_access_name(snd_pcm_access_t access)
{
return snd_pcm_access_names[(__force int)access];
return snd_pcm_access_names[access];
}
static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
{
return snd_pcm_subformat_names[(__force int)subformat];
return snd_pcm_subformat_names[subformat];
}
static const char *snd_pcm_tstamp_mode_name(int mode)
@ -290,7 +288,7 @@ static const char *snd_pcm_tstamp_mode_name(int mode)
static const char *snd_pcm_state_name(snd_pcm_state_t state)
{
return snd_pcm_state_names[(__force int)state];
return snd_pcm_state_names[state];
}
#if IS_ENABLED(CONFIG_SND_PCM_OSS)

View File

@ -24,15 +24,12 @@ struct pcm_format_data {
unsigned char silence[8]; /* silence data to fill */
};
/* we do lots of calculations on snd_pcm_format_t; shut up sparse */
#define INT __force int
static bool valid_format(snd_pcm_format_t format)
{
return (INT)format >= 0 && (INT)format <= (INT)SNDRV_PCM_FORMAT_LAST;
return format >= 0 && format <= SNDRV_PCM_FORMAT_LAST;
}
static const struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = {
static const struct pcm_format_data pcm_formats[SNDRV_PCM_FORMAT_LAST+1] = {
[SNDRV_PCM_FORMAT_S8] = {
.width = 8, .phys = 8, .le = -1, .signd = 1,
.silence = {},
@ -251,7 +248,7 @@ int snd_pcm_format_signed(snd_pcm_format_t format)
int val;
if (!valid_format(format))
return -EINVAL;
val = pcm_formats[(INT)format].signd;
val = pcm_formats[format].signd;
if (val < 0)
return -EINVAL;
return val;
@ -300,7 +297,7 @@ int snd_pcm_format_little_endian(snd_pcm_format_t format)
int val;
if (!valid_format(format))
return -EINVAL;
val = pcm_formats[(INT)format].le;
val = pcm_formats[format].le;
if (val < 0)
return -EINVAL;
return val;
@ -337,7 +334,7 @@ int snd_pcm_format_width(snd_pcm_format_t format)
int val;
if (!valid_format(format))
return -EINVAL;
val = pcm_formats[(INT)format].width;
val = pcm_formats[format].width;
if (!val)
return -EINVAL;
return val;
@ -356,7 +353,7 @@ int snd_pcm_format_physical_width(snd_pcm_format_t format)
int val;
if (!valid_format(format))
return -EINVAL;
val = pcm_formats[(INT)format].phys;
val = pcm_formats[format].phys;
if (!val)
return -EINVAL;
return val;
@ -390,9 +387,9 @@ const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format)
{
if (!valid_format(format))
return NULL;
if (! pcm_formats[(INT)format].phys)
if (! pcm_formats[format].phys)
return NULL;
return pcm_formats[(INT)format].silence;
return pcm_formats[format].silence;
}
EXPORT_SYMBOL(snd_pcm_format_silence_64);
@ -416,12 +413,12 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
return -EINVAL;
if (samples == 0)
return 0;
width = pcm_formats[(INT)format].phys; /* physical width */
width = pcm_formats[format].phys; /* physical width */
if (!width)
return -EINVAL;
pat = pcm_formats[(INT)format].silence;
pat = pcm_formats[format].silence;
/* signed or 1 byte data */
if (pcm_formats[(INT)format].signd == 1 || width <= 8) {
if (pcm_formats[format].signd == 1 || width <= 8) {
unsigned int bytes = samples * width / 8;
memset(data, *pat, bytes);
return 0;

View File

@ -257,7 +257,7 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream,
}
/* macro for simplified cast */
#define PARAM_MASK_BIT(b) (1U << (__force int)(b))
#define PARAM_MASK_BIT(b) (1U << (b))
static bool hw_support_mmap(struct snd_pcm_substream *substream)
{
@ -489,7 +489,7 @@ static int fixup_unreferenced_params(struct snd_pcm_substream *substream,
params->msbits = snd_interval_value(i);
m = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
if (snd_mask_single(m)) {
snd_pcm_format_t format = (__force snd_pcm_format_t)snd_mask_min(m);
snd_pcm_format_t format = snd_mask_min(m);
params->msbits = snd_pcm_format_width(format);
}
}
@ -497,13 +497,13 @@ static int fixup_unreferenced_params(struct snd_pcm_substream *substream,
if (params->msbits) {
m = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
if (snd_mask_single(m)) {
snd_pcm_format_t format = (__force snd_pcm_format_t)snd_mask_min(m);
snd_pcm_format_t format = snd_mask_min(m);
if (snd_pcm_format_linear(format) &&
snd_pcm_format_width(format) != params->msbits) {
m_rw = hw_param_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT);
snd_mask_reset(m_rw,
(__force unsigned)SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
if (snd_mask_empty(m_rw))
return -EINVAL;
}
@ -1252,7 +1252,7 @@ static void snd_pcm_trigger_tstamp(struct snd_pcm_substream *substream)
runtime->trigger_master = NULL;
}
#define ACTION_ARG_IGNORE (__force snd_pcm_state_t)0
#define ACTION_ARG_IGNORE 0
struct action_ops {
int (*pre_action)(struct snd_pcm_substream *substream,
@ -1635,7 +1635,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_stop_xrun);
/*
* pause callbacks: pass boolean (to start pause or resume) as state argument
*/
#define pause_pushed(state) (__force bool)(state)
#define pause_pushed(state) (bool)(state)
static int snd_pcm_pre_pause(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
@ -1707,14 +1707,14 @@ static const struct action_ops snd_pcm_action_pause = {
static int snd_pcm_pause(struct snd_pcm_substream *substream, bool push)
{
return snd_pcm_action(&snd_pcm_action_pause, substream,
(__force snd_pcm_state_t)push);
(snd_pcm_state_t)push);
}
static int snd_pcm_pause_lock_irq(struct snd_pcm_substream *substream,
bool push)
{
return snd_pcm_action_lock_irq(&snd_pcm_action_pause, substream,
(__force snd_pcm_state_t)push);
(snd_pcm_state_t)push);
}
#ifdef CONFIG_PM
@ -1982,7 +1982,7 @@ static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
snd_pcm_state_t state)
{
snd_pcm_state_t cur_state = snd_pcm_get_state(substream);
int f_flags = (__force int)state;
int f_flags = state;
if (cur_state == SNDRV_PCM_STATE_OPEN ||
cur_state == SNDRV_PCM_STATE_DISCONNECTED)
@ -2050,7 +2050,7 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream,
return snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
substream,
(__force snd_pcm_state_t)f_flags);
(snd_pcm_state_t)f_flags);
}
/*
@ -2461,7 +2461,7 @@ static int snd_pcm_hw_rule_format(struct snd_pcm_hw_params *params,
if (bits <= 0)
continue; /* ignore invalid formats */
if ((unsigned)bits < i->min || (unsigned)bits > i->max)
snd_mask_reset(&m, (__force unsigned)k);
snd_mask_reset(&m, k);
}
return snd_mask_refine(mask, &m);
}
@ -2543,16 +2543,16 @@ static int snd_pcm_hw_rule_subformats(struct snd_pcm_hw_params *params,
snd_mask_none(&m);
/* All PCMs support at least the default STD subformat. */
snd_mask_set(&m, (__force unsigned)SNDRV_PCM_SUBFORMAT_STD);
snd_mask_set(&m, SNDRV_PCM_SUBFORMAT_STD);
pcm_for_each_format(f) {
if (!snd_mask_test(fmask, (__force unsigned)f))
if (!snd_mask_test(fmask, f))
continue;
if (f == SNDRV_PCM_FORMAT_S32_LE && *subformats)
m.bits[0] |= *subformats;
else if (snd_pcm_format_linear(f))
snd_mask_set(&m, (__force unsigned)SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
snd_mask_set(&m, SNDRV_PCM_SUBFORMAT_MSBITS_MAX);
}
return snd_mask_refine(sfmask, &m);
@ -2880,9 +2880,10 @@ static int snd_pcm_open_file(struct file *file,
static int snd_pcm_playback_open(struct inode *inode, struct file *file)
{
struct snd_pcm *pcm;
int err = nonseekable_open(inode, file);
if (err < 0)
return err;
int err;
nonseekable_open(inode, file);
pcm = snd_lookup_minor_data(iminor(inode),
SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
@ -2894,9 +2895,10 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file)
static int snd_pcm_capture_open(struct inode *inode, struct file *file)
{
struct snd_pcm *pcm;
int err = nonseekable_open(inode, file);
if (err < 0)
return err;
int err;
nonseekable_open(inode, file);
pcm = snd_lookup_minor_data(iminor(inode),
SNDRV_DEVICE_TYPE_PCM_CAPTURE);
err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
@ -2918,7 +2920,7 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
if (err < 0)
goto __error1;
if (!try_module_get(pcm->card->module)) {
err = -EFAULT;
err = -ENODEV;
goto __error2;
}
init_waitqueue_entry(&wait, current);
@ -3914,6 +3916,8 @@ static vm_fault_t snd_pcm_mmap_data_fault(struct vm_fault *vmf)
if (substream == NULL)
return VM_FAULT_SIGBUS;
runtime = substream->runtime;
if (runtime->state == SNDRV_PCM_STATE_DISCONNECTED)
return VM_FAULT_SIGBUS;
offset = vmf->pgoff << PAGE_SHIFT;
dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
if (offset > dma_bytes - PAGE_SIZE)
@ -4239,29 +4243,29 @@ static unsigned long snd_pcm_get_unmapped_area(struct file *file,
const struct file_operations snd_pcm_f_ops[2] = {
{
.owner = THIS_MODULE,
.write = snd_pcm_write,
.write_iter = snd_pcm_writev,
.open = snd_pcm_playback_open,
.release = snd_pcm_release,
.poll = snd_pcm_poll,
.unlocked_ioctl = snd_pcm_ioctl,
.compat_ioctl = snd_pcm_ioctl_compat,
.mmap = snd_pcm_mmap,
.fasync = snd_pcm_fasync,
.get_unmapped_area = snd_pcm_get_unmapped_area,
.owner = THIS_MODULE,
.write = snd_pcm_write,
.write_iter = snd_pcm_writev,
.open = snd_pcm_playback_open,
.release = snd_pcm_release,
.poll = snd_pcm_poll,
.unlocked_ioctl = snd_pcm_ioctl,
.compat_ioctl = snd_pcm_ioctl_compat,
.mmap = snd_pcm_mmap,
.fasync = snd_pcm_fasync,
.get_unmapped_area = snd_pcm_get_unmapped_area,
},
{
.owner = THIS_MODULE,
.read = snd_pcm_read,
.read_iter = snd_pcm_readv,
.open = snd_pcm_capture_open,
.release = snd_pcm_release,
.poll = snd_pcm_poll,
.unlocked_ioctl = snd_pcm_ioctl,
.compat_ioctl = snd_pcm_ioctl_compat,
.mmap = snd_pcm_mmap,
.fasync = snd_pcm_fasync,
.get_unmapped_area = snd_pcm_get_unmapped_area,
.owner = THIS_MODULE,
.read = snd_pcm_read,
.read_iter = snd_pcm_readv,
.open = snd_pcm_capture_open,
.release = snd_pcm_release,
.poll = snd_pcm_poll,
.unlocked_ioctl = snd_pcm_ioctl,
.compat_ioctl = snd_pcm_ioctl_compat,
.mmap = snd_pcm_mmap,
.fasync = snd_pcm_fasync,
.get_unmapped_area = snd_pcm_get_unmapped_area,
}
};

View File

@ -408,9 +408,10 @@ static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode,
return 0;
}
/* called from sound/core/seq/seq_midi.c */
int snd_rawmidi_kernel_open(struct snd_rawmidi *rmidi, int subdevice,
int mode, struct snd_rawmidi_file *rfile)
/* called from sound/core/seq/seq_midi.c and sound/core/ump.c */
int snd_rawmidi_kernel_open_nested(struct snd_rawmidi *rmidi, int subdevice,
int mode, struct snd_rawmidi_file *rfile,
int depth)
{
int err;
@ -419,13 +420,14 @@ int snd_rawmidi_kernel_open(struct snd_rawmidi *rmidi, int subdevice,
if (!try_module_get(rmidi->card->module))
return -ENXIO;
guard(mutex)(&rmidi->open_mutex);
mutex_lock_nested(&rmidi->open_mutex, depth);
err = rawmidi_open_priv(rmidi, subdevice, mode, rfile);
if (err < 0)
module_put(rmidi->card->module);
mutex_unlock(&rmidi->open_mutex);
return err;
}
EXPORT_SYMBOL(snd_rawmidi_kernel_open);
EXPORT_SYMBOL(snd_rawmidi_kernel_open_nested);
static int snd_rawmidi_open(struct inode *inode, struct file *file)
{
@ -441,9 +443,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
return -EINVAL; /* invalid combination */
err = stream_open(inode, file);
if (err < 0)
return err;
stream_open(inode, file);
if (maj == snd_major) {
rmidi = snd_lookup_minor_data(iminor(inode),
@ -1784,14 +1784,14 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
*/
static const struct file_operations snd_rawmidi_f_ops = {
.owner = THIS_MODULE,
.read = snd_rawmidi_read,
.write = snd_rawmidi_write,
.open = snd_rawmidi_open,
.release = snd_rawmidi_release,
.poll = snd_rawmidi_poll,
.unlocked_ioctl = snd_rawmidi_ioctl,
.compat_ioctl = snd_rawmidi_ioctl_compat,
.owner = THIS_MODULE,
.read = snd_rawmidi_read,
.write = snd_rawmidi_write,
.open = snd_rawmidi_open,
.release = snd_rawmidi_release,
.poll = snd_rawmidi_poll,
.unlocked_ioctl = snd_rawmidi_ioctl,
.compat_ioctl = snd_rawmidi_ioctl_compat,
};
static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi,

View File

@ -206,17 +206,16 @@ odev_poll(struct file *file, poll_table * wait)
* registration of sequencer minor device
*/
static const struct file_operations seq_oss_f_ops =
{
.owner = THIS_MODULE,
.read = odev_read,
.write = odev_write,
.open = odev_open,
.release = odev_release,
.poll = odev_poll,
.unlocked_ioctl = odev_ioctl,
.compat_ioctl = odev_ioctl_compat,
.llseek = noop_llseek,
static const struct file_operations seq_oss_f_ops = {
.owner = THIS_MODULE,
.read = odev_read,
.write = odev_write,
.open = odev_open,
.release = odev_release,
.poll = odev_poll,
.unlocked_ioctl = odev_ioctl,
.compat_ioctl = odev_ioctl_compat,
.llseek = noop_llseek,
};
static int __init

View File

@ -59,7 +59,7 @@ static DEFINE_MUTEX(register_mutex);
* client table
*/
static char clienttablock[SNDRV_SEQ_MAX_CLIENTS];
static struct snd_seq_client *clienttab[SNDRV_SEQ_MAX_CLIENTS];
static struct snd_seq_client __rcu *clienttab[SNDRV_SEQ_MAX_CLIENTS];
static struct snd_seq_usage client_usage;
/*
@ -95,15 +95,23 @@ static inline int snd_seq_write_pool_allocated(struct snd_seq_client *client)
return snd_seq_total_cells(client->pool) > 0;
}
/* return pointer to client structure for specified id */
static struct snd_seq_client *clientptr(int clientid)
/* return pointer to client structure for specified id; call under RCU read-lock */
static struct snd_seq_client *__clientptr(int clientid)
{
if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) {
pr_debug("ALSA: seq: oops. Trying to get pointer to client %d\n",
clientid);
return NULL;
}
return clienttab[clientid];
return rcu_dereference_check(clienttab[clientid],
lockdep_is_held(&clients_lock));
}
/* return pointer to client structure for specified id */
static struct snd_seq_client *clientptr(int clientid)
{
guard(rcu)();
return __clientptr(clientid);
}
static struct snd_seq_client *client_use_ptr(int clientid, bool load_module)
@ -115,8 +123,8 @@ static struct snd_seq_client *client_use_ptr(int clientid, bool load_module)
clientid);
return NULL;
}
scoped_guard(spinlock_irqsave, &clients_lock) {
client = clientptr(clientid);
scoped_guard(rcu) {
client = __clientptr(clientid);
if (client)
return snd_seq_client_ref(client);
if (clienttablock[clientid])
@ -150,8 +158,8 @@ static struct snd_seq_client *client_use_ptr(int clientid, bool load_module)
snd_seq_device_load_drivers();
}
}
scoped_guard(spinlock_irqsave, &clients_lock) {
client = clientptr(clientid);
scoped_guard(rcu) {
client = __clientptr(clientid);
if (client)
return snd_seq_client_ref(client);
}
@ -212,7 +220,6 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize)
}
client->type = NO_CLIENT;
snd_use_lock_init(&client->use_lock);
rwlock_init(&client->ports_lock);
mutex_init(&client->ports_mutex);
INIT_LIST_HEAD(&client->ports_list_head);
mutex_init(&client->ioctl_mutex);
@ -224,14 +231,17 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize)
for (c = SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN;
c < SNDRV_SEQ_MAX_CLIENTS;
c++) {
if (clienttab[c] || clienttablock[c])
if (rcu_access_pointer(clienttab[c]) || clienttablock[c])
continue;
clienttab[client->number = c] = client;
client->number = c;
rcu_assign_pointer(clienttab[c], client);
return client;
}
} else {
if (clienttab[client_index] == NULL && !clienttablock[client_index]) {
clienttab[client->number = client_index] = client;
if (rcu_access_pointer(clienttab[client_index]) == NULL &&
!clienttablock[client_index]) {
client->number = client_index;
rcu_assign_pointer(clienttab[client_index], client);
return client;
}
}
@ -249,10 +259,16 @@ static int seq_free_client1(struct snd_seq_client *client)
return 0;
scoped_guard(spinlock_irq, &clients_lock) {
clienttablock[client->number] = 1;
clienttab[client->number] = NULL;
rcu_assign_pointer(clienttab[client->number], NULL);
}
snd_seq_delete_all_ports(client);
snd_seq_queue_client_leave(client->number);
/* the client has been unpublished from the table; wait for a grace
* period so that lockless readers (snd_seq_client_use_ptr()) that
* observed the old pointer can no longer take a new use_lock
* reference, then drain the outstanding references before freeing
*/
synchronize_rcu();
snd_use_lock_sync(&client->use_lock);
if (client->pool)
snd_seq_pool_delete(&client->pool);
@ -296,11 +312,8 @@ static int snd_seq_open(struct inode *inode, struct file *file)
int c, mode; /* client id */
struct snd_seq_client *client;
struct snd_seq_user_client *user;
int err;
err = stream_open(inode, file);
if (err < 0)
return err;
stream_open(inode, file);
scoped_guard(mutex, &register_mutex) {
client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS);
@ -517,9 +530,8 @@ static struct snd_seq_client *get_event_dest_client(struct snd_seq_event *event)
* Return the error event.
*
* If the receiver client is a user client, the original event is
* encapsulated in SNDRV_SEQ_EVENT_BOUNCE as variable length event. If
* the original event is also variable length, the external data is
* copied after the event record.
* encapsulated in SNDRV_SEQ_EVENT_BOUNCE as variable length event. The
* external data of a variable length event is not copied along.
* If the receiver client is a kernel client, the original event is
* quoted in SNDRV_SEQ_EVENT_KERNEL_ERROR, since this requires no extra
* kmalloc.
@ -528,7 +540,7 @@ static int bounce_error_event(struct snd_seq_client *client,
struct snd_seq_event *event,
int err, int atomic, int hop)
{
struct snd_seq_event bounce_ev;
struct snd_seq_event bounce_ev, quoted;
int result;
if (client == NULL ||
@ -548,15 +560,19 @@ static int bounce_error_event(struct snd_seq_client *client,
* For user clients, send SNDRV_SEQ_EVENT_BOUNCE with the
* original event embedded as variable-length data. This
* avoids exposing data.quote.event (a kernel pointer) to
* userspace. The variable-length path in snd_seq_event_dup()
* copies the event data from data.ext.ptr into chained cells,
* and snd_seq_expand_var_event() copies only the data content
* -- never the pointer -- to userspace.
* userspace. Sanitise the embedded copy too - a queued
* variable-length event carries the address of its own
* extension cell, and the payload goes out verbatim.
*/
quoted = *event;
if (snd_seq_ev_is_variable(&quoted)) {
quoted.data.ext.len &= ~SNDRV_SEQ_EXT_MASK;
quoted.data.ext.ptr = NULL;
}
bounce_ev.type = SNDRV_SEQ_EVENT_BOUNCE;
bounce_ev.flags = SNDRV_SEQ_EVENT_LENGTH_VARIABLE;
bounce_ev.data.ext.len = sizeof(struct snd_seq_event);
bounce_ev.data.ext.ptr = (char *)event;
bounce_ev.data.ext.ptr = (char *)&quoted;
} else {
/*
* For kernel clients, quote the event pointer directly.
@ -720,10 +736,11 @@ static int __deliver_to_subscribers(struct snd_seq_client *client,
/* lock list */
if (atomic)
read_lock(&grp->list_lock);
rcu_read_lock();
else
down_read_nested(&grp->list_mutex, hop);
list_for_each_entry(subs, &grp->list_head, src_list) {
hlist_for_each_entry_rcu(subs, &grp->list_head, src_list,
lockdep_is_held(&grp->list_mutex)) {
/* both ports ready? */
if (atomic_read(&subs->ref_count) != 2)
continue;
@ -744,7 +761,7 @@ static int __deliver_to_subscribers(struct snd_seq_client *client,
memcpy(event, &event_saved, saved_size);
}
if (atomic)
read_unlock(&grp->list_lock);
rcu_read_unlock();
else
up_read(&grp->list_mutex);
memcpy(event, &event_saved, saved_size);
@ -1941,7 +1958,7 @@ static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, void *arg)
{
struct snd_seq_query_subs *subs = arg;
struct snd_seq_port_subs_info *group;
struct list_head *p;
struct hlist_node *p;
int i;
struct snd_seq_client *cptr __free(snd_seq_client) =
@ -1968,15 +1985,15 @@ static int snd_seq_ioctl_query_subs(struct snd_seq_client *client, void *arg)
/* search for the subscriber */
subs->num_subs = group->count;
i = 0;
list_for_each(p, &group->list_head) {
hlist_for_each(p, &group->list_head) {
if (i++ == subs->index) {
/* found! */
struct snd_seq_subscribers *s;
if (subs->type == SNDRV_SEQ_QUERY_SUBS_READ) {
s = list_entry(p, struct snd_seq_subscribers, src_list);
s = hlist_entry(p, struct snd_seq_subscribers, src_list);
subs->addr = s->info.dest;
} else {
s = list_entry(p, struct snd_seq_subscribers, dest_list);
s = hlist_entry(p, struct snd_seq_subscribers, dest_list);
subs->addr = s->info.sender;
}
subs->flags = s->info.flags;
@ -2532,19 +2549,19 @@ static void snd_seq_info_dump_subscribers(struct snd_info_buffer *buffer,
struct snd_seq_port_subs_info *group,
int is_src, char *msg)
{
struct list_head *p;
struct hlist_node *p;
struct snd_seq_subscribers *s;
int count = 0;
guard(rwsem_read)(&group->list_mutex);
if (list_empty(&group->list_head))
if (hlist_empty(&group->list_head))
return;
snd_iprintf(buffer, msg);
list_for_each(p, &group->list_head) {
hlist_for_each(p, &group->list_head) {
if (is_src)
s = list_entry(p, struct snd_seq_subscribers, src_list);
s = hlist_entry(p, struct snd_seq_subscribers, src_list);
else
s = list_entry(p, struct snd_seq_subscribers, dest_list);
s = hlist_entry(p, struct snd_seq_subscribers, dest_list);
if (count++)
snd_iprintf(buffer, ", ");
snd_iprintf(buffer, "%d:%d",
@ -2666,16 +2683,15 @@ void snd_seq_info_clients_read(struct snd_info_entry *entry,
* REGISTRATION PART
*/
static const struct file_operations snd_seq_f_ops =
{
.owner = THIS_MODULE,
.read = snd_seq_read,
.write = snd_seq_write,
.open = snd_seq_open,
.release = snd_seq_release,
.poll = snd_seq_poll,
.unlocked_ioctl = snd_seq_ioctl,
.compat_ioctl = snd_seq_ioctl_compat,
static const struct file_operations snd_seq_f_ops = {
.owner = THIS_MODULE,
.read = snd_seq_read,
.write = snd_seq_write,
.open = snd_seq_open,
.release = snd_seq_release,
.poll = snd_seq_poll,
.unlocked_ioctl = snd_seq_ioctl,
.compat_ioctl = snd_seq_ioctl_compat,
};
static struct device *seq_dev;

View File

@ -49,7 +49,6 @@ struct snd_seq_client {
/* ports */
int num_ports; /* number of ports */
struct list_head ports_list_head;
rwlock_t ports_lock;
struct mutex ports_mutex;
struct mutex ioctl_mutex;
int convert32; /* convert 32->64bit */

View File

@ -42,9 +42,11 @@ struct seq_midisynth {
struct snd_rawmidi *rmidi;
int device;
int subdevice;
struct snd_rawmidi_substream __rcu *input_substream;
snd_use_lock_t input_use_lock; /* in-flight event_input users */
struct snd_rawmidi_file input_rfile;
spinlock_t output_lock; /* protects output_rfile publication */
snd_use_lock_t output_use_lock; /* in-flight event_input users */
struct snd_rawmidi_substream __rcu *output_substream;
struct snd_rawmidi_file output_rfile;
int seq_client;
int seq_port;
@ -76,6 +78,14 @@ static void snd_midi_input_event(struct snd_rawmidi_substream *substream)
msynth = runtime->private_data;
if (msynth == NULL)
return;
scoped_guard(rcu) {
if (rcu_dereference(msynth->input_substream) != substream)
return;
snd_use_lock_use(&msynth->input_use_lock);
}
memset(&ev, 0, sizeof(ev));
while (runtime->avail > 0) {
res = snd_rawmidi_kernel_read(substream, buf, sizeof(buf));
@ -95,6 +105,8 @@ static void snd_midi_input_event(struct snd_rawmidi_substream *substream)
memset(&ev, 0, sizeof(ev));
}
}
snd_use_lock_free(&msynth->input_use_lock);
}
static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, int count)
@ -134,8 +146,8 @@ static int event_process_midi(struct snd_seq_event *ev, int direct,
if (snd_BUG_ON(!msynth))
return -EINVAL;
scoped_guard(spinlock_irqsave, &msynth->output_lock) {
substream = msynth->output_rfile.output;
scoped_guard(rcu) {
substream = rcu_dereference(msynth->output_substream);
if (!substream)
return -ENODEV;
snd_use_lock_use(&msynth->output_use_lock);
@ -177,7 +189,7 @@ static int snd_seq_midisynth_new(struct seq_midisynth *msynth,
msynth->card = card;
msynth->device = device;
msynth->subdevice = subdevice;
spin_lock_init(&msynth->output_lock);
snd_use_lock_init(&msynth->input_use_lock);
snd_use_lock_init(&msynth->output_use_lock);
return 0;
}
@ -188,28 +200,31 @@ static int midisynth_subscribe(void *private_data, struct snd_seq_port_subscribe
int err;
struct seq_midisynth *msynth = private_data;
struct snd_rawmidi_runtime *runtime;
struct snd_rawmidi_file rfile = {};
struct snd_rawmidi_params params;
/* open midi port */
err = snd_rawmidi_kernel_open(msynth->rmidi, msynth->subdevice,
SNDRV_RAWMIDI_LFLG_INPUT,
&msynth->input_rfile);
&rfile);
if (err < 0) {
pr_debug("ALSA: seq_midi: midi input open failed!!!\n");
return err;
}
runtime = msynth->input_rfile.input->runtime;
runtime = rfile.input->runtime;
memset(&params, 0, sizeof(params));
params.avail_min = 1;
params.buffer_size = input_buffer_size;
err = snd_rawmidi_input_params(msynth->input_rfile.input, &params);
err = snd_rawmidi_input_params(rfile.input, &params);
if (err < 0) {
snd_rawmidi_kernel_release(&msynth->input_rfile);
snd_rawmidi_kernel_release(&rfile);
return err;
}
snd_midi_event_reset_encode(msynth->parser);
runtime->event = snd_midi_input_event;
runtime->private_data = msynth;
msynth->input_rfile = rfile;
rcu_assign_pointer(msynth->input_substream, rfile.input);
snd_rawmidi_kernel_read(msynth->input_rfile.input, NULL, 0);
return 0;
}
@ -219,10 +234,19 @@ static int midisynth_unsubscribe(void *private_data, struct snd_seq_port_subscri
{
int err;
struct seq_midisynth *msynth = private_data;
struct snd_rawmidi_file rfile;
if (snd_BUG_ON(!msynth->input_rfile.input))
rcu_assign_pointer(msynth->input_substream, NULL);
synchronize_rcu();
snd_use_lock_sync(&msynth->input_use_lock);
rfile = msynth->input_rfile;
msynth->input_rfile = (struct snd_rawmidi_file){};
if (snd_BUG_ON(!rfile.input))
return -EINVAL;
err = snd_rawmidi_kernel_release(&msynth->input_rfile);
err = snd_rawmidi_kernel_release(&rfile);
return err;
}
@ -252,8 +276,8 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info
return err;
}
snd_midi_event_reset_decode(msynth->parser);
scoped_guard(spinlock_irqsave, &msynth->output_lock)
msynth->output_rfile = rfile;
msynth->output_rfile = rfile;
rcu_assign_pointer(msynth->output_substream, rfile.output);
return 0;
}
@ -261,17 +285,16 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info
static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *info)
{
struct seq_midisynth *msynth = private_data;
struct snd_rawmidi_file rfile = {};
struct snd_rawmidi_file rfile;
scoped_guard(spinlock_irqsave, &msynth->output_lock) {
rfile = msynth->output_rfile;
msynth->output_rfile = (struct snd_rawmidi_file){};
}
rcu_assign_pointer(msynth->output_substream, NULL);
synchronize_rcu();
snd_use_lock_sync(&msynth->output_use_lock);
rfile = msynth->output_rfile;
msynth->output_rfile = (struct snd_rawmidi_file){};
if (snd_BUG_ON(!rfile.output))
return -EINVAL;
snd_use_lock_sync(&msynth->output_use_lock);
snd_rawmidi_drain_output(rfile.output);
return snd_rawmidi_kernel_release(&rfile);
}

View File

@ -48,8 +48,8 @@ struct snd_seq_client_port *snd_seq_port_use_ptr(struct snd_seq_client *client,
if (client == NULL)
return NULL;
guard(read_lock)(&client->ports_lock);
list_for_each_entry(port, &client->ports_list_head, list) {
guard(rcu)();
list_for_each_entry_rcu(port, &client->ports_list_head, list) {
if (port->addr.port == num) {
if (port->closing)
break; /* deleting now */
@ -71,8 +71,8 @@ struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *cl
num = pinfo->addr.port;
found = NULL;
guard(read_lock)(&client->ports_lock);
list_for_each_entry(port, &client->ports_list_head, list) {
guard(rcu)();
list_for_each_entry_rcu(port, &client->ports_list_head, list) {
if ((port->capability & SNDRV_SEQ_PORT_CAP_INACTIVE) &&
!check_inactive)
continue; /* skip inactive ports */
@ -98,10 +98,9 @@ struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *cl
/* initialize snd_seq_port_subs_info */
static void port_subs_info_init(struct snd_seq_port_subs_info *grp)
{
INIT_LIST_HEAD(&grp->list_head);
INIT_HLIST_HEAD(&grp->list_head);
grp->count = 0;
grp->exclusive = 0;
rwlock_init(&grp->list_lock);
init_rwsem(&grp->list_mutex);
grp->open = NULL;
grp->close = NULL;
@ -154,7 +153,6 @@ int snd_seq_insert_port(struct snd_seq_client *client, int port,
num = max(port, 0);
guard(mutex)(&client->ports_mutex);
guard(write_lock_irq)(&client->ports_lock);
struct list_head *insert_before = &client->ports_list_head;
list_for_each_entry(p, &client->ports_list_head, list) {
if (p->addr.port == port)
@ -166,12 +164,13 @@ int snd_seq_insert_port(struct snd_seq_client *client, int port,
if (port < 0) /* auto-probe mode */
num = p->addr.port + 1;
}
/* insert the new port */
list_add_tail(&new_port->list, insert_before);
client->num_ports++;
/* finish initializing the port before publishing it to RCU readers */
new_port->addr.port = num; /* store the port number in the port */
if (!new_port->name[0])
sprintf(new_port->name, "port-%d", num);
/* insert the new port */
list_add_tail_rcu(&new_port->list, insert_before);
client->num_ports++;
return num;
}
@ -202,12 +201,12 @@ static void delete_and_unsubscribe_port(struct snd_seq_client *client,
bool is_src, bool ack);
static inline struct snd_seq_subscribers *
get_subscriber(struct list_head *p, bool is_src)
get_subscriber(struct hlist_node *p, bool is_src)
{
if (is_src)
return list_entry(p, struct snd_seq_subscribers, src_list);
return hlist_entry(p, struct snd_seq_subscribers, src_list);
else
return list_entry(p, struct snd_seq_subscribers, dest_list);
return hlist_entry(p, struct snd_seq_subscribers, dest_list);
}
/*
@ -219,9 +218,9 @@ static void clear_subscriber_list(struct snd_seq_client *client,
struct snd_seq_port_subs_info *grp,
int is_src)
{
struct list_head *p, *n;
struct hlist_node *p, *n;
list_for_each_safe(p, n, &grp->list_head) {
hlist_for_each_safe(p, n, &grp->list_head) {
struct snd_seq_subscribers *subs;
subs = get_subscriber(p, is_src);
@ -238,13 +237,13 @@ static void clear_subscriber_list(struct snd_seq_client *client,
* remove the subscriber info
*/
if (atomic_dec_and_test(&subs->ref_count))
kfree(subs);
kfree_rcu(subs, rcu);
continue;
}
/* ok we got the connected port */
delete_and_unsubscribe_port(c, aport, subs, !is_src, true);
kfree(subs);
kfree_rcu(subs, rcu);
}
}
@ -254,7 +253,13 @@ static int port_delete(struct snd_seq_client *client,
{
/* set closing flag and wait for all port access are gone */
port->closing = 1;
snd_use_lock_sync(&port->use_lock);
/* the port has already been unlinked from the client's port list;
* wait for a grace period so that RCU readers still traversing the
* list can no longer take a new use_lock reference, then drain the
* outstanding references before freeing
*/
synchronize_rcu();
snd_use_lock_sync(&port->use_lock);
/* clear subscribers info */
clear_subscriber_list(client, port, &port->c_src, true);
@ -277,11 +282,10 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port)
struct snd_seq_client_port *found = NULL, *p;
scoped_guard(mutex, &client->ports_mutex) {
guard(write_lock_irq)(&client->ports_lock);
list_for_each_entry(p, &client->ports_list_head, list) {
if (p->addr.port == port) {
/* ok found. delete from the list at first */
list_del(&p->list);
list_del_rcu(&p->list);
client->num_ports--;
found = p;
break;
@ -297,26 +301,16 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port)
/* delete the all ports belonging to the given client */
int snd_seq_delete_all_ports(struct snd_seq_client *client)
{
struct list_head deleted_list;
struct snd_seq_client_port *port, *tmp;
/* move the port list to deleted_list, and
* clear the port list in the client data.
/* unlink and delete each port; port_delete() waits for an RCU grace
* period before draining the port, so concurrent lockless readers can
* no longer take a new use_lock reference on it
*/
guard(mutex)(&client->ports_mutex);
scoped_guard(write_lock_irq, &client->ports_lock) {
if (!list_empty(&client->ports_list_head)) {
list_add(&deleted_list, &client->ports_list_head);
list_del_init(&client->ports_list_head);
} else {
INIT_LIST_HEAD(&deleted_list);
}
client->num_ports = 0;
}
/* remove each port in deleted_list */
list_for_each_entry_safe(port, tmp, &deleted_list, list) {
list_del(&port->list);
list_for_each_entry_safe(port, tmp, &client->ports_list_head, list) {
list_del_rcu(&port->list);
client->num_ports--;
snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port);
port_delete(client, port);
}
@ -499,20 +493,20 @@ static int check_and_subscribe_port(struct snd_seq_client *client,
bool is_src, bool exclusive, bool ack)
{
struct snd_seq_port_subs_info *grp;
struct list_head *p;
struct hlist_node *p;
struct snd_seq_subscribers *s;
int err;
grp = is_src ? &port->c_src : &port->c_dest;
guard(rwsem_write)(&grp->list_mutex);
if (exclusive) {
if (!list_empty(&grp->list_head))
if (!hlist_empty(&grp->list_head))
return -EBUSY;
} else {
if (grp->exclusive)
return -EBUSY;
/* check whether already exists */
list_for_each(p, &grp->list_head) {
hlist_for_each(p, &grp->list_head) {
s = get_subscriber(p, is_src);
if (match_subs_info(&subs->info, &s->info))
return -EBUSY;
@ -526,11 +520,10 @@ static int check_and_subscribe_port(struct snd_seq_client *client,
}
/* add to list */
guard(write_lock_irq)(&grp->list_lock);
if (is_src)
list_add_tail(&subs->src_list, &grp->list_head);
hlist_add_tail_rcu(&subs->src_list, &grp->list_head);
else
list_add_tail(&subs->dest_list, &grp->list_head);
hlist_add_tail_rcu(&subs->dest_list, &grp->list_head);
grp->exclusive = exclusive;
atomic_inc(&subs->ref_count);
@ -544,17 +537,15 @@ static void __delete_and_unsubscribe_port(struct snd_seq_client *client,
bool is_src, bool ack)
{
struct snd_seq_port_subs_info *grp;
struct list_head *list;
struct hlist_node *list;
bool empty;
grp = is_src ? &port->c_src : &port->c_dest;
list = is_src ? &subs->src_list : &subs->dest_list;
scoped_guard(write_lock_irq, &grp->list_lock) {
empty = list_empty(list);
if (!empty)
list_del_init(list);
grp->exclusive = 0;
}
empty = hlist_unhashed(list);
if (!empty)
hlist_del_init_rcu(list);
grp->exclusive = 0;
if (!empty)
unsubscribe_port(client, port, grp, &subs->info, ack);
@ -590,8 +581,8 @@ int snd_seq_port_connect(struct snd_seq_client *connector,
subs->info = *info;
atomic_set(&subs->ref_count, 0);
INIT_LIST_HEAD(&subs->src_list);
INIT_LIST_HEAD(&subs->dest_list);
INIT_HLIST_NODE(&subs->src_list);
INIT_HLIST_NODE(&subs->dest_list);
exclusive = !!(info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE);
@ -612,7 +603,7 @@ int snd_seq_port_connect(struct snd_seq_client *connector,
delete_and_unsubscribe_port(src_client, src_port, subs, true,
connector->number != src_client->number);
error:
kfree(subs);
kfree_rcu(subs, rcu);
return err;
}
@ -633,7 +624,7 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector,
*/
scoped_guard(rwsem_write, &dest->list_mutex) {
/* look for the connection */
list_for_each_entry(subs, &dest->list_head, dest_list) {
hlist_for_each_entry(subs, &dest->list_head, dest_list) {
if (match_subs_info(info, &subs->info)) {
__delete_and_unsubscribe_port(dest_client, dest_port,
subs, false,
@ -648,7 +639,7 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector,
delete_and_unsubscribe_port(src_client, src_port, subs, true,
connector->number != src_client->number);
kfree(subs);
kfree_rcu(subs, rcu);
return 0;
}
@ -662,7 +653,7 @@ int snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp,
int err = -ENOENT;
guard(rwsem_read)(&src_grp->list_mutex);
list_for_each_entry(s, &src_grp->list_head, src_list) {
hlist_for_each_entry(s, &src_grp->list_head, src_list) {
if (addr_match(dest_addr, &s->info.dest)) {
*subs = s->info;
err = 0;

View File

@ -28,17 +28,17 @@
struct snd_seq_subscribers {
struct snd_seq_port_subscribe info; /* additional info */
struct list_head src_list; /* link of sources */
struct list_head dest_list; /* link of destinations */
struct hlist_node src_list; /* link of sources */
struct hlist_node dest_list; /* link of destinations */
atomic_t ref_count;
struct rcu_head rcu; /* for deferred free */
};
struct snd_seq_port_subs_info {
struct list_head list_head; /* list of subscribed ports */
struct hlist_head list_head; /* list of subscribed ports */
unsigned int count; /* count of subscribers */
unsigned int exclusive: 1; /* exclusive mode */
struct rw_semaphore list_mutex;
rwlock_t list_lock;
int (*open)(void *private_data, struct snd_seq_port_subscribe *info);
int (*close)(void *private_data, struct snd_seq_port_subscribe *info);
};

View File

@ -37,8 +37,11 @@ struct seq_ump_client {
struct snd_ump_endpoint *ump; /* assigned endpoint */
int seq_client; /* sequencer client id */
int opened[2]; /* current opens for each direction */
rwlock_t output_lock; /* protects out_rfile output access */
struct snd_rawmidi_file out_rfile; /* rawmidi for output */
/* RCU-protected shadow of out_rfile.output for the delivery hot path;
* out_rfile itself is only touched by open/close under open_mutex
*/
struct snd_rawmidi_substream __rcu *out_substream;
struct seq_ump_input_buffer input; /* input parser context */
void *ump_info[SNDRV_UMP_MAX_BLOCKS + 1]; /* shadow of seq client ump_info */
struct work_struct group_notify_work; /* FB change notification */
@ -89,8 +92,8 @@ static int seq_ump_process_event(struct snd_seq_event *ev, int direct,
unsigned char type;
int len;
guard(read_lock_irqsave)(&client->output_lock);
substream = client->out_rfile.output;
guard(rcu)();
substream = rcu_dereference(client->out_substream);
if (!substream)
return -ENODEV;
if (!snd_seq_ev_is_ump(ev))
@ -108,19 +111,22 @@ static int seq_ump_process_event(struct snd_seq_event *ev, int direct,
static int seq_ump_client_open(struct seq_ump_client *client, int dir)
{
struct snd_ump_endpoint *ump = client->ump;
struct snd_rawmidi_file rfile = {};
int err;
guard(mutex)(&ump->open_mutex);
if (dir == STR_OUT && !client->opened[dir]) {
/* out_rfile is only accessed under open_mutex; the delivery
* path reads out_substream via RCU, so open into out_rfile
* directly and publish the substream afterwards
*/
err = snd_rawmidi_kernel_open(&ump->core, 0,
SNDRV_RAWMIDI_LFLG_OUTPUT |
SNDRV_RAWMIDI_LFLG_APPEND,
&rfile);
&client->out_rfile);
if (err < 0)
return err;
scoped_guard(write_lock_irqsave, &client->output_lock)
client->out_rfile = rfile;
rcu_assign_pointer(client->out_substream,
client->out_rfile.output);
}
client->opened[dir]++;
return 0;
@ -130,17 +136,18 @@ static int seq_ump_client_open(struct seq_ump_client *client, int dir)
static int seq_ump_client_close(struct seq_ump_client *client, int dir)
{
struct snd_ump_endpoint *ump = client->ump;
struct snd_rawmidi_file rfile = {};
guard(mutex)(&ump->open_mutex);
if (!--client->opened[dir]) {
if (dir == STR_OUT) {
scoped_guard(write_lock_irqsave, &client->output_lock) {
rfile = client->out_rfile;
client->out_rfile = (struct snd_rawmidi_file){};
}
if (rfile.rmidi)
snd_rawmidi_kernel_release(&rfile);
if (dir == STR_OUT && client->out_rfile.rmidi) {
rcu_assign_pointer(client->out_substream, NULL);
/* wait for a grace period so that no reader in the
* delivery path is still writing to the substream
* before it is released
*/
synchronize_rcu();
snd_rawmidi_kernel_release(&client->out_rfile);
client->out_rfile = (struct snd_rawmidi_file){};
}
}
return 0;
@ -480,7 +487,6 @@ static int snd_seq_ump_probe(struct snd_seq_device *dev)
INIT_WORK(&client->group_notify_work, handle_group_notify);
client->ump = ump;
rwlock_init(&client->output_lock);
client->seq_client =
snd_seq_create_kernel_client(card, ump->core.device,

View File

@ -78,10 +78,11 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
int len;
if (atomic)
read_lock(&rdev->filelist_lock);
rcu_read_lock();
else
down_read(&rdev->filelist_sem);
list_for_each_entry(vmidi, &rdev->filelist, list) {
list_for_each_entry_rcu(vmidi, &rdev->filelist, list,
lockdep_is_held(&rdev->filelist_sem)) {
if (!READ_ONCE(vmidi->trigger))
continue;
if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
@ -96,7 +97,7 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
}
}
if (atomic)
read_unlock(&rdev->filelist_lock);
rcu_read_unlock();
else
up_read(&rdev->filelist_sem);
@ -200,8 +201,7 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream)
vmidi->port = rdev->port;
runtime->private_data = vmidi;
scoped_guard(rwsem_write, &rdev->filelist_sem) {
guard(write_lock_irq)(&rdev->filelist_lock);
list_add_tail(&vmidi->list, &rdev->filelist);
list_add_tail_rcu(&vmidi->list, &rdev->filelist);
}
vmidi->rdev = rdev;
return 0;
@ -243,9 +243,13 @@ static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream)
struct snd_virmidi *vmidi = substream->runtime->private_data;
scoped_guard(rwsem_write, &rdev->filelist_sem) {
guard(write_lock_irq)(&rdev->filelist_lock);
list_del(&vmidi->list);
list_del_rcu(&vmidi->list);
}
/* wait for a grace period so that lockless readers in the atomic
* delivery path (snd_virmidi_dev_receive_event()) are no longer
* traversing this entry before its parser and memory are freed
*/
synchronize_rcu();
snd_midi_event_free(vmidi->parser);
substream->runtime->private_data = NULL;
kfree(vmidi);
@ -508,7 +512,6 @@ int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmi
rdev->device = device;
rdev->client = -1;
init_rwsem(&rdev->filelist_sem);
rwlock_init(&rdev->filelist_lock);
INIT_LIST_HEAD(&rdev->filelist);
rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH;
rmidi->private_data = rdev;

View File

@ -167,11 +167,10 @@ static int snd_open(struct inode *inode, struct file *file)
return err;
}
static const struct file_operations snd_fops =
{
.owner = THIS_MODULE,
.open = snd_open,
.llseek = noop_llseek,
static const struct file_operations snd_fops = {
.owner = THIS_MODULE,
.open = snd_open,
.llseek = noop_llseek,
};
#ifdef CONFIG_SND_DYNAMIC_MINORS
@ -358,7 +357,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu
struct snd_minor *mptr;
guard(mutex)(&sound_mutex);
for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) {
for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) {
mptr = snd_minors[minor];
if (!mptr)
continue;
@ -395,15 +394,21 @@ int __init snd_minor_info_init(void)
static int __init alsa_sound_init(void)
{
int err;
snd_major = major;
snd_ecards_limit = cards_limit;
if (register_chrdev(major, "alsa", &snd_fops)) {
err = register_chrdev(major, "alsa", &snd_fops);
if (err < 0) {
pr_err("ALSA core: unable to register native major device number %d\n", major);
return -EIO;
return err;
}
if (snd_info_init() < 0) {
err = snd_info_init();
if (err < 0) {
unregister_chrdev(major, "alsa");
return -ENOMEM;
return err;
}
#ifdef CONFIG_SND_DEBUG

View File

@ -17,8 +17,8 @@
.name = #fmt, \
}
#define WRONG_FORMAT_1 (__force snd_pcm_format_t)((__force int)SNDRV_PCM_FORMAT_LAST + 1)
#define WRONG_FORMAT_2 (__force snd_pcm_format_t)-1
#define WRONG_FORMAT_1 (SNDRV_PCM_FORMAT_LAST + 1)
#define WRONG_FORMAT_2 -1
#define VALID_NAME "ValidName"
#define NAME_W_SPEC_CHARS "In%v@1id name"

View File

@ -1546,11 +1546,8 @@ static int realloc_user_queue(struct snd_timer_user *tu, int size)
static int snd_timer_user_open(struct inode *inode, struct file *file)
{
struct snd_timer_user *tu;
int err;
err = stream_open(inode, file);
if (err < 0)
return err;
stream_open(inode, file);
tu = kzalloc_obj(*tu);
if (tu == NULL)
@ -2176,9 +2173,9 @@ static long snd_utimer_ioctl(struct file *file, unsigned int ioctl, unsigned lon
}
static const struct file_operations snd_utimer_fops = {
.llseek = noop_llseek,
.release = snd_utimer_release,
.unlocked_ioctl = snd_utimer_ioctl,
.llseek = noop_llseek,
.release = snd_utimer_release,
.unlocked_ioctl = snd_utimer_ioctl,
};
static int snd_utimer_start(struct snd_timer *t)
@ -2530,16 +2527,15 @@ static __poll_t snd_timer_user_poll(struct file *file, poll_table * wait)
#define snd_timer_user_ioctl_compat NULL
#endif
static const struct file_operations snd_timer_f_ops =
{
.owner = THIS_MODULE,
.read = snd_timer_user_read,
.open = snd_timer_user_open,
.release = snd_timer_user_release,
.poll = snd_timer_user_poll,
.unlocked_ioctl = snd_timer_user_ioctl,
.compat_ioctl = snd_timer_user_ioctl_compat,
.fasync = snd_timer_user_fasync,
static const struct file_operations snd_timer_f_ops = {
.owner = THIS_MODULE,
.read = snd_timer_user_read,
.open = snd_timer_user_open,
.release = snd_timer_user_release,
.poll = snd_timer_user_poll,
.unlocked_ioctl = snd_timer_user_ioctl,
.compat_ioctl = snd_timer_user_ioctl_compat,
.fasync = snd_timer_user_fasync,
};
/* unregister the system timer */

View File

@ -1157,10 +1157,11 @@ static int snd_ump_legacy_open(struct snd_rawmidi_substream *substream)
return -ENODEV;
if (dir == SNDRV_RAWMIDI_STREAM_OUTPUT) {
if (!ump->legacy_out_opens) {
err = snd_rawmidi_kernel_open(&ump->core, 0,
SNDRV_RAWMIDI_LFLG_OUTPUT |
SNDRV_RAWMIDI_LFLG_APPEND,
&ump->legacy_out_rfile);
err = snd_rawmidi_kernel_open_nested(&ump->core, 0,
SNDRV_RAWMIDI_LFLG_OUTPUT |
SNDRV_RAWMIDI_LFLG_APPEND,
&ump->legacy_out_rfile,
SINGLE_DEPTH_NESTING);
if (err < 0)
return err;
}

Some files were not shown because too many files have changed in this diff Show More