sound updates for 5.10

The amount of changes is smaller at this round (what a surprise),
 but lots of activity is seen.  Most of changes are about ASoC
 driver development, especially Intel platforms.
 Here are some highlights:
 
 General:
 * Replace all tasklet usages with other alternatives
 * Cleanup of the ASoC error unwinding code
 * Fixes for trivial issues caught by static checker
 * Spell fixes allover the places
 
 ALSA Core:
 * Lockdep fix for control devices
 * Fix for potential OSS sequencer mutex stalls
 
 HD-audio and USB-audio:
 * SoundBlaster AE-7 support
 * Changes in quirk table for the rename handling
 * Quirks for HP and ASUS machines, Pioneer DJ DJM-250MK2.
 
 ASoC:
 * Lots of updates for Intel SOF and SoundWire enablement
 * Replacement of the DSP driver for some older x86 systems;
   the new code was written from scratch, better maintenance
   expected
 * Helpers for parsing auxiluary devices from the device tree
 * New support for AllWinner A64, Cirrus Logic CS4234, Mediatek
   MT6359 Microchip S/PDIF TX and RX controllers, Realtek RT1015P,
   and Texas Instruments J721E, TAS2110, TAS2564 and TAS2764
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAl+HHD4OHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE9eAw//Wgs9LfQE3rBcsGVNTHimW2cPzbdHVK1eth6N
 pFT6rdEG2N+ALR0ESA26CSBniJocqxNvXYzaYT0fy+7tS/chOjhkfr6SttYPDmwc
 q2u1SQIqdx41Q0DVUXYxSLVExjT4Rx96qeibLy5pi8DsbL0DOVa7PkVDl1XHXNJ0
 iSZwA18gCRdezpoOCD+UF8EBplULjYfPp0xstqjaQzTCpJQ5C1xpbZdHWfhTWsKo
 H98d4GL4yUUbJb5/Wi7uqiUGhPIxgBUMVkaY+uRifeNA/MGD5rUZQaf8ft6uQFUL
 D5RCUksJiQfyrj++g9/mzOWVRCFZ6MvaAmEW4xwlPvTsP2uIVIqS5RH8Z2BhwjXr
 J8/4gPuCtoEKbfsOOCOG9MlGsquf9LBeiH5KZ7gqb7ilu4tICR2zXtBr6U7e64Wd
 LsPROQnr/+lxIlEJjlhiarf1jXMfo4glxuoLsDcIH+Baf0lTiMNoBVIZTUdJ0urq
 Srh++Bk/WGvoVJe1PHp7IfhZCoBACozPXq7EifbnCsUM+cVtQtjWrydyi8k/Yona
 5EfS5wQdEH6JvQirkmGJm8kNMu+e3hW2HzoJqV2Z2DUMMnCSra62KD0wPA/wRchu
 mkC47875a+jgo58fq4bX9hzGi2CrE/TMYdii6I2bbAm/Mp7czXZfO0LOTWDc4Bs5
 T8qt+HI=
 =nWAp
 -----END PGP SIGNATURE-----

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

Pull sound updates from Takashi Iwai:
 "The amount of changes is smaller at this round (what a surprise), but
  lots of activity is seen. Most of changes are about ASoC driver
  development, especially Intel platforms. Here are some highlights:

  General:
   - Replace all tasklet usages with other alternatives
   - Cleanup of the ASoC error unwinding code
   - Fixes for trivial issues caught by static checker
   - Spell fixes allover the places

  ALSA Core:
   - Lockdep fix for control devices
   - Fix for potential OSS sequencer mutex stalls

  HD-audio and USB-audio:
   - SoundBlaster AE-7 support
   - Changes in quirk table for the rename handling
   - Quirks for HP and ASUS machines, Pioneer DJ DJM-250MK2.

  ASoC:
   - Lots of updates for Intel SOF and SoundWire enablement
   - Replacement of the DSP driver for some older x86 systems; the new
     code was written from scratch, better maintenance expected
   - Helpers for parsing auxiluary devices from the device tree
   - New support for AllWinner A64, Cirrus Logic CS4234, Mediatek MT6359
     Microchip S/PDIF TX and RX controllers, Realtek RT1015P, and Texas
     Instruments J721E, TAS2110, TAS2564 and TAS2764"

* tag 'sound-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (498 commits)
  ALSA: hda/hdmi: fix incorrect locking in hdmi_pcm_close
  ALSA: hda: fix jack detection with Realtek codecs when in D3
  ALSA: fireworks: use semicolons rather than commas to separate statements
  ALSA: hda: use semicolons rather than commas to separate statements
  ALSA: hda/i915 - fix list corruption with concurrent probes
  ASoC: dmaengine: Document support for TX only or RX only streams
  ASoC: mchp-spdiftx: remove 'TX' from playback stream name
  ASoC: ti: davinci-mcasp: Use &pdev->dev for early dev_warn
  ASoC: tas2764: Add the driver for the TAS2764
  dt-bindings: tas2764: Add the TAS2764 binding doc
  ASoC: Intel: catpt: Add explicit DMADEVICES kconfig dependency
  ASoC: Intel: catpt: Fix compilation when CONFIG_MODULES is disabled
  ASoC: stm32: dfsdm: add actual resolution trace
  ASoC: stm32: dfsdm: change rate limits
  ASoC: qcom: sc7180: Add support for audio over DP
  Asoc: qcom: lpass-platform : Increase buffer size
  ASoC: qcom: Add support for lpass hdmi driver
  Asoc: qcom: lpass:Update lpaif_dmactl members order
  Asoc:qcom:lpass-cpu:Update dts property read API
  ASoC: dt-bindings: Add dt binding for lpass hdmi
  ...
This commit is contained in:
Linus Torvalds 2020-10-15 11:07:44 -07:00
commit c48b75b727
380 changed files with 25571 additions and 13559 deletions

View File

@ -0,0 +1,16 @@
What: /sys/devices/pci0000:00/<dev>/fw_version
Date: September 2020
Contact: Cezary Rojewski <cezary.rojewski@intel.com>
Description:
Version of AudioDSP firmware ASoC catpt driver is
communicating with.
Format: %d.%d.%d.%d, type:major:minor:build.
What: /sys/devices/pci0000:00/<dev>/fw_info
Date: September 2020
Contact: Cezary Rojewski <cezary.rojewski@intel.com>
Description:
Detailed AudioDSP firmware build information including
build hash and log-providers hash. This information is
obtained during initial handshake with firmware.
Format: %s.

View File

@ -10,6 +10,11 @@ Required properties:
Optional properties:
- reset-gpios: A GPIO specifier for the power down & reset pin
- mute-gpios: A GPIO specifier for the soft mute pin
- AVDD-supply: Analog power supply
- DVDD-supply: Digital power supply
- dsd-path: Select DSD input pins for ak4497
0: select #16, #17, #19 pins
1: select #3, #4, #5 pins
Example:

View File

@ -10,6 +10,8 @@ Required properties:
Optional properties:
- reset-gpios: A GPIO specifier for the power down & reset pin.
- AVDD-supply: Analog power supply
- DVDD-supply: Digital power supply
Example:

View File

@ -15,7 +15,11 @@ properties:
const: 0
compatible:
const: allwinner,sun8i-a33-codec
oneOf:
- items:
- const: allwinner,sun50i-a64-codec
- const: allwinner,sun8i-a33-codec
- const: allwinner,sun8i-a33-codec
reg:
maxItems: 1

View File

@ -0,0 +1,74 @@
# SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/cirrus,cs4234.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Cirrus Logic cs4234 audio CODEC
maintainers:
- patches@opensource.cirrus.com
description:
The CS4234 is a highly versatile CODEC that combines 4 channels of
high performance analog to digital conversion, 4 channels of high
performance digital to analog conversion for audio, and 1 channel of
digital to analog conversion to provide a nondelayed audio reference
signal to an external Class H tracking power supply. If not used to
drive a tracking power supply, the 5th DAC can instead be used as a
standard audio grade DAC, with performance specifications identical
to that of the 4 DACs in the audio path. Additionally, the CS4234
includes tunable group delay for each of the 4 audio DAC paths to
provide lead time for the external switch-mode power supply, and a
nondelayed path into the DAC outputs for input signals requiring a
low-latency path to the outputs.
properties:
compatible:
enum:
- cirrus,cs4234
reg:
description:
The 7-bit I2C address depends on the state of the ADx pins, in
binary given by [0 0 1 0 AD2 AD1 AD0 0].
items:
minimum: 0x10
maximum: 0x17
VA-supply:
description:
Analogue power supply.
VL-supply:
description:
Interface power supply.
reset-gpios:
maxItems: 1
required:
- compatible
- reg
- VA-supply
- VL-supply
additionalProperties: false
examples:
- |
i2c@e0004000 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0xe0004000 0x1000>;
cs4234: codec@11 {
compatible = "cirrus,cs4234";
reg = <0x11>;
VA-supply = <&vdd3v3>;
VL-supply = <&vdd3v3>;
reset-gpios = <&gpio 0>;
};
};

View File

@ -1,68 +0,0 @@
Freescale Sony/Philips Digital Interface Format (S/PDIF) Controller
The Freescale S/PDIF audio block is a stereo transceiver that allows the
processor to receive and transmit digital audio via an coaxial cable or
a fibre cable.
Required properties:
- compatible : Compatible list, should contain one of the following
compatibles:
"fsl,imx35-spdif",
"fsl,vf610-spdif",
"fsl,imx6sx-spdif",
- reg : Offset and length of the register set for the device.
- interrupts : Contains the spdif interrupt.
- dmas : Generic dma devicetree binding as described in
Documentation/devicetree/bindings/dma/dma.txt.
- dma-names : Two dmas have to be defined, "tx" and "rx".
- clocks : Contains an entry for each entry in clock-names.
- clock-names : Includes the following entries:
"core" The core clock of spdif controller.
"rxtx<0-7>" Clock source list for tx and rx clock.
This clock list should be identical to the source
list connecting to the spdif clock mux in "SPDIF
Transceiver Clock Diagram" of SoC reference manual.
It can also be referred to TxClk_Source bit of
register SPDIF_STC.
"spba" The spba clock is required when SPDIF is placed as a
bus slave of the Shared Peripheral Bus and when two
or more bus masters (CPU, DMA or DSP) try to access
it. This property is optional depending on the SoC
design.
Optional properties:
- big-endian : If this property is absent, the native endian mode
will be in use as default, or the big endian mode
will be in use for all the device registers.
Example:
spdif: spdif@2004000 {
compatible = "fsl,imx35-spdif";
reg = <0x02004000 0x4000>;
interrupts = <0 52 0x04>;
dmas = <&sdma 14 18 0>,
<&sdma 15 18 0>;
dma-names = "rx", "tx";
clocks = <&clks 197>, <&clks 3>,
<&clks 197>, <&clks 107>,
<&clks 0>, <&clks 118>,
<&clks 62>, <&clks 139>,
<&clks 0>;
clock-names = "core", "rxtx0",
"rxtx1", "rxtx2",
"rxtx3", "rxtx4",
"rxtx5", "rxtx6",
"rxtx7";
big-endian;
};

View File

@ -0,0 +1,110 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/fsl,spdif.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale Sony/Philips Digital Interface Format (S/PDIF) Controller
maintainers:
- Shengjiu Wang <shengjiu.wang@nxp.com>
description: |
The Freescale S/PDIF audio block is a stereo transceiver that allows the
processor to receive and transmit digital audio via an coaxial cable or
a fibre cable.
properties:
compatible:
enum:
- fsl,imx35-spdif
- fsl,vf610-spdif
- fsl,imx6sx-spdif
reg:
maxItems: 1
interrupts:
maxItems: 1
dmas:
items:
- description: DMA controller phandle and request line for RX
- description: DMA controller phandle and request line for TX
dma-names:
items:
- const: rx
- const: tx
clocks:
items:
- description: The core clock of spdif controller.
- description: Clock for tx0 and rx0.
- description: Clock for tx1 and rx1.
- description: Clock for tx2 and rx2.
- description: Clock for tx3 and rx3.
- description: Clock for tx4 and rx4.
- description: Clock for tx5 and rx5.
- description: Clock for tx6 and rx6.
- description: Clock for tx7 and rx7.
- description: The spba clock is required when SPDIF is placed as a bus
slave of the Shared Peripheral Bus and when two or more bus masters
(CPU, DMA or DSP) try to access it. This property is optional depending
on the SoC design.
minItems: 9
clock-names:
items:
- const: core
- const: rxtx0
- const: rxtx1
- const: rxtx2
- const: rxtx3
- const: rxtx4
- const: rxtx5
- const: rxtx6
- const: rxtx7
- const: spba
minItems: 9
big-endian:
$ref: /schemas/types.yaml#/definitions/flag
description: |
If this property is absent, the native endian mode will be in use
as default, or the big endian mode will be in use for all the device
registers. Set this flag for HCDs with big endian descriptors and big
endian registers.
required:
- compatible
- reg
- interrupts
- dmas
- dma-names
- clocks
- clock-names
additionalProperties: false
examples:
- |
spdif@2004000 {
compatible = "fsl,imx35-spdif";
reg = <0x02004000 0x4000>;
interrupts = <0 52 0x04>;
dmas = <&sdma 14 18 0>,
<&sdma 15 18 0>;
dma-names = "rx", "tx";
clocks = <&clks 197>, <&clks 3>,
<&clks 197>, <&clks 107>,
<&clks 0>, <&clks 118>,
<&clks 62>, <&clks 139>,
<&clks 0>;
clock-names = "core", "rxtx0",
"rxtx1", "rxtx2",
"rxtx3", "rxtx4",
"rxtx5", "rxtx6",
"rxtx7";
big-endian;
};

View File

@ -38,6 +38,8 @@ The compatible list for this generic sound card currently:
"fsl,imx-audio-wm8524"
"fsl,imx-audio-tlv320aic32x4"
Required properties:
- compatible : Contains one of entries in the compatible list.

View File

@ -17,6 +17,7 @@ properties:
compatible:
enum:
- intel,keembay-i2s
- intel,keembay-tdm
"#sound-dai-cells":
const: 0

View File

@ -55,5 +55,5 @@ audio-codec@10 {
compatible = "maxim,max98090";
reg = <0x10>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
interrupts = <TEGRA_GPIO(H, 4) IRQ_TYPE_LEVEL_HIGH>;
};

View File

@ -0,0 +1,73 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/mchp,spdifrx.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip S/PDIF Rx Controller Device Tree Bindings
maintainers:
- Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
description:
The Microchip Sony/Philips Digital Interface Receiver is a
serial port compliant with the IEC-60958 standard.
properties:
"#sound-dai-cells":
const: 0
compatible:
const: microchip,sama7g5-spdifrx
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
items:
- description: Peripheral Bus Clock
- description: Generic Clock
clock-names:
items:
- const: pclk
- const: gclk
dmas:
description: RX DMA Channel
maxItems: 1
dma-names:
const: rx
required:
- "#sound-dai-cells"
- compatible
- reg
- interrupts
- clocks
- clock-names
- dmas
- dma-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/at91.h>
#include <dt-bindings/dma/at91.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
spdifrx: spdifrx@e1614000 {
#sound-dai-cells = <0>;
compatible = "microchip,sama7g5-spdifrx";
reg = <0xe1614000 0x4000>;
interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&dma0 AT91_XDMAC_DT_PERID(49)>;
dma-names = "rx";
clocks = <&pmc PMC_TYPE_PERIPHERAL 84>, <&pmc PMC_TYPE_GCK 84>;
clock-names = "pclk", "gclk";
};

View File

@ -0,0 +1,75 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/mchp,spdiftx.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip S/PDIF Tx Controller Device Tree Bindings
maintainers:
- Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
description:
The Microchip Sony/Philips Digital Interface Transmitter is a
serial port compliant with the IEC-60958 standard.
properties:
"#sound-dai-cells":
const: 0
compatible:
const: microchip,sama7g5-spdiftx
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
items:
- description: Peripheral Bus Clock
- description: Generic Clock
clock-names:
items:
- const: pclk
- const: gclk
dmas:
description: TX DMA Channel
maxItems: 1
dma-names:
const: tx
required:
- "#sound-dai-cells"
- compatible
- reg
- interrupts
- clocks
- clock-names
- dmas
- dma-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/at91.h>
#include <dt-bindings/dma/at91.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
spdiftx@e1618000 {
#sound-dai-cells = <0>;
compatible = "microchip,sama7g5-spdiftx";
reg = <0xe1618000 0x4000>;
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&dma0 AT91_XDMAC_DT_PERID(50)>;
dma-names = "tx";
clocks = <&pmc PMC_TYPE_PERIPHERAL 85>, <&pmc PMC_TYPE_GCK 85>;
clock-names = "pclk", "gclk";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spdiftx_default>;
};

View File

@ -0,0 +1,61 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/mt6359.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek MT6359 Codec Device Tree Bindings
maintainers:
- Eason Yen <eason.yen@mediatek.com>
- Jiaxin Yu <jiaxin.yu@mediatek.com>
- Shane Chien <shane.chien@mediatek.com>
description: |
The communication between MT6359 and SoC is through Mediatek PMIC wrapper.
For more detail, please visit Mediatek PMIC wrapper documentation.
Must be a child node of PMIC wrapper.
properties:
mediatek,dmic-mode:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Indicates how many data pins are used to transmit two channels of PDM
signal. 0 means two wires, 1 means one wire. Default value is 0.
enum:
- 0 # one wire
- 1 # two wires
mediatek,mic-type-0:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Specifies the type of mic type connected to adc0
enum:
- 0 # IDLE - mic in turn-off status
- 1 # ACC - analog mic with alternating coupling
- 2 # DMIC - digital mic
- 3 # DCC - analog mic with direct couping
- 4 # DCC_ECM_DIFF - analog electret condenser mic with differential mode
- 5 # DCC_ECM_SINGLE - analog electret condenser mic with single mode
mediatek,mic-type-1:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Specifies the type of mic type connected to adc1
mediatek,mic-type-2:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Specifies the type of mic type connected to adc2
additionalProperties: false
examples:
- |
mt6359codec: mt6359codec {
mediatek,dmic-mode = <0>;
mediatek,mic-type-0 = <2>;
};
...

View File

@ -3,6 +3,7 @@ MT8183 with MT6358, DA7219, MAX98357, and RT1015 CODECS
Required properties:
- compatible : "mediatek,mt8183_da7219_max98357" for MAX98357A codec
"mediatek,mt8183_da7219_rt1015" for RT1015 codec
"mediatek,mt8183_da7219_rt1015p" for RT1015P codec
- mediatek,headset-codec: the phandles of da7219 codecs
- mediatek,platform: the phandle of MT8183 ASoC platform

View File

@ -34,6 +34,13 @@ Required properties:
* DMIC
* Ext Spk
Optional properties:
- aux-devs : A list of phandles for auxiliary devices (e.g. analog
amplifiers) that do not appear directly within the DAI
links. Should be connected to another audio component
using "qcom,audio-routing".
Dai-link subnode properties and subnodes:
Required dai-link subnodes:

View File

@ -55,6 +55,14 @@ This binding describes the APQ8096 sound card, which uses qdsp for audio.
Value type: <stringlist>
Definition: The user-visible name of this sound card.
- aux-devs
Usage: optional
Value type: <array of phandles>
Definition: A list of phandles for auxiliary devices (e.g. analog
amplifiers) that do not appear directly within the DAI
links. Should be connected to another audio component
using "audio-routing".
= dailinks
Each subnode of sndcard represents either a dailink, and subnodes of each
dailinks would be cpu/codec/platform dais.

View File

@ -1,79 +0,0 @@
* Qualcomm Technologies LPASS CPU DAI
This node models the Qualcomm Technologies Low-Power Audio SubSystem (LPASS).
Required properties:
- compatible : "qcom,lpass-cpu" or "qcom,apq8016-lpass-cpu"
- clocks : Must contain an entry for each entry in clock-names.
- clock-names : A list which must include the following entries:
* "ahbix-clk"
* "mi2s-osr-clk"
* "mi2s-bit-clk"
: required clocks for "qcom,lpass-cpu-apq8016"
* "ahbix-clk"
* "mi2s-bit-clk0"
* "mi2s-bit-clk1"
* "mi2s-bit-clk2"
* "mi2s-bit-clk3"
* "pcnoc-mport-clk"
* "pcnoc-sway-clk"
- interrupts : Must contain an entry for each entry in
interrupt-names.
- interrupt-names : A list which must include the following entries:
* "lpass-irq-lpaif"
- pinctrl-N : One property must exist for each entry in
pinctrl-names. See ../pinctrl/pinctrl-bindings.txt
for details of the property values.
- pinctrl-names : Must contain a "default" entry.
- reg : Must contain an address for each entry in reg-names.
- reg-names : A list which must include the following entries:
* "lpass-lpaif"
- #address-cells : Must be 1
- #size-cells : Must be 0
Optional properties:
- qcom,adsp : Phandle for the audio DSP node
By default, the driver uses up to 4 MI2S SD lines, for a total of 8 channels.
The SD lines to use can be configured by adding subnodes for each of the DAIs.
Required properties for each DAI (represented by a subnode):
- reg : Must be one of the DAI IDs
(usually part of dt-bindings header)
- qcom,playback-sd-lines: List of serial data lines to use for playback
Each SD line should be represented by a number from 0-3.
- qcom,capture-sd-lines : List of serial data lines to use for capture
Each SD line should be represented by a number from 0-3.
Note that adding a subnode changes the default to "no lines configured",
so both playback and capture lines should be configured when a subnode is added.
Example:
lpass@28100000 {
compatible = "qcom,lpass-cpu";
clocks = <&lcc AHBIX_CLK>, <&lcc MI2S_OSR_CLK>, <&lcc MI2S_BIT_CLK>;
clock-names = "ahbix-clk", "mi2s-osr-clk", "mi2s-bit-clk";
interrupts = <0 85 1>;
interrupt-names = "lpass-irq-lpaif";
pinctrl-names = "default", "idle";
pinctrl-0 = <&mi2s_default>;
pinctrl-1 = <&mi2s_idle>;
reg = <0x28100000 0x10000>;
reg-names = "lpass-lpaif";
qcom,adsp = <&adsp>;
#address-cells = <1>;
#size-cells = <0>;
/* Optional to set different MI2S SD lines */
dai@3 {
reg = <MI2S_QUATERNARY>;
qcom,playback-sd-lines = <0 1>;
};
};

View File

@ -0,0 +1,219 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/qcom,lpass-cpu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies Inc. LPASS CPU dai driver bindings
maintainers:
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
- Rohit kumar <rohitkr@codeaurora.org>
description: |
Qualcomm Technologies Inc. SOC Low-Power Audio SubSystem (LPASS) that consist
of MI2S interface for audio data transfer on external codecs. LPASS cpu driver
is a module to configure Low-Power Audio Interface(LPAIF) core registers
across different IP versions.
properties:
compatible:
enum:
- qcom,lpass-cpu
- qcom,apq8016-lpass-cpu
- qcom,sc7180-lpass-cpu
reg:
maxItems: 2
description: LPAIF core registers
reg-names:
maxItems: 2
clocks:
minItems: 3
maxItems: 6
clock-names:
minItems: 3
maxItems: 6
interrupts:
maxItems: 2
description: LPAIF DMA buffer interrupt
interrupt-names:
maxItems: 2
qcom,adsp:
$ref: /schemas/types.yaml#/definitions/phandle
description: Phandle for the audio DSP node
iommus:
maxItems: 2
description: Phandle to apps_smmu node with sid mask
power-domains:
maxItems: 1
'#sound-dai-cells':
const: 1
'#address-cells':
const: 1
'#size-cells':
const: 0
patternProperties:
"^dai-link@[0-9a-f]$":
type: object
description: |
LPASS CPU dai node for each I2S device. Bindings of each node
depends on the specific driver providing the functionality and
properties.
properties:
reg:
maxItems: 1
description: Must be one of the DAI ID
qcom,playback-sd-lines:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: list of MI2S data lines for playback
qcom,capture-sd-lines:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: list of MI2S data lines for capture
required:
- reg
additionalProperties: false
required:
- compatible
- reg
- reg-names
- clocks
- clock-names
- interrupts
- interrupt-names
- '#sound-dai-cells'
additionalProperties: false
allOf:
- if:
properties:
compatible:
contains:
const: qcom,lpass-cpu
then:
properties:
clock-names:
items:
- const: ahbix-clk
- const: mi2s-osr-clk
- const: mi2s-bit-clk
- if:
properties:
compatible:
contains:
const: qcom,apq8016-lpass-cpu
then:
properties:
clock-names:
items:
- const: ahbix-clk
- const: mi2s-bit-clk0
- const: mi2s-bit-clk1
- const: mi2s-bit-clk2
- const: mi2s-bit-clk3
- const: pcnoc-mport-clk
- const: pcnoc-sway-clk
- if:
properties:
compatible:
contains:
const: qcom,sc7180-lpass-cpu
then:
properties:
clock-names:
oneOf:
- items: #for I2S
- const: pcnoc-sway-clk
- const: audio-core
- const: mclk0
- const: pcnoc-mport-clk
- const: mi2s-bit-clk0
- const: mi2s-bit-clk1
- items: #for HDMI
- const: pcnoc-sway-clk
- const: audio-core
- const: pcnoc-mport-clk
reg-names:
anyOf:
- items: #for I2S
- const: lpass-lpaif
- items: #for I2S and HDMI
- const: lpass-hdmiif
- const: lpass-lpaif
interrupt-names:
anyOf:
- items: #for I2S
- const: lpass-irq-lpaif
- items: #for I2S and HDMI
- const: lpass-irq-lpaif
- const: lpass-irq-hdmi
required:
- iommus
- power-domains
examples:
- |
#include <dt-bindings/sound/sc7180-lpass.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
lpass@62d80000 {
compatible = "qcom,sc7180-lpass-cpu";
reg = <0 0x62d87000 0 0x68000>,
<0 0x62f00000 0 0x29000>;
reg-names = "lpass-hdmiif",
"lpass-lpaif";
iommus = <&apps_smmu 0x1020 0>,
<&apps_smmu 0x1032 0>;
power-domains = <&lpass_hm 0>;
clocks = <&gcc 131>,
<&lpasscorecc 6>,
<&lpasscorecc 7>,
<&lpasscorecc 10>,
<&lpasscorecc 8>,
<&lpasscorecc 9>;
clock-names = "pcnoc-sway-clk", "audio-core",
"mclk0", "pcnoc-mport-clk",
"mi2s-bit-clk0", "mi2s-bit-clk1";
interrupts = <0 160 1>,
<0 268 1>;
interrupt-names = "lpass-irq-lpaif",
"lpass-irq-hdmi";
#sound-dai-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
/* Optional to set different MI2S SD lines */
dai-link@0 {
reg = <MI2S_PRIMARY>;
qcom,playback-sd-lines = <1>;
qcom,capture-sd-lines = <0>;
};
};
};
...

View File

@ -98,6 +98,24 @@ configuration of each dai. Must contain the following properties.
0 - MSB
1 - LSB
= AFE CLOCKSS
"clocks" subnode of the AFE node. It represents q6afe clocks
"clocks" node should have following properties.
- compatible:
Usage: required
Value type: <stringlist>
Definition: must be "qcom,q6afe-clocks"
- #clock-cells:
Usage: required
Value type: <u32>
Definition: Must be 2. Clock Id followed by
below valid clock coupling attributes.
1 - for no coupled clock
2 - for dividend of the coupled clock
3 - for divisor of the coupled clock
4 - for inverted and no couple clock
= EXAMPLE
apr-service@4 {
@ -175,4 +193,9 @@ apr-service@4 {
qcom,sd-lines = <1>;
};
};
clocks {
compatible = "qcom,q6afe-clocks";
#clock-cells = <2>;
};
};

View File

@ -24,6 +24,14 @@ This binding describes the SDM845 sound card, which uses qdsp for audio.
Value type: <stringlist>
Definition: The user-visible name of this sound card.
- aux-devs
Usage: optional
Value type: <array of phandles>
Definition: A list of phandles for auxiliary devices (e.g. analog
amplifiers) that do not appear directly within the DAI
links. Should be connected to another audio component
using "audio-routing".
= dailinks
Each subnode of sndcard represents either a dailink, and subnodes of each
dailinks would be cpu/codec/platform dais.

View File

@ -0,0 +1,36 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/realtek,rt1015p.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Realtek rt1015p codec devicetree bindings
maintainers:
- Tzung-Bi Shih <tzungbi@google.com>
description: |
Rt1015p is a rt1015 variant which does not support I2C and
only supports S24, 48kHz, 64FS.
properties:
compatible:
const: realtek,rt1015p
sdb-gpios:
description:
GPIO used for shutdown control.
0 means shut down; 1 means power on.
maxItems: 1
required:
- compatible
examples:
- |
#include <dt-bindings/gpio/gpio.h>
rt1015p: rt1015p {
compatible = "realtek,rt1015p";
sdb-gpios = <&pio 175 GPIO_ACTIVE_HIGH>;
};

View File

@ -27,6 +27,7 @@ properties:
- enum:
- rockchip,rk3188-spdif
- rockchip,rk3288-spdif
- rockchip,rk3308-spdif
- const: rockchip,rk3066-spdif
reg:

View File

@ -88,7 +88,7 @@ rt5640 {
compatible = "realtek,rt5640";
reg = <0x1c>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_LEVEL_HIGH>;
realtek,ldo1-en-gpios =
<&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
};

View File

@ -72,7 +72,7 @@ rt5659 {
compatible = "realtek,rt5659";
reg = <0x1b>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_LEVEL_HIGH>;
realtek,ldo1-en-gpios =
<&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
};

View File

@ -62,7 +62,7 @@ rt5659 {
compatible = "realtek,rt5665";
reg = <0x1b>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_LEVEL_HIGH>;
realtek,ldo1-en-gpios =
<&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
};

View File

@ -41,7 +41,7 @@ rt5668 {
compatible = "realtek,rt5668b";
reg = <0x1a>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(U, 6) GPIO_ACTIVE_HIGH>;
interrupts = <TEGRA_GPIO(U, 6) IRQ_TYPE_LEVEL_HIGH>;
realtek,ldo1-en-gpios =
<&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
realtek,dmic1-data-pin = <1>;

View File

@ -64,7 +64,7 @@ rt5677 {
compatible = "realtek,rt5677";
reg = <0x2c>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_LEVEL_HIGH>;
gpio-controller;
#gpio-cells = <2>;

View File

@ -58,7 +58,7 @@ rt5682 {
compatible = "realtek,rt5682i";
reg = <0x1a>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(U, 6) GPIO_ACTIVE_HIGH>;
interrupts = <TEGRA_GPIO(U, 6) IRQ_TYPE_LEVEL_HIGH>;
realtek,ldo1-en-gpios =
<&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
realtek,dmic1-data-pin = <1>;

View File

@ -11,12 +11,11 @@ maintainers:
properties:
compatible:
oneOf:
- const: samsung,aries-wm8994
description: With FM radio and modem master
- const: samsung,fascinate4g-wm8994
description: Without FM radio and modem slave
enum:
# With FM radio and modem master
- samsung,aries-wm8994
# Without FM radio and modem slave
- samsung,fascinate4g-wm8994
model:
$ref: /schemas/types.yaml#/definitions/string

View File

@ -21,7 +21,8 @@ properties:
type: object
properties:
sound-dai:
$ref: /schemas/types.yaml#/definitions/phandle
$ref: /schemas/types.yaml#/definitions/phandle-array
maxItems: 1
description: phandle to the I2S controller
required:
- sound-dai
@ -30,7 +31,8 @@ properties:
type: object
properties:
sound-dai:
$ref: /schemas/types.yaml#/definitions/phandle
$ref: /schemas/types.yaml#/definitions/phandle-array
maxItems: 1
description: phandle to the WM1811 CODEC
required:
- sound-dai

View File

@ -28,6 +28,11 @@ properties:
$ref: /schemas/types.yaml#/definitions/string
description: The user-visible name of this sound complex.
assigned-clock-parents: true
assigned-clock-rates: true
assigned-clocks: true
clocks: true
cpu:
type: object
properties:

View File

@ -41,6 +41,12 @@ properties:
- samsung,exynos7-i2s
- samsung,exynos7-i2s1
'#address-cells':
const: 1
'#size-cells':
const: 0
reg:
maxItems: 1
@ -58,6 +64,9 @@ properties:
- const: rx
- const: tx-sec
assigned-clock-parents: true
assigned-clocks: true
clocks:
minItems: 1
maxItems: 3
@ -92,6 +101,9 @@ properties:
- const: i2s_cdclk2
description: Names of the CDCLK I2S output clocks.
interrupts:
maxItems: 1
samsung,idma-addr:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
@ -104,6 +116,9 @@ properties:
pinctrl-names:
const: default
power-domains:
maxItems: 1
"#sound-dai-cells":
const: 1

View File

@ -19,6 +19,10 @@ properties:
"#sound-dai-cells":
const: 0
assigned-clock-parents: true
assigned-clock-rates: true
assigned-clocks: true
clocks:
items:
- description: the clock provider of SYS_MCLK

View File

@ -1,37 +0,0 @@
Texas Instruments TAS2562 Smart PA
The TAS2562 is a mono, digital input Class-D audio amplifier optimized for
efficiently driving high peak power into small loudspeakers.
Integrated speaker voltage and current sense provides for
real time monitoring of loudspeaker behavior.
Required properties:
- #address-cells - Should be <1>.
- #size-cells - Should be <0>.
- compatible: - Should contain "ti,tas2562", "ti,tas2563".
- reg: - The i2c address. Should be 0x4c, 0x4d, 0x4e or 0x4f.
- ti,imon-slot-no:- TDM TX current sense time slot.
- ti,vmon-slot-no:- TDM TX voltage sense time slot. This slot must always be
greater then ti,imon-slot-no.
Optional properties:
- interrupt-parent: phandle to the interrupt controller which provides
the interrupt.
- interrupts: (GPIO) interrupt to which the chip is connected.
- shut-down-gpio: GPIO used to control the state of the device.
Examples:
tas2562@4c {
#address-cells = <1>;
#size-cells = <0>;
compatible = "ti,tas2562";
reg = <0x4c>;
interrupt-parent = <&gpio1>;
interrupts = <14>;
shut-down-gpio = <&gpio1 15 0>;
ti,imon-slot-no = <0>;
ti,vmon-slot-no = <1>;
};

View File

@ -16,11 +16,19 @@ description: |
Integrated speaker voltage and current sense provides for
real time monitoring of loudspeaker behavior.
Specifications about the audio amplifier can be found at:
https://www.ti.com/lit/gpn/tas2562
https://www.ti.com/lit/gpn/tas2563
https://www.ti.com/lit/gpn/tas2564
https://www.ti.com/lit/gpn/tas2110
properties:
compatible:
enum:
- ti,tas2562
- ti,tas2563
- ti,tas2564
- ti,tas2110
reg:
maxItems: 1

View File

@ -0,0 +1,76 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) 2020 Texas Instruments Incorporated
%YAML 1.2
---
$id: "http://devicetree.org/schemas/sound/tas2764.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: Texas Instruments TAS2764 Smart PA
maintainers:
- Dan Murphy <dmurphy@ti.com>
description: |
The TAS2764 is a mono, digital input Class-D audio amplifier optimized for
efficiently driving high peak power into small loudspeakers.
Integrated speaker voltage and current sense provides for
real time monitoring of loudspeaker behavior.
properties:
compatible:
enum:
- ti,tas2764
reg:
maxItems: 1
description: |
I2C address of the device can be between 0x38 to 0x45.
reset-gpios:
maxItems: 1
description: GPIO used to reset the device.
shutdown-gpios:
maxItems: 1
description: GPIO used to control the state of the device.
interrupts:
maxItems: 1
ti,imon-slot-no:
$ref: /schemas/types.yaml#/definitions/uint32
description: TDM TX current sense time slot.
ti,vmon-slot-no:
$ref: /schemas/types.yaml#/definitions/uint32
description: TDM TX voltage sense time slot.
'#sound-dai-cells':
const: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
i2c0 {
#address-cells = <1>;
#size-cells = <0>;
codec: codec@38 {
compatible = "ti,tas2764";
reg = <0x38>;
#sound-dai-cells = <1>;
interrupt-parent = <&gpio1>;
interrupts = <14>;
reset-gpios = <&gpio1 15 0>;
shutdown-gpios = <&gpio1 15 0>;
ti,imon-slot-no = <0>;
ti,vmon-slot-no = <2>;
};
};
...

View File

@ -24,11 +24,14 @@ properties:
reg:
maxItems: 1
description: |
I2C address of the device can be one of these 0x4c, 0x4d, 0x4e or 0x4f
I2C address of the device can be between 0x41 to 0x48.
reset-gpio:
description: GPIO used to reset the device.
shutdown-gpios:
description: GPIO used to control the state of the device.
interrupts:
maxItems: 1
@ -41,6 +44,7 @@ properties:
description: TDM TX voltage sense time slot.
ti,asi-format:
deprecated: true
$ref: /schemas/types.yaml#/definitions/uint32
description: Sets TDM RX capture edge.
enum:
@ -62,13 +66,14 @@ examples:
i2c0 {
#address-cells = <1>;
#size-cells = <0>;
codec: codec@4c {
codec: codec@41 {
compatible = "ti,tas2770";
reg = <0x4c>;
reg = <0x41>;
#sound-dai-cells = <1>;
interrupt-parent = <&gpio1>;
interrupts = <14>;
reset-gpio = <&gpio1 15 0>;
shutdown-gpios = <&gpio1 14 0>;
ti,imon-slot-no = <0>;
ti,vmon-slot-no = <2>;
};

View File

@ -18,18 +18,25 @@ description: |
PLL15 (for 44.1KHz). The same PLLs are used for McASP10's AUXCLK clock via
different HSDIVIDER.
Clocking setup for 48KHz family:
PLL4 ---> PLL4_HSDIV0 ---> MCASP10_AUXCLK ---> McASP10.auxclk
|-> PLL4_HSDIV2 ---> AUDIO_REFCLK2 ---> pcm3168a.SCKI
Clocking setup for j721e:
48KHz family:
PLL4 ---> PLL4_HSDIV0 ---> MCASP10_AUXCLK ---> McASP10.auxclk
|-> PLL4_HSDIV2 ---> AUDIO_REFCLK2 ---> pcm3168a.SCKI
Clocking setup for 44.1KHz family:
PLL15 ---> PLL15_HSDIV0 ---> MCASP10_AUXCLK ---> McASP10.auxclk
|-> PLL15_HSDIV2 ---> AUDIO_REFCLK2 ---> pcm3168a.SCKI
44.1KHz family:
PLL15 ---> PLL15_HSDIV0 ---> MCASP10_AUXCLK ---> McASP10.auxclk
|-> PLL15_HSDIV2 ---> AUDIO_REFCLK2 ---> pcm3168a.SCKI
Clocking setup for j7200:
48KHz family:
PLL4 ---> PLL4_HSDIV0 ---> MCASP0_AUXCLK ---> McASP0.auxclk
|-> PLL4_HSDIV2 ---> AUDIO_REFCLK2 ---> pcm3168a.SCKI
properties:
compatible:
items:
- const: ti,j721e-cpb-audio
enum:
- ti,j721e-cpb-audio
- ti,j7200-cpb-audio
model:
$ref: /schemas/types.yaml#/definitions/string
@ -44,22 +51,12 @@ properties:
$ref: /schemas/types.yaml#/definitions/phandle
clocks:
items:
- description: AUXCLK clock for McASP used by CPB audio
- description: Parent for CPB_McASP auxclk (for 48KHz)
- description: Parent for CPB_McASP auxclk (for 44.1KHz)
- description: SCKI clock for the pcm3168a codec on CPB
- description: Parent for CPB_SCKI clock (for 48KHz)
- description: Parent for CPB_SCKI clock (for 44.1KHz)
minItems: 4
maxItems: 6
clock-names:
items:
- const: cpb-mcasp-auxclk
- const: cpb-mcasp-auxclk-48000
- const: cpb-mcasp-auxclk-44100
- const: cpb-codec-scki
- const: cpb-codec-scki-48000
- const: cpb-codec-scki-44100
minItems: 4
maxItems: 6
required:
- compatible
@ -71,6 +68,57 @@ required:
additionalProperties: false
allOf:
- if:
properties:
compatible:
contains:
const: ti,j721e-cpb-audio
then:
properties:
clocks:
minItems: 6
items:
- description: AUXCLK clock for McASP used by CPB audio
- description: Parent for CPB_McASP auxclk (for 48KHz)
- description: Parent for CPB_McASP auxclk (for 44.1KHz)
- description: SCKI clock for the pcm3168a codec on CPB
- description: Parent for CPB_SCKI clock (for 48KHz)
- description: Parent for CPB_SCKI clock (for 44.1KHz)
clock-names:
items:
- const: cpb-mcasp-auxclk
- const: cpb-mcasp-auxclk-48000
- const: cpb-mcasp-auxclk-44100
- const: cpb-codec-scki
- const: cpb-codec-scki-48000
- const: cpb-codec-scki-44100
- if:
properties:
compatible:
contains:
const: ti,j7200-cpb-audio
then:
properties:
clocks:
maxItems: 4
items:
- description: AUXCLK clock for McASP used by CPB audio
- description: Parent for CPB_McASP auxclk (for 48KHz)
- description: SCKI clock for the pcm3168a codec on CPB
- description: Parent for CPB_SCKI clock (for 48KHz)
clock-names:
items:
- const: cpb-mcasp-auxclk
- const: cpb-mcasp-auxclk-48000
- const: cpb-codec-scki
- const: cpb-codec-scki-48000
examples:
- |+
sound {

View File

@ -108,6 +108,12 @@ properties:
maximum: 7
default: [0, 0, 0, 0]
ti,asi-tx-drive:
type: boolean
description: |
When set the device will set the Tx ASI output to a Hi-Z state for unused
data cycles. Default is to drive the output low on unused ASI cycles.
patternProperties:
'^ti,gpo-config-[1-4]$':
$ref: /schemas/types.yaml#/definitions/uint32-array
@ -134,6 +140,49 @@ patternProperties:
4d - Drive weak low and active high
5d - Drive Hi-Z and active high
ti,gpio-config:
description: |
Defines the configuration and output drive for the General Purpose
Input and Output pin (GPIO1). Its value is a pair, the first value is for
the configuration type and the second value is for the output drive
type. The array is defined as <GPIO1_CFG GPIO1_DRV>
configuration for the GPIO pin can be one of the following:
0 - disabled
1 - GPIO1 is configured as a general-purpose output (GPO)
2 - (default) GPIO1 is configured as a device interrupt output (IRQ)
3 - GPIO1 is configured as a secondary ASI output (SDOUT2)
4 - GPIO1 is configured as a PDM clock output (PDMCLK)
8 - GPIO1 is configured as an input to control when MICBIAS turns on or
off (MICBIAS_EN)
9 - GPIO1 is configured as a general-purpose input (GPI)
10 - GPIO1 is configured as a master clock input (MCLK)
11 - GPIO1 is configured as an ASI input for daisy-chain (SDIN)
12 - GPIO1 is configured as a PDM data input for channel 1 and channel 2
(PDMDIN1)
13 - GPIO1 is configured as a PDM data input for channel 3 and channel 4
(PDMDIN2)
14 - GPIO1 is configured as a PDM data input for channel 5 and channel 6
(PDMDIN3)
15 - GPIO1 is configured as a PDM data input for channel 7 and channel 8
(PDMDIN4)
output drive type for the GPIO pin can be one of the following:
0 - Hi-Z output
1 - Drive active low and active high
2 - (default) Drive active low and weak high
3 - Drive active low and Hi-Z
4 - Drive weak low and active high
5 - Drive Hi-Z and active high
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32-array
- minItems: 2
maxItems: 2
items:
maximum: 15
default: [2, 2]
required:
- compatible
- reg
@ -152,6 +201,7 @@ examples:
ti,mic-bias-source = <6>;
ti,pdm-edge-select = <0 1 0 1>;
ti,gpi-config = <4 5 6 7>;
ti,gpio-config = <10 2>;
ti,gpo-config-1 = <0 0>;
ti,gpo-config-2 = <0 0>;
reset-gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;

View File

@ -4177,6 +4177,7 @@ CIRRUS LOGIC AUDIO CODEC DRIVERS
M: James Schulman <james.schulman@cirrus.com>
M: David Rhodes <david.rhodes@cirrus.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
L: patches@opensource.cirrus.com
S: Maintained
F: sound/soc/codecs/cs*

View File

@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
#include <linux/workqueue.h>
@ -474,6 +475,20 @@ static struct platform_device gta02_buttons_device = {
},
};
static struct gpiod_lookup_table gta02_audio_gpio_table = {
.dev_id = "neo1973-audio",
.table = {
GPIO_LOOKUP("GPIOJ", 2, "amp-shut", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("GPIOJ", 1, "hp", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct platform_device gta02_audio = {
.name = "neo1973-audio",
.id = -1,
};
static void __init gta02_map_io(void)
{
s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
@ -498,6 +513,7 @@ static struct platform_device *gta02_devices[] __initdata = {
&gta02_buttons_device,
&s3c_device_adc,
&s3c_device_ts,
&gta02_audio,
};
static void gta02_poweroff(void)
@ -524,6 +540,7 @@ static void __init gta02_machine_init(void)
i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
gpiod_add_lookup_table(&gta02_audio_gpio_table);
platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
pm_power_off = gta02_poweroff;

View File

@ -475,6 +475,22 @@ static struct gpiod_lookup_table h1940_mmc_gpio_table = {
},
};
static struct gpiod_lookup_table h1940_audio_gpio_table = {
.dev_id = "h1940-audio",
.table = {
GPIO_LOOKUP("H1940_LATCH",
H1940_LATCH_AUDIO_POWER - H1940_LATCH_GPIO(0),
"speaker-power", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("GPIOG", 4, "hp", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct platform_device h1940_audio = {
.name = "h1940-audio",
.id = -1,
};
static struct pwm_lookup h1940_pwm_lookup[] = {
PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight", NULL, 36296,
PWM_POLARITY_NORMAL),
@ -651,6 +667,7 @@ static struct platform_device *h1940_devices[] __initdata = {
&s3c_device_ts,
&power_supply,
&h1940_battery,
&h1940_audio,
};
static void __init h1940_map_io(void)
@ -690,6 +707,7 @@ static void __init h1940_init(void)
s3c24xx_fb_set_platdata(&h1940_fb_info);
gpiod_add_lookup_table(&h1940_mmc_gpio_table);
gpiod_add_lookup_table(&h1940_audio_gpio_table);
s3c24xx_mci_set_platdata(&h1940_mmc_cfg);
s3c24xx_udc_set_platdata(&h1940_udc_cfg);
s3c24xx_ts_set_platdata(&h1940_ts_cfg);

View File

@ -728,6 +728,20 @@ static struct i2c_board_info rx1950_i2c_devices[] = {
},
};
static struct gpiod_lookup_table rx1950_audio_gpio_table = {
.dev_id = "rx1950-audio",
.table = {
GPIO_LOOKUP("GPIOG", 12, "hp-gpio", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("GPIOA", 1, "speaker-power", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct platform_device rx1950_audio = {
.name = "rx1950-audio",
.id = -1,
};
static struct platform_device *rx1950_devices[] __initdata = {
&s3c2410_device_dclk,
&s3c_device_lcd,
@ -746,6 +760,7 @@ static struct platform_device *rx1950_devices[] __initdata = {
&power_supply,
&rx1950_battery,
&rx1950_leds,
&rx1950_audio,
};
static void __init rx1950_map_io(void)
@ -813,6 +828,7 @@ static void __init rx1950_init_machine(void)
gpio_direction_output(S3C2410_GPJ(6), 0);
pwm_add_table(rx1950_pwm_lookup, ARRAY_SIZE(rx1950_pwm_lookup));
gpiod_add_lookup_table(&rx1950_audio_gpio_table);
platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
i2c_register_board_info(0, rx1950_i2c_devices,

View File

@ -293,6 +293,7 @@ static int stm32_dfsdm_compute_osrs(struct stm32_dfsdm_filter *fl,
max >>= flo->rshift;
}
flo->max = (s32)max;
flo->bits = bits;
pr_debug("%s: fast %d, fosr %d, iosr %d, res 0x%llx/%d bits, rshift %d, lshift %d\n",
__func__, fast, flo->fosr, flo->iosr,
@ -476,6 +477,9 @@ static int stm32_dfsdm_channels_configure(struct iio_dev *indio_dev,
if (!flo->res)
return -EINVAL;
dev_dbg(&indio_dev->dev, "Samples actual resolution: %d bits",
min(flo->bits, (u32)DFSDM_DATA_RES - 1));
for_each_set_bit(bit, &adc->smask,
sizeof(adc->smask) * BITS_PER_BYTE) {
chan = indio_dev->channels + bit;

View File

@ -249,6 +249,7 @@ enum stm32_dfsdm_sinc_order {
* @rshift: output sample right shift (hardware shift)
* @lshift: output sample left shift (software shift)
* @res: output sample resolution
* @bits: output sample resolution in bits
* @max: output sample maximum positive value
*/
struct stm32_dfsdm_filter_osr {
@ -257,6 +258,7 @@ struct stm32_dfsdm_filter_osr {
unsigned int rshift;
unsigned int lshift;
u64 res;
u32 bits;
s32 max;
};

View File

@ -16,7 +16,6 @@
#include <linux/interrupt.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/platform_data/dma-atmel.h>
#include <linux/of.h>
#include <linux/io.h>

View File

@ -117,6 +117,10 @@ struct drm_audio_component {
* @audio_ops: Ops implemented by hda driver, called by DRM driver
*/
const struct drm_audio_component_audio_ops *audio_ops;
/**
* @master_bind_complete: completion held during component master binding
*/
struct completion master_bind_complete;
};
#endif /* _DRM_AUDIO_COMPONENT_H_ */

View File

@ -107,6 +107,100 @@
#define QUINARY_TDM_RX_7 102
#define QUINARY_TDM_TX_7 103
#define DISPLAY_PORT_RX 104
#define WSA_CODEC_DMA_RX_0 105
#define WSA_CODEC_DMA_TX_0 106
#define WSA_CODEC_DMA_RX_1 107
#define WSA_CODEC_DMA_TX_1 108
#define WSA_CODEC_DMA_TX_2 109
#define VA_CODEC_DMA_TX_0 110
#define VA_CODEC_DMA_TX_1 111
#define VA_CODEC_DMA_TX_2 112
#define RX_CODEC_DMA_RX_0 113
#define TX_CODEC_DMA_TX_0 114
#define RX_CODEC_DMA_RX_1 115
#define TX_CODEC_DMA_TX_1 116
#define RX_CODEC_DMA_RX_2 117
#define TX_CODEC_DMA_TX_2 118
#define RX_CODEC_DMA_RX_3 119
#define TX_CODEC_DMA_TX_3 120
#define RX_CODEC_DMA_RX_4 121
#define TX_CODEC_DMA_TX_4 122
#define RX_CODEC_DMA_RX_5 123
#define TX_CODEC_DMA_TX_5 124
#define RX_CODEC_DMA_RX_6 125
#define RX_CODEC_DMA_RX_7 126
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2
#define LPASS_CLK_ID_SEC_MI2S_IBIT 3
#define LPASS_CLK_ID_SEC_MI2S_EBIT 4
#define LPASS_CLK_ID_TER_MI2S_IBIT 5
#define LPASS_CLK_ID_TER_MI2S_EBIT 6
#define LPASS_CLK_ID_QUAD_MI2S_IBIT 7
#define LPASS_CLK_ID_QUAD_MI2S_EBIT 8
#define LPASS_CLK_ID_SPEAKER_I2S_IBIT 9
#define LPASS_CLK_ID_SPEAKER_I2S_EBIT 10
#define LPASS_CLK_ID_SPEAKER_I2S_OSR 11
#define LPASS_CLK_ID_QUI_MI2S_IBIT 12
#define LPASS_CLK_ID_QUI_MI2S_EBIT 13
#define LPASS_CLK_ID_SEN_MI2S_IBIT 14
#define LPASS_CLK_ID_SEN_MI2S_EBIT 15
#define LPASS_CLK_ID_INT0_MI2S_IBIT 16
#define LPASS_CLK_ID_INT1_MI2S_IBIT 17
#define LPASS_CLK_ID_INT2_MI2S_IBIT 18
#define LPASS_CLK_ID_INT3_MI2S_IBIT 19
#define LPASS_CLK_ID_INT4_MI2S_IBIT 20
#define LPASS_CLK_ID_INT5_MI2S_IBIT 21
#define LPASS_CLK_ID_INT6_MI2S_IBIT 22
#define LPASS_CLK_ID_QUI_MI2S_OSR 23
#define LPASS_CLK_ID_PRI_PCM_IBIT 24
#define LPASS_CLK_ID_PRI_PCM_EBIT 25
#define LPASS_CLK_ID_SEC_PCM_IBIT 26
#define LPASS_CLK_ID_SEC_PCM_EBIT 27
#define LPASS_CLK_ID_TER_PCM_IBIT 28
#define LPASS_CLK_ID_TER_PCM_EBIT 29
#define LPASS_CLK_ID_QUAD_PCM_IBIT 30
#define LPASS_CLK_ID_QUAD_PCM_EBIT 31
#define LPASS_CLK_ID_QUIN_PCM_IBIT 32
#define LPASS_CLK_ID_QUIN_PCM_EBIT 33
#define LPASS_CLK_ID_QUI_PCM_OSR 34
#define LPASS_CLK_ID_PRI_TDM_IBIT 35
#define LPASS_CLK_ID_PRI_TDM_EBIT 36
#define LPASS_CLK_ID_SEC_TDM_IBIT 37
#define LPASS_CLK_ID_SEC_TDM_EBIT 38
#define LPASS_CLK_ID_TER_TDM_IBIT 39
#define LPASS_CLK_ID_TER_TDM_EBIT 40
#define LPASS_CLK_ID_QUAD_TDM_IBIT 41
#define LPASS_CLK_ID_QUAD_TDM_EBIT 42
#define LPASS_CLK_ID_QUIN_TDM_IBIT 43
#define LPASS_CLK_ID_QUIN_TDM_EBIT 44
#define LPASS_CLK_ID_QUIN_TDM_OSR 45
#define LPASS_CLK_ID_MCLK_1 46
#define LPASS_CLK_ID_MCLK_2 47
#define LPASS_CLK_ID_MCLK_3 48
#define LPASS_CLK_ID_MCLK_4 49
#define LPASS_CLK_ID_INTERNAL_DIGITAL_CODEC_CORE 50
#define LPASS_CLK_ID_INT_MCLK_0 51
#define LPASS_CLK_ID_INT_MCLK_1 52
#define LPASS_CLK_ID_MCLK_5 53
#define LPASS_CLK_ID_WSA_CORE_MCLK 54
#define LPASS_CLK_ID_WSA_CORE_NPL_MCLK 55
#define LPASS_CLK_ID_VA_CORE_MCLK 56
#define LPASS_CLK_ID_TX_CORE_MCLK 57
#define LPASS_CLK_ID_TX_CORE_NPL_MCLK 58
#define LPASS_CLK_ID_RX_CORE_MCLK 59
#define LPASS_CLK_ID_RX_CORE_NPL_MCLK 60
#define LPASS_CLK_ID_VA_CORE_2X_MCLK 61
#define LPASS_HW_AVTIMER_VOTE 101
#define LPASS_HW_MACRO_VOTE 102
#define LPASS_HW_DCODEC_VOTE 103
#define Q6AFE_MAX_CLK_ID 104
#define LPASS_CLK_ATTRIBUTE_INVALID 0x0
#define LPASS_CLK_ATTRIBUTE_COUPLE_NO 0x1
#define LPASS_CLK_ATTRIBUTE_COUPLE_DIVIDEND 0x2
#define LPASS_CLK_ATTRIBUTE_COUPLE_DIVISOR 0x3
#endif /* __DT_BINDINGS_Q6_AFE_H__ */

View File

@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __DT_SC7180_LPASS_H
#define __DT_SC7180_LPASS_H
#define MI2S_PRIMARY 0
#define MI2S_SECONDARY 1
#define LPASS_DP_RX 2
#define LPASS_MCLK0 0
#endif /* __DT_APQ8016_LPASS_H */

View File

@ -253,6 +253,7 @@ struct hda_codec {
unsigned int force_pin_prefix:1; /* Add location prefix */
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 mst_no_extra_pcms:1; /* no backup PCMs for DP-MST */
#ifdef CONFIG_PM

View File

@ -119,7 +119,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define AZX_REG_VS_EM3U 0x103C
#define AZX_REG_VS_EM4L 0x1040
#define AZX_REG_VS_EM4U 0x1044
#define AZX_REG_VS_LTRC 0x1048
#define AZX_REG_VS_LTRP 0x1048
#define AZX_REG_VS_D0I3C 0x104A
#define AZX_REG_VS_PCE 0x104B
#define AZX_REG_VS_L2MAGC 0x1050

View File

@ -10,7 +10,7 @@ int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
void snd_hdac_ext_bus_exit(struct hdac_bus *bus);
int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr,
struct hdac_device *hdev);
struct hdac_device *hdev, int type);
void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev);
void snd_hdac_ext_bus_device_remove(struct hdac_bus *bus);

View File

@ -117,9 +117,6 @@ struct hdmi_codec_pdata {
struct snd_soc_component;
struct snd_soc_jack;
int hdmi_codec_set_jack_detect(struct snd_soc_component *component,
struct snd_soc_jack *jack);
#define HDMI_CODEC_DRV_NAME "hdmi-audio-codec"
#endif /* __HDMI_CODEC_H__ */

View File

@ -23,11 +23,6 @@ int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
#define MASK_OFS(i) ((i) >> 5)
#define MASK_BIT(i) (1U << ((i) & 31))
static inline size_t snd_mask_sizeof(void)
{
return sizeof(struct snd_mask);
}
static inline void snd_mask_none(struct snd_mask *mask)
{
memset(mask, 0, sizeof(*mask));

View File

@ -16,7 +16,6 @@
*/
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_haswell_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_legacy_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_skl_machines[];

View File

@ -58,7 +58,7 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
* 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
* @platform: string used for HDAudio codec support
* @codec_mask: used for HDAudio support
* @common_hdmi_codec_drv: use commom HDAudio HDMI codec driver
* @link_mask: links enabled on the board
@ -93,11 +93,13 @@ struct snd_soc_acpi_endpoint {
* @adr: 64 bit ACPI _ADR value
* @num_endpoints: number of endpoints for this device
* @endpoints: array of endpoints
* @name_prefix: string used for codec controls
*/
struct snd_soc_acpi_adr_device {
const u64 adr;
const u8 num_endpoints;
const struct snd_soc_acpi_endpoint *endpoints;
const char *name_prefix;
};
/**

View File

@ -217,6 +217,11 @@ struct snd_soc_component {
/* machine specific init */
int (*init)(struct snd_soc_component *component);
/* function mark */
struct snd_pcm_substream *mark_module;
struct snd_pcm_substream *mark_open;
void *mark_pm;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_root;
const char *debugfs_prefix;
@ -370,17 +375,19 @@ void snd_soc_component_exit_regmap(struct snd_soc_component *component);
#endif
#define snd_soc_component_module_get_when_probe(component)\
snd_soc_component_module_get(component, 0)
#define snd_soc_component_module_get_when_open(component) \
snd_soc_component_module_get(component, 1)
snd_soc_component_module_get(component, NULL, 0)
#define snd_soc_component_module_get_when_open(component, substream) \
snd_soc_component_module_get(component, substream, 1)
int snd_soc_component_module_get(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
int upon_open);
#define snd_soc_component_module_put_when_remove(component) \
snd_soc_component_module_put(component, 0)
#define snd_soc_component_module_put_when_close(component) \
snd_soc_component_module_put(component, 1)
snd_soc_component_module_put(component, NULL, 0, 0)
#define snd_soc_component_module_put_when_close(component, substream, rollback) \
snd_soc_component_module_put(component, substream, 1, rollback)
void snd_soc_component_module_put(struct snd_soc_component *component,
int upon_open);
struct snd_pcm_substream *substream,
int upon_open, int rollback);
static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c,
void *data)
@ -424,7 +431,8 @@ int snd_soc_component_force_enable_pin_unlocked(
int snd_soc_component_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream);
int snd_soc_component_close(struct snd_soc_component *component,
struct snd_pcm_substream *substream);
struct snd_pcm_substream *substream,
int rollback);
void snd_soc_component_suspend(struct snd_soc_component *component);
void snd_soc_component_resume(struct snd_soc_component *component);
int snd_soc_component_is_suspended(struct snd_soc_component *component);
@ -457,5 +465,9 @@ void snd_soc_pcm_component_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_component *last);
int snd_soc_pcm_component_trigger(struct snd_pcm_substream *substream,
int cmd);
int snd_soc_pcm_component_pm_runtime_get(struct snd_soc_pcm_runtime *rtd,
void *stream);
void snd_soc_pcm_component_pm_runtime_put(struct snd_soc_pcm_runtime *rtd,
void *stream, int rollback);
#endif /* __SOC_COMPONENT_H */

View File

@ -153,7 +153,7 @@ void snd_soc_dai_hw_free(struct snd_soc_dai *dai,
int snd_soc_dai_startup(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
struct snd_pcm_substream *substream, int rollback);
snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
void snd_soc_dai_suspend(struct snd_soc_dai *dai);
@ -388,6 +388,9 @@ struct snd_soc_dai {
struct list_head list;
/* function mark */
struct snd_pcm_substream *mark_startup;
/* bit field */
unsigned int probed:1;
};
@ -471,7 +474,8 @@ static inline int snd_soc_dai_set_sdw_stream(struct snd_soc_dai *dai,
* This routine only retrieves that was previously configured
* with snd_soc_dai_get_sdw_stream()
*
* Returns pointer to stream or -ENOTSUPP if callback is not supported;
* Returns pointer to stream or an ERR_PTR value, e.g.
* ERR_PTR(-ENOTSUPP) if callback is not supported;
*/
static inline void *snd_soc_dai_get_sdw_stream(struct snd_soc_dai *dai,
int direction)

View File

@ -14,7 +14,8 @@ int snd_soc_link_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params);
int snd_soc_link_startup(struct snd_pcm_substream *substream);
void snd_soc_link_shutdown(struct snd_pcm_substream *substream);
void snd_soc_link_shutdown(struct snd_pcm_substream *substream,
int rollback);
int snd_soc_link_prepare(struct snd_pcm_substream *substream);
int snd_soc_link_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params);

View File

@ -1159,6 +1159,9 @@ struct snd_soc_pcm_runtime {
unsigned int num; /* 0-based and monotonic increasing */
struct list_head list; /* rtd list of the soc card */
/* function mark */
struct snd_pcm_substream *mark_startup;
/* bit field */
unsigned int pop_wait:1;
unsigned int fe_compr:1; /* for Dynamic PCM */
@ -1333,6 +1336,7 @@ void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
const char *propname);
int snd_soc_of_parse_aux_devs(struct snd_soc_card *card, const char *propname);
unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
const char *prefix,
struct device_node **bitclkmaster,

View File

@ -66,6 +66,8 @@ struct sof_dev_desc {
/* alternate list of machines using this configuration */
struct snd_soc_acpi_mach *alt_machines;
bool use_acpi_target_states;
/* Platform resource indexes in BAR / ACPI resources. */
/* Must set to -1 if not used - add new items to end */
int resindex_lpe_base;

View File

@ -60,6 +60,7 @@ enum sof_ext_man_elem_type {
SOF_EXT_MAN_ELEM_FW_VERSION = 0,
SOF_EXT_MAN_ELEM_WINDOW = SOF_IPC_EXT_WINDOW,
SOF_EXT_MAN_ELEM_CC_VERSION = SOF_IPC_EXT_CC_INFO,
SOF_EXT_MAN_ELEM_DBG_ABI = SOF_IPC_EXT_USER_ABI_INFO,
};
/* extended manifest element header */
@ -92,4 +93,10 @@ struct sof_ext_man_cc_version {
struct sof_ipc_cc_version cc_version;
} __packed;
struct ext_man_dbg_abi {
struct sof_ext_man_elem_header hdr;
/* use sof_ipc struct because of code re-use */
struct sof_ipc_user_abi_version dbg_abi;
} __packed;
#endif /* __SOF_FIRMWARE_EXT_MANIFEST_H__ */

View File

@ -46,9 +46,11 @@ struct sof_ipc_fw_version {
uint8_t time[10];
uint8_t tag[6];
uint32_t abi_version;
/* used to check FW and ldc file compatibility, reproducible value */
uint32_t src_hash;
/* reserved for future use */
uint32_t reserved[4];
uint32_t reserved[3];
} __packed;
/* FW ready Message - sent by firmware when boot has completed */
@ -99,7 +101,7 @@ struct sof_ipc_window_elem {
struct sof_ipc_window {
struct sof_ipc_ext_data_hdr ext_hdr;
uint32_t num_windows;
struct sof_ipc_window_elem window[];
struct sof_ipc_window_elem window[SOF_IPC_MAX_ELEMS];
} __packed;
struct sof_ipc_cc_version {

View File

@ -57,8 +57,8 @@ struct sof_ipc_comp {
uint32_t pipeline_id;
uint32_t core;
/* reserved for future use */
uint32_t reserved[1];
/* extended data length, 0 if no extended data */
uint32_t ext_data_length;
} __packed;
/*
@ -87,6 +87,9 @@ struct sof_ipc_comp {
*/
#define SOF_BUF_UNDERRUN_PERMITTED BIT(1)
/* the UUID size in bytes, shared between FW and host */
#define SOF_UUID_SIZE 16
/* create new component buffer - SOF_IPC_TPLG_BUFFER_NEW */
struct sof_ipc_buffer {
struct sof_ipc_comp comp;
@ -300,4 +303,9 @@ enum sof_event_types {
SOF_KEYWORD_DETECT_DAPM_EVENT,
};
/* extended data struct for UUID components */
struct sof_ipc_comp_ext {
uint8_t uuid[SOF_UUID_SIZE];
} __packed;
#endif

View File

@ -21,13 +21,13 @@
#define SNDRV_TIMER_HW_STOP 0x00000002 /* call stop before start */
#define SNDRV_TIMER_HW_SLAVE 0x00000004 /* only slave timer (variable resolution) */
#define SNDRV_TIMER_HW_FIRST 0x00000008 /* first tick can be incomplete */
#define SNDRV_TIMER_HW_TASKLET 0x00000010 /* timer is called from tasklet */
#define SNDRV_TIMER_HW_WORK 0x00000010 /* timer is called from work */
#define SNDRV_TIMER_IFLG_SLAVE 0x00000001
#define SNDRV_TIMER_IFLG_RUNNING 0x00000002
#define SNDRV_TIMER_IFLG_START 0x00000004
#define SNDRV_TIMER_IFLG_AUTO 0x00000008 /* auto restart */
#define SNDRV_TIMER_IFLG_FAST 0x00000010 /* fast callback (do not use tasklet) */
#define SNDRV_TIMER_IFLG_FAST 0x00000010 /* fast callback (do not use work) */
#define SNDRV_TIMER_IFLG_CALLBACK 0x00000020 /* timer callback is active */
#define SNDRV_TIMER_IFLG_EXCLUSIVE 0x00000040 /* exclusive owner - no more instances */
#define SNDRV_TIMER_IFLG_EARLY_EVENT 0x00000080 /* write early event to the poll queue */
@ -74,7 +74,7 @@ struct snd_timer {
struct list_head active_list_head;
struct list_head ack_list_head;
struct list_head sack_list_head; /* slow ack list head */
struct tasklet_struct task_queue;
struct work_struct task_work;
int max_instances; /* upper limit of timer instances */
int num_instances; /* current number of timer instances */
};
@ -96,7 +96,7 @@ struct snd_timer_instance {
unsigned long ticks; /* auto-load ticks when expired */
unsigned long cticks; /* current ticks */
unsigned long pticks; /* accumulated ticks for callback */
unsigned long resolution; /* current resolution for tasklet */
unsigned long resolution; /* current resolution for work */
unsigned long lost; /* lost ticks */
int slave_class;
unsigned int slave_id;

View File

@ -1,385 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM hswadsp
#if !defined(_TRACE_HSWADSP_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HSWADSP_H
#include <linux/types.h>
#include <linux/ktime.h>
#include <linux/tracepoint.h>
struct sst_hsw;
struct sst_hsw_stream;
struct sst_hsw_ipc_stream_free_req;
struct sst_hsw_ipc_volume_req;
struct sst_hsw_ipc_stream_alloc_req;
struct sst_hsw_audio_data_format_ipc;
struct sst_hsw_ipc_stream_info_reply;
struct sst_hsw_ipc_device_config_req;
DECLARE_EVENT_CLASS(sst_irq,
TP_PROTO(uint32_t status, uint32_t mask),
TP_ARGS(status, mask),
TP_STRUCT__entry(
__field( unsigned int, status )
__field( unsigned int, mask )
),
TP_fast_assign(
__entry->status = status;
__entry->mask = mask;
),
TP_printk("status 0x%8.8x mask 0x%8.8x",
(unsigned int)__entry->status, (unsigned int)__entry->mask)
);
DEFINE_EVENT(sst_irq, sst_irq_busy,
TP_PROTO(unsigned int status, unsigned int mask),
TP_ARGS(status, mask)
);
DEFINE_EVENT(sst_irq, sst_irq_done,
TP_PROTO(unsigned int status, unsigned int mask),
TP_ARGS(status, mask)
);
DECLARE_EVENT_CLASS(ipc,
TP_PROTO(const char *name, int val),
TP_ARGS(name, val),
TP_STRUCT__entry(
__string( name, name )
__field( unsigned int, val )
),
TP_fast_assign(
__assign_str(name, name);
__entry->val = val;
),
TP_printk("%s 0x%8.8x", __get_str(name), (unsigned int)__entry->val)
);
DEFINE_EVENT(ipc, ipc_request,
TP_PROTO(const char *name, int val),
TP_ARGS(name, val)
);
DEFINE_EVENT(ipc, ipc_reply,
TP_PROTO(const char *name, int val),
TP_ARGS(name, val)
);
DEFINE_EVENT(ipc, ipc_pending_reply,
TP_PROTO(const char *name, int val),
TP_ARGS(name, val)
);
DEFINE_EVENT(ipc, ipc_notification,
TP_PROTO(const char *name, int val),
TP_ARGS(name, val)
);
DEFINE_EVENT(ipc, ipc_error,
TP_PROTO(const char *name, int val),
TP_ARGS(name, val)
);
DECLARE_EVENT_CLASS(stream_position,
TP_PROTO(unsigned int id, unsigned int pos),
TP_ARGS(id, pos),
TP_STRUCT__entry(
__field( unsigned int, id )
__field( unsigned int, pos )
),
TP_fast_assign(
__entry->id = id;
__entry->pos = pos;
),
TP_printk("id %d position 0x%x",
(unsigned int)__entry->id, (unsigned int)__entry->pos)
);
DEFINE_EVENT(stream_position, stream_read_position,
TP_PROTO(unsigned int id, unsigned int pos),
TP_ARGS(id, pos)
);
DEFINE_EVENT(stream_position, stream_write_position,
TP_PROTO(unsigned int id, unsigned int pos),
TP_ARGS(id, pos)
);
TRACE_EVENT(hsw_stream_buffer,
TP_PROTO(struct sst_hsw_stream *stream),
TP_ARGS(stream),
TP_STRUCT__entry(
__field( int, id )
__field( int, pt_addr )
__field( int, num_pages )
__field( int, ring_size )
__field( int, ring_offset )
__field( int, first_pfn )
),
TP_fast_assign(
__entry->id = stream->host_id;
__entry->pt_addr = stream->request.ringinfo.ring_pt_address;
__entry->num_pages = stream->request.ringinfo.num_pages;
__entry->ring_size = stream->request.ringinfo.ring_size;
__entry->ring_offset = stream->request.ringinfo.ring_offset;
__entry->first_pfn = stream->request.ringinfo.ring_first_pfn;
),
TP_printk("stream %d ring addr 0x%x pages %d size 0x%x offset 0x%x PFN 0x%x",
(int) __entry->id, (int)__entry->pt_addr,
(int)__entry->num_pages, (int)__entry->ring_size,
(int)__entry->ring_offset, (int)__entry->first_pfn)
);
TRACE_EVENT(hsw_stream_alloc_reply,
TP_PROTO(struct sst_hsw_stream *stream),
TP_ARGS(stream),
TP_STRUCT__entry(
__field( int, id )
__field( int, stream_id )
__field( int, mixer_id )
__field( int, peak0 )
__field( int, peak1 )
__field( int, vol0 )
__field( int, vol1 )
),
TP_fast_assign(
__entry->id = stream->host_id;
__entry->stream_id = stream->reply.stream_hw_id;
__entry->mixer_id = stream->reply.mixer_hw_id;
__entry->peak0 = stream->reply.peak_meter_register_address[0];
__entry->peak1 = stream->reply.peak_meter_register_address[1];
__entry->vol0 = stream->reply.volume_register_address[0];
__entry->vol1 = stream->reply.volume_register_address[1];
),
TP_printk("stream %d hw id %d mixer %d peak 0x%x:0x%x vol 0x%x,0x%x",
(int) __entry->id, (int) __entry->stream_id, (int)__entry->mixer_id,
(int)__entry->peak0, (int)__entry->peak1,
(int)__entry->vol0, (int)__entry->vol1)
);
TRACE_EVENT(hsw_mixer_info_reply,
TP_PROTO(struct sst_hsw_ipc_stream_info_reply *reply),
TP_ARGS(reply),
TP_STRUCT__entry(
__field( int, mixer_id )
__field( int, peak0 )
__field( int, peak1 )
__field( int, vol0 )
__field( int, vol1 )
),
TP_fast_assign(
__entry->mixer_id = reply->mixer_hw_id;
__entry->peak0 = reply->peak_meter_register_address[0];
__entry->peak1 = reply->peak_meter_register_address[1];
__entry->vol0 = reply->volume_register_address[0];
__entry->vol1 = reply->volume_register_address[1];
),
TP_printk("mixer id %d peak 0x%x:0x%x vol 0x%x,0x%x",
(int)__entry->mixer_id,
(int)__entry->peak0, (int)__entry->peak1,
(int)__entry->vol0, (int)__entry->vol1)
);
TRACE_EVENT(hsw_stream_data_format,
TP_PROTO(struct sst_hsw_stream *stream,
struct sst_hsw_audio_data_format_ipc *req),
TP_ARGS(stream, req),
TP_STRUCT__entry(
__field( uint32_t, id )
__field( uint32_t, frequency )
__field( uint32_t, bitdepth )
__field( uint32_t, map )
__field( uint32_t, config )
__field( uint32_t, style )
__field( uint8_t, ch_num )
__field( uint8_t, valid_bit )
),
TP_fast_assign(
__entry->id = stream->host_id;
__entry->frequency = req->frequency;
__entry->bitdepth = req->bitdepth;
__entry->map = req->map;
__entry->config = req->config;
__entry->style = req->style;
__entry->ch_num = req->ch_num;
__entry->valid_bit = req->valid_bit;
),
TP_printk("stream %d freq %d depth %d map 0x%x config 0x%x style 0x%x ch %d bits %d",
(int) __entry->id, (uint32_t)__entry->frequency,
(uint32_t)__entry->bitdepth, (uint32_t)__entry->map,
(uint32_t)__entry->config, (uint32_t)__entry->style,
(uint8_t)__entry->ch_num, (uint8_t)__entry->valid_bit)
);
TRACE_EVENT(hsw_stream_alloc_request,
TP_PROTO(struct sst_hsw_stream *stream,
struct sst_hsw_ipc_stream_alloc_req *req),
TP_ARGS(stream, req),
TP_STRUCT__entry(
__field( uint32_t, id )
__field( uint8_t, path_id )
__field( uint8_t, stream_type )
__field( uint8_t, format_id )
),
TP_fast_assign(
__entry->id = stream->host_id;
__entry->path_id = req->path_id;
__entry->stream_type = req->stream_type;
__entry->format_id = req->format_id;
),
TP_printk("stream %d path %d type %d format %d",
(int) __entry->id, (uint8_t)__entry->path_id,
(uint8_t)__entry->stream_type, (uint8_t)__entry->format_id)
);
TRACE_EVENT(hsw_stream_free_req,
TP_PROTO(struct sst_hsw_stream *stream,
struct sst_hsw_ipc_stream_free_req *req),
TP_ARGS(stream, req),
TP_STRUCT__entry(
__field( int, id )
__field( int, stream_id )
),
TP_fast_assign(
__entry->id = stream->host_id;
__entry->stream_id = req->stream_id;
),
TP_printk("stream %d hw id %d",
(int) __entry->id, (int) __entry->stream_id)
);
TRACE_EVENT(hsw_volume_req,
TP_PROTO(struct sst_hsw_stream *stream,
struct sst_hsw_ipc_volume_req *req),
TP_ARGS(stream, req),
TP_STRUCT__entry(
__field( int, id )
__field( uint32_t, channel )
__field( uint32_t, target_volume )
__field( uint64_t, curve_duration )
__field( uint32_t, curve_type )
),
TP_fast_assign(
__entry->id = stream->host_id;
__entry->channel = req->channel;
__entry->target_volume = req->target_volume;
__entry->curve_duration = req->curve_duration;
__entry->curve_type = req->curve_type;
),
TP_printk("stream %d chan 0x%x vol %d duration %llu type %d",
(int) __entry->id, (uint32_t) __entry->channel,
(uint32_t)__entry->target_volume,
(uint64_t)__entry->curve_duration,
(uint32_t)__entry->curve_type)
);
TRACE_EVENT(hsw_device_config_req,
TP_PROTO(struct sst_hsw_ipc_device_config_req *req),
TP_ARGS(req),
TP_STRUCT__entry(
__field( uint32_t, ssp )
__field( uint32_t, clock_freq )
__field( uint32_t, mode )
__field( uint16_t, clock_divider )
),
TP_fast_assign(
__entry->ssp = req->ssp_interface;
__entry->clock_freq = req->clock_frequency;
__entry->mode = req->mode;
__entry->clock_divider = req->clock_divider;
),
TP_printk("SSP %d Freq %d mode %d div %d",
(uint32_t)__entry->ssp,
(uint32_t)__entry->clock_freq, (uint32_t)__entry->mode,
(uint32_t)__entry->clock_divider)
);
#endif /* _TRACE_HSWADSP_H */
/* This part must be outside protection */
#include <trace/define_trace.h>

View File

@ -26,7 +26,7 @@
/* SOF ABI version major, minor and patch numbers */
#define SOF_ABI_MAJOR 3
#define SOF_ABI_MINOR 16
#define SOF_ABI_MINOR 17
#define SOF_ABI_PATCH 0
/* SOF ABI version number. Format within 32bit word is MMmmmppp */

View File

@ -24,6 +24,9 @@
#define SOF_TPLG_KCTL_ENUM_ID 257
#define SOF_TPLG_KCTL_BYTES_ID 258
#define SOF_TPLG_KCTL_SWITCH_ID 259
#define SOF_TPLG_KCTL_BYTES_VOLATILE_RO 260
#define SOF_TPLG_KCTL_BYTES_VOLATILE_RW 261
#define SOF_TPLG_KCTL_BYTES_WO_ID 262
/*
* Tokens - must match values in topology configurations
@ -73,6 +76,8 @@
/* Token retired with ABI 3.2, do not use for new capabilities
* #define SOF_TKN_COMP_PRELOAD_COUNT 403
*/
#define SOF_TKN_COMP_CORE_ID 404
#define SOF_TKN_COMP_UUID 405
/* SSP */
#define SOF_TKN_INTEL_SSP_CLKS_CONTROL 500

View File

@ -3,7 +3,7 @@
* Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
*/
unsigned int snd_ac97_bus_scan_one(struct ac97_controller *ac97,
unsigned int snd_ac97_bus_scan_one(struct ac97_controller *adrv,
unsigned int codec_num);
static inline bool ac97_ids_match(unsigned int id1, unsigned int id2,

View File

@ -254,12 +254,11 @@ static void i2sbus_wait_for_stop(struct i2sbus_dev *i2sdev,
struct pcm_info *pi)
{
unsigned long flags;
struct completion done;
DECLARE_COMPLETION_ONSTACK(done);
long timeout;
spin_lock_irqsave(&i2sdev->low_lock, flags);
if (pi->dbdma_ring.stopping) {
init_completion(&done);
pi->stop_completion = &done;
spin_unlock_irqrestore(&i2sdev->low_lock, flags);
timeout = wait_for_completion_timeout(&done, HZ);

View File

@ -475,12 +475,12 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
struct snd_pcm_runtime *runtime;
int offset, next_period, block_size;
dev_dbg(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n",
casr & AC97C_CSR_OVRUN ? " OVRUN" : "",
casr & AC97C_CSR_RXRDY ? " RXRDY" : "",
casr & AC97C_CSR_UNRUN ? " UNRUN" : "",
casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
casr & AC97C_CSR_TXRDY ? " TXRDY" : "",
!casr ? " NONE" : "");
(casr & AC97C_CSR_OVRUN) ? " OVRUN" : "",
(casr & AC97C_CSR_RXRDY) ? " RXRDY" : "",
(casr & AC97C_CSR_UNRUN) ? " UNRUN" : "",
(casr & AC97C_CSR_TXEMPTY) ? " TXEMPTY" : "",
(casr & AC97C_CSR_TXRDY) ? " TXRDY" : "",
!casr ? " NONE" : "");
if ((casr & camr) & AC97C_CSR_ENDTX) {
runtime = chip->playback_substream->runtime;
block_size = frames_to_bytes(runtime, runtime->period_size);
@ -521,11 +521,11 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
if (sr & AC97C_SR_COEVT) {
dev_info(&chip->pdev->dev, "codec channel event%s%s%s%s%s\n",
cosr & AC97C_CSR_OVRUN ? " OVRUN" : "",
cosr & AC97C_CSR_RXRDY ? " RXRDY" : "",
cosr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
cosr & AC97C_CSR_TXRDY ? " TXRDY" : "",
!cosr ? " NONE" : "");
(cosr & AC97C_CSR_OVRUN) ? " OVRUN" : "",
(cosr & AC97C_CSR_RXRDY) ? " RXRDY" : "",
(cosr & AC97C_CSR_TXEMPTY) ? " TXEMPTY" : "",
(cosr & AC97C_CSR_TXRDY) ? " TXRDY" : "",
!cosr ? " NONE" : "");
retval = IRQ_HANDLED;
}

View File

@ -513,10 +513,11 @@ EXPORT_SYMBOL(snd_compr_malloc_pages);
int snd_compr_free_pages(struct snd_compr_stream *stream)
{
struct snd_compr_runtime *runtime = stream->runtime;
struct snd_compr_runtime *runtime;
if (snd_BUG_ON(!(stream) || !(stream)->runtime))
return -EINVAL;
runtime = stream->runtime;
if (runtime->dma_area == NULL)
return 0;
if (runtime->dma_buffer_p != &stream->dma_buffer) {
@ -1031,7 +1032,7 @@ static const struct file_operations snd_compr_file_ops = {
static int snd_compress_dev_register(struct snd_device *device)
{
int ret = -EINVAL;
int ret;
struct snd_compr *compr;
if (snd_BUG_ON(!device || !device->device_data))

View File

@ -150,14 +150,14 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
return;
if (card->shutdown)
return;
read_lock(&card->ctl_files_rwlock);
read_lock_irqsave(&card->ctl_files_rwlock, flags);
#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
card->mixer_oss_change_count++;
#endif
list_for_each_entry(ctl, &card->ctl_files, list) {
if (!ctl->subscribed)
continue;
spin_lock_irqsave(&ctl->read_lock, flags);
spin_lock(&ctl->read_lock);
list_for_each_entry(ev, &ctl->events, list) {
if (ev->id.numid == id->numid) {
ev->mask |= mask;
@ -174,10 +174,10 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
}
_found:
wake_up(&ctl->change_sleep);
spin_unlock_irqrestore(&ctl->read_lock, flags);
spin_unlock(&ctl->read_lock);
kill_fasync(&ctl->fasync, SIGIO, POLL_IN);
}
read_unlock(&card->ctl_files_rwlock);
read_unlock_irqrestore(&card->ctl_files_rwlock, flags);
}
EXPORT_SYMBOL(snd_ctl_notify);
@ -717,22 +717,19 @@ static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
}
static int snd_ctl_elem_list(struct snd_card *card,
struct snd_ctl_elem_list __user *_list)
struct snd_ctl_elem_list *list)
{
struct snd_ctl_elem_list list;
struct snd_kcontrol *kctl;
struct snd_ctl_elem_id id;
unsigned int offset, space, jidx;
int err = 0;
if (copy_from_user(&list, _list, sizeof(list)))
return -EFAULT;
offset = list.offset;
space = list.space;
offset = list->offset;
space = list->space;
down_read(&card->controls_rwsem);
list.count = card->controls_count;
list.used = 0;
list->count = card->controls_count;
list->used = 0;
if (space > 0) {
list_for_each_entry(kctl, &card->controls, list) {
if (offset >= kctl->count) {
@ -741,12 +738,12 @@ static int snd_ctl_elem_list(struct snd_card *card,
}
for (jidx = offset; jidx < kctl->count; jidx++) {
snd_ctl_build_ioff(&id, kctl, jidx);
if (copy_to_user(list.pids + list.used, &id,
if (copy_to_user(list->pids + list->used, &id,
sizeof(id))) {
err = -EFAULT;
goto out;
}
list.used++;
list->used++;
if (!--space)
goto out;
}
@ -755,11 +752,26 @@ static int snd_ctl_elem_list(struct snd_card *card,
}
out:
up_read(&card->controls_rwsem);
if (!err && copy_to_user(_list, &list, sizeof(list)))
err = -EFAULT;
return err;
}
static int snd_ctl_elem_list_user(struct snd_card *card,
struct snd_ctl_elem_list __user *_list)
{
struct snd_ctl_elem_list list;
int err;
if (copy_from_user(&list, _list, sizeof(list)))
return -EFAULT;
err = snd_ctl_elem_list(card, &list);
if (err)
return err;
if (copy_to_user(_list, &list, sizeof(list)))
return -EFAULT;
return 0;
}
/* Check whether the given kctl info is valid */
static int snd_ctl_check_elem_info(struct snd_card *card,
const struct snd_ctl_elem_info *info)
@ -1703,7 +1715,7 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
case SNDRV_CTL_IOCTL_CARD_INFO:
return snd_ctl_card_info(card, ctl, cmd, argp);
case SNDRV_CTL_IOCTL_ELEM_LIST:
return snd_ctl_elem_list(card, argp);
return snd_ctl_elem_list_user(card, argp);
case SNDRV_CTL_IOCTL_ELEM_INFO:
return snd_ctl_elem_info_user(ctl, argp);
case SNDRV_CTL_IOCTL_ELEM_READ:
@ -1939,8 +1951,9 @@ int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type)
{
struct snd_ctl_file *kctl;
int subdevice = -1;
unsigned long flags;
read_lock(&card->ctl_files_rwlock);
read_lock_irqsave(&card->ctl_files_rwlock, flags);
list_for_each_entry(kctl, &card->ctl_files, list) {
if (kctl->pid == task_pid(current)) {
subdevice = kctl->preferred_subdevice[type];
@ -1948,7 +1961,7 @@ int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type)
break;
}
}
read_unlock(&card->ctl_files_rwlock);
read_unlock_irqrestore(&card->ctl_files_rwlock, flags);
return subdevice;
}
EXPORT_SYMBOL_GPL(snd_ctl_get_preferred_subdevice);
@ -1997,13 +2010,14 @@ static int snd_ctl_dev_disconnect(struct snd_device *device)
{
struct snd_card *card = device->device_data;
struct snd_ctl_file *ctl;
unsigned long flags;
read_lock(&card->ctl_files_rwlock);
read_lock_irqsave(&card->ctl_files_rwlock, flags);
list_for_each_entry(ctl, &card->ctl_files, list) {
wake_up(&ctl->change_sleep);
kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
}
read_unlock(&card->ctl_files_rwlock);
read_unlock_irqrestore(&card->ctl_files_rwlock, flags);
return snd_unregister_device(&card->ctl_dev);
}

View File

@ -22,24 +22,22 @@ struct snd_ctl_elem_list32 {
static int snd_ctl_elem_list_compat(struct snd_card *card,
struct snd_ctl_elem_list32 __user *data32)
{
struct snd_ctl_elem_list __user *data;
struct snd_ctl_elem_list data = {};
compat_caddr_t ptr;
int err;
data = compat_alloc_user_space(sizeof(*data));
/* offset, space, used, count */
if (copy_in_user(data, data32, 4 * sizeof(u32)))
if (copy_from_user(&data, data32, 4 * sizeof(u32)))
return -EFAULT;
/* pids */
if (get_user(ptr, &data32->pids) ||
put_user(compat_ptr(ptr), &data->pids))
if (get_user(ptr, &data32->pids))
return -EFAULT;
err = snd_ctl_elem_list(card, data);
data.pids = compat_ptr(ptr);
err = snd_ctl_elem_list(card, &data);
if (err < 0)
return err;
/* copy the result */
if (copy_in_user(data32, data, 4 * sizeof(u32)))
if (copy_to_user(data32, &data, 4 * sizeof(u32)))
return -EFAULT;
return 0;
}

View File

@ -114,7 +114,7 @@ static int snd_hrtimer_stop(struct snd_timer *t)
}
static const struct snd_timer_hardware hrtimer_hw __initconst = {
.flags = SNDRV_TIMER_HW_AUTO | SNDRV_TIMER_HW_TASKLET,
.flags = SNDRV_TIMER_HW_AUTO | SNDRV_TIMER_HW_WORK,
.open = snd_hrtimer_open,
.close = snd_hrtimer_close,
.start = snd_hrtimer_start,

View File

@ -203,28 +203,35 @@ static int snd_hwdep_dsp_status(struct snd_hwdep *hw,
}
static int snd_hwdep_dsp_load(struct snd_hwdep *hw,
struct snd_hwdep_dsp_image __user *_info)
struct snd_hwdep_dsp_image *info)
{
struct snd_hwdep_dsp_image info;
int err;
if (! hw->ops.dsp_load)
return -ENXIO;
memset(&info, 0, sizeof(info));
if (copy_from_user(&info, _info, sizeof(info)))
return -EFAULT;
if (info.index >= 32)
if (info->index >= 32)
return -EINVAL;
/* check whether the dsp was already loaded */
if (hw->dsp_loaded & (1u << info.index))
if (hw->dsp_loaded & (1u << info->index))
return -EBUSY;
err = hw->ops.dsp_load(hw, &info);
err = hw->ops.dsp_load(hw, info);
if (err < 0)
return err;
hw->dsp_loaded |= (1u << info.index);
hw->dsp_loaded |= (1u << info->index);
return 0;
}
static int snd_hwdep_dsp_load_user(struct snd_hwdep *hw,
struct snd_hwdep_dsp_image __user *_info)
{
struct snd_hwdep_dsp_image info = {};
if (copy_from_user(&info, _info, sizeof(info)))
return -EFAULT;
return snd_hwdep_dsp_load(hw, &info);
}
static long snd_hwdep_ioctl(struct file * file, unsigned int cmd,
unsigned long arg)
{
@ -238,7 +245,7 @@ static long snd_hwdep_ioctl(struct file * file, unsigned int cmd,
case SNDRV_HWDEP_IOCTL_DSP_STATUS:
return snd_hwdep_dsp_status(hw, argp);
case SNDRV_HWDEP_IOCTL_DSP_LOAD:
return snd_hwdep_dsp_load(hw, argp);
return snd_hwdep_dsp_load_user(hw, argp);
}
if (hw->ops.ioctl)
return hw->ops.ioctl(hw, file, cmd, arg);

View File

@ -19,26 +19,17 @@ struct snd_hwdep_dsp_image32 {
static int snd_hwdep_dsp_load_compat(struct snd_hwdep *hw,
struct snd_hwdep_dsp_image32 __user *src)
{
struct snd_hwdep_dsp_image __user *dst;
struct snd_hwdep_dsp_image info = {};
compat_caddr_t ptr;
u32 val;
dst = compat_alloc_user_space(sizeof(*dst));
if (copy_from_user(&info, src, 4 + 64) ||
get_user(ptr, &src->image) ||
get_user(info.length, &src->length) ||
get_user(info.driver_data, &src->driver_data))
return -EFAULT;
info.image = compat_ptr(ptr);
/* index and name */
if (copy_in_user(dst, src, 4 + 64))
return -EFAULT;
if (get_user(ptr, &src->image) ||
put_user(compat_ptr(ptr), &dst->image))
return -EFAULT;
if (get_user(val, &src->length) ||
put_user(val, &dst->length))
return -EFAULT;
if (get_user(val, &src->driver_data) ||
put_user(val, &dst->driver_data))
return -EFAULT;
return snd_hwdep_dsp_load(hw, dst);
return snd_hwdep_dsp_load(hw, &info);
}
enum {

View File

@ -519,10 +519,9 @@ EXPORT_SYMBOL(snd_card_free_when_closed);
*/
int snd_card_free(struct snd_card *card)
{
struct completion released;
DECLARE_COMPLETION_ONSTACK(released);
int ret;
init_completion(&released);
card->release_completion = &released;
ret = snd_card_free_when_closed(card);
if (ret)

View File

@ -157,8 +157,8 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
* so if we fail to malloc, try to fetch memory traditionally.
*/
dmab->dev.type = SNDRV_DMA_TYPE_DEV;
#endif /* CONFIG_GENERIC_ALLOCATOR */
fallthrough;
#endif /* CONFIG_GENERIC_ALLOCATOR */
case SNDRV_DMA_TYPE_DEV:
case SNDRV_DMA_TYPE_DEV_UC:
snd_malloc_dev_pages(dmab, size);

View File

@ -991,11 +991,13 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
kfree(runtime->hw_constraints.rules);
/* Avoid concurrent access to runtime via PCM timer interface */
if (substream->timer)
if (substream->timer) {
spin_lock_irq(&substream->timer->lock);
substream->runtime = NULL;
if (substream->timer)
substream->runtime = NULL;
spin_unlock_irq(&substream->timer->lock);
} else {
substream->runtime = NULL;
}
kfree(runtime);
put_pid(substream->pid);
substream->pid = NULL;

View File

@ -377,7 +377,7 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne
*/
int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
{
struct snd_card *card = substream->pcm->card;
struct snd_card *card;
struct snd_pcm_runtime *runtime;
struct snd_dma_buffer *dmab = NULL;
@ -387,6 +387,7 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
SNDRV_DMA_TYPE_UNKNOWN))
return -EINVAL;
runtime = substream->runtime;
card = substream->pcm->card;
if (runtime->dma_buffer_p) {
/* perphaps, we might free the large DMA memory region

View File

@ -35,7 +35,7 @@ module_param_array(amidi_map, int, NULL, 0444);
MODULE_PARM_DESC(amidi_map, "Raw MIDI device number assigned to 2nd OSS device.");
#endif /* CONFIG_SND_OSSEMUL */
static int snd_rawmidi_free(struct snd_rawmidi *rawmidi);
static int snd_rawmidi_free(struct snd_rawmidi *rmidi);
static int snd_rawmidi_dev_free(struct snd_device *device);
static int snd_rawmidi_dev_register(struct snd_device *device);
static int snd_rawmidi_dev_disconnect(struct snd_device *device);

View File

@ -174,9 +174,12 @@ odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (snd_BUG_ON(!dp))
return -ENXIO;
mutex_lock(&register_mutex);
if (cmd != SNDCTL_SEQ_SYNC &&
mutex_lock_interruptible(&register_mutex))
return -ERESTARTSYS;
rc = snd_seq_oss_ioctl(dp, cmd, arg);
mutex_unlock(&register_mutex);
if (cmd != SNDCTL_SEQ_SYNC)
mutex_unlock(&register_mutex);
return rc;
}

View File

@ -173,7 +173,7 @@ EXPORT_SYMBOL(snd_timer_instance_free);
*/
static struct snd_timer *snd_timer_find(struct snd_timer_id *tid)
{
struct snd_timer *timer = NULL;
struct snd_timer *timer;
list_for_each_entry(timer, &snd_timer_list, device_list) {
if (timer->tmr_class != tid->dev_class)
@ -813,12 +813,12 @@ static void snd_timer_clear_callbacks(struct snd_timer *timer,
}
/*
* timer tasklet
* timer work
*
*/
static void snd_timer_tasklet(struct tasklet_struct *t)
static void snd_timer_work(struct work_struct *work)
{
struct snd_timer *timer = from_tasklet(timer, t, task_queue);
struct snd_timer *timer = container_of(work, struct snd_timer, task_work);
unsigned long flags;
if (timer->card && timer->card->shutdown) {
@ -843,7 +843,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
unsigned long resolution;
struct list_head *ack_list_head;
unsigned long flags;
int use_tasklet = 0;
bool use_work = false;
if (timer == NULL)
return;
@ -884,7 +884,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
--timer->running;
list_del_init(&ti->active_list);
}
if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
if ((timer->hw.flags & SNDRV_TIMER_HW_WORK) ||
(ti->flags & SNDRV_TIMER_IFLG_FAST))
ack_list_head = &timer->ack_list_head;
else
@ -919,11 +919,11 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
snd_timer_process_callbacks(timer, &timer->ack_list_head);
/* do we have any slow callbacks? */
use_tasklet = !list_empty(&timer->sack_list_head);
use_work = !list_empty(&timer->sack_list_head);
spin_unlock_irqrestore(&timer->lock, flags);
if (use_tasklet)
tasklet_schedule(&timer->task_queue);
if (use_work)
queue_work(system_highpri_wq, &timer->task_work);
}
EXPORT_SYMBOL(snd_timer_interrupt);
@ -967,7 +967,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
INIT_LIST_HEAD(&timer->ack_list_head);
INIT_LIST_HEAD(&timer->sack_list_head);
spin_lock_init(&timer->lock);
tasklet_setup(&timer->task_queue, snd_timer_tasklet);
INIT_WORK(&timer->task_work, snd_timer_work);
timer->max_instances = 1000; /* default limit per timer */
if (card != NULL) {
timer->module = card->module;
@ -1200,7 +1200,7 @@ static int snd_timer_s_close(struct snd_timer *timer)
static const struct snd_timer_hardware snd_timer_system =
{
.flags = SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_TASKLET,
.flags = SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_WORK,
.resolution = 1000000000L / HZ,
.ticks = 10000000L,
.close = snd_timer_s_close,
@ -1280,8 +1280,8 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
list_for_each_entry(ti, &timer->open_list_head, open_list)
snd_iprintf(buffer, " Client %s : %s\n",
ti->owner ? ti->owner : "unknown",
ti->flags & (SNDRV_TIMER_IFLG_START |
SNDRV_TIMER_IFLG_RUNNING)
(ti->flags & (SNDRV_TIMER_IFLG_START |
SNDRV_TIMER_IFLG_RUNNING))
? "running" : "stopped");
}
mutex_unlock(&register_mutex);

View File

@ -110,7 +110,7 @@ struct loopback_cable {
struct {
int stream;
struct snd_timer_id id;
struct tasklet_struct event_tasklet;
struct work_struct event_work;
struct snd_timer_instance *instance;
} snd_timer;
};
@ -309,8 +309,8 @@ static int loopback_snd_timer_close_cable(struct loopback_pcm *dpcm)
*/
snd_timer_close(cable->snd_timer.instance);
/* wait till drain tasklet has finished if requested */
tasklet_kill(&cable->snd_timer.event_tasklet);
/* wait till drain work has finished if requested */
cancel_work_sync(&cable->snd_timer.event_work);
snd_timer_instance_free(cable->snd_timer.instance);
memset(&cable->snd_timer, 0, sizeof(cable->snd_timer));
@ -794,11 +794,11 @@ static void loopback_snd_timer_function(struct snd_timer_instance *timeri,
resolution);
}
static void loopback_snd_timer_tasklet(unsigned long arg)
static void loopback_snd_timer_work(struct work_struct *work)
{
struct snd_timer_instance *timeri = (struct snd_timer_instance *)arg;
struct loopback_cable *cable = timeri->callback_data;
struct loopback_cable *cable;
cable = container_of(work, struct loopback_cable, snd_timer.event_work);
loopback_snd_timer_period_elapsed(cable, SNDRV_TIMER_EVENT_MSTOP, 0);
}
@ -828,9 +828,9 @@ static void loopback_snd_timer_event(struct snd_timer_instance *timeri,
* state the streaming will be aborted by the usual timeout. It
* should not be aborted here because may be the timer sound
* card does only a recovery and the timer is back soon.
* This tasklet triggers loopback_snd_timer_tasklet()
* This work triggers loopback_snd_timer_work()
*/
tasklet_schedule(&cable->snd_timer.event_tasklet);
schedule_work(&cable->snd_timer.event_work);
}
}
@ -1124,7 +1124,7 @@ static int loopback_snd_timer_open(struct loopback_pcm *dpcm)
err = -ENOMEM;
goto exit;
}
/* The callback has to be called from another tasklet. If
/* The callback has to be called from another work. If
* SNDRV_TIMER_IFLG_FAST is specified it will be called from the
* snd_pcm_period_elapsed() call of the selected sound card.
* snd_pcm_period_elapsed() helds snd_pcm_stream_lock_irqsave().
@ -1137,9 +1137,8 @@ static int loopback_snd_timer_open(struct loopback_pcm *dpcm)
timeri->callback_data = (void *)cable;
timeri->ccallback = loopback_snd_timer_event;
/* initialise a tasklet used for draining */
tasklet_init(&cable->snd_timer.event_tasklet,
loopback_snd_timer_tasklet, (unsigned long)timeri);
/* initialise a work used for draining */
INIT_WORK(&cable->snd_timer.event_work, loopback_snd_timer_work);
/* The mutex loopback->cable_lock is kept locked.
* Therefore snd_timer_open() cannot be called a second time

View File

@ -23,10 +23,10 @@ MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround "
#define DMIX_WANTS_S16 1
/*
* Call snd_pcm_period_elapsed in a tasklet
* Call snd_pcm_period_elapsed in a work
* This avoids spinlock messes and long-running irq contexts
*/
static void pcsp_call_pcm_elapsed(unsigned long priv)
static void pcsp_call_pcm_elapsed(struct work_struct *work)
{
if (atomic_read(&pcsp_chip.timer_active)) {
struct snd_pcm_substream *substream;
@ -36,7 +36,7 @@ static void pcsp_call_pcm_elapsed(unsigned long priv)
}
}
static DECLARE_TASKLET_OLD(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed);
static DECLARE_WORK(pcsp_pcm_work, pcsp_call_pcm_elapsed);
/* write the port and returns the next expire time in ns;
* called at the trigger-start and in hrtimer callback
@ -119,11 +119,9 @@ static void pcsp_pointer_update(struct snd_pcsp *chip)
if (periods_elapsed) {
chip->period_ptr += periods_elapsed * period_bytes;
chip->period_ptr %= buffer_bytes;
queue_work(system_highpri_wq, &pcsp_pcm_work);
}
spin_unlock_irqrestore(&chip->substream_lock, flags);
if (periods_elapsed)
tasklet_schedule(&pcsp_pcm_tasklet);
}
enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
@ -196,7 +194,7 @@ void pcsp_sync_stop(struct snd_pcsp *chip)
pcsp_stop_playing(chip);
local_irq_enable();
hrtimer_cancel(&chip->timer);
tasklet_kill(&pcsp_pcm_tasklet);
cancel_work_sync(&pcsp_pcm_work);
}
static int snd_pcsp_playback_close(struct snd_pcm_substream *substream)

View File

@ -467,7 +467,7 @@ static int portman_probe(struct parport *p)
parport_write_control(p, 0); /* Reset Strobe=0. */
/* Check if Tx circuitry is functioning properly. If initialized
* unit TxEmpty is false, send out char and see if if goes true.
* unit TxEmpty is false, send out char and see if it goes true.
*/
/* 8 */
parport_write_control(p, TXDATA0); /* Tx channel 0, strobe off. */

View File

@ -597,9 +597,9 @@ static void vx_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *b
snd_iprintf(buffer, "%s\n", chip->card->longname);
snd_iprintf(buffer, "Xilinx Firmware: %s\n",
chip->chip_status & VX_STAT_XILINX_LOADED ? "Loaded" : "No");
(chip->chip_status & VX_STAT_XILINX_LOADED) ? "Loaded" : "No");
snd_iprintf(buffer, "Device Initialized: %s\n",
chip->chip_status & VX_STAT_DEVICE_INIT ? "Yes" : "No");
(chip->chip_status & VX_STAT_DEVICE_INIT) ? "Yes" : "No");
snd_iprintf(buffer, "DSP audio info:");
if (chip->audio_info & VX_AUDIO_INFO_REAL_TIME)
snd_iprintf(buffer, " realtime");

View File

@ -60,7 +60,6 @@ static void vx_pcm_read_per_bytes(struct vx_core *chip, struct snd_pcm_runtime *
*buf++ = vx_inb(chip, RXL);
if (++offset >= pipe->buffer_bytes) {
offset = 0;
buf = (unsigned char *)runtime->dma_area;
}
pipe->hw_ptr = offset;
}
@ -530,7 +529,6 @@ static int vx_pcm_playback_open(struct snd_pcm_substream *subs)
err = vx_alloc_pipe(chip, 0, audio, 2, &pipe); /* stereo playback */
if (err < 0)
return err;
chip->playback_pipes[audio] = pipe;
}
/* open for playback */
pipe->references++;

View File

@ -64,7 +64,7 @@
#define IT_PKT_HEADER_SIZE_CIP 8 // For 2 CIP header.
#define IT_PKT_HEADER_SIZE_NO_CIP 0 // Nothing.
static void pcm_period_tasklet(struct tasklet_struct *t);
static void pcm_period_work(struct work_struct *work);
/**
* amdtp_stream_init - initialize an AMDTP stream structure
@ -94,7 +94,7 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
s->flags = flags;
s->context = ERR_PTR(-1);
mutex_init(&s->mutex);
tasklet_setup(&s->period_tasklet, pcm_period_tasklet);
INIT_WORK(&s->period_work, pcm_period_work);
s->packet_index = 0;
init_waitqueue_head(&s->callback_wait);
@ -203,7 +203,7 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s,
// Linux driver for 1394 OHCI controller voluntarily flushes isoc
// context when total size of accumulated context header reaches
// PAGE_SIZE. This kicks tasklet for the isoc context and brings
// PAGE_SIZE. This kicks work for the isoc context and brings
// callback in the middle of scheduled interrupts.
// Although AMDTP streams in the same domain use the same events per
// IRQ, use the largest size of context header between IT/IR contexts.
@ -333,7 +333,7 @@ EXPORT_SYMBOL(amdtp_stream_get_max_payload);
*/
void amdtp_stream_pcm_prepare(struct amdtp_stream *s)
{
tasklet_kill(&s->period_tasklet);
cancel_work_sync(&s->period_work);
s->pcm_buffer_pointer = 0;
s->pcm_period_pointer = 0;
}
@ -437,13 +437,14 @@ static void update_pcm_pointers(struct amdtp_stream *s,
s->pcm_period_pointer += frames;
if (s->pcm_period_pointer >= pcm->runtime->period_size) {
s->pcm_period_pointer -= pcm->runtime->period_size;
tasklet_hi_schedule(&s->period_tasklet);
queue_work(system_highpri_wq, &s->period_work);
}
}
static void pcm_period_tasklet(struct tasklet_struct *t)
static void pcm_period_work(struct work_struct *work)
{
struct amdtp_stream *s = from_tasklet(s, t, period_tasklet);
struct amdtp_stream *s = container_of(work, struct amdtp_stream,
period_work);
struct snd_pcm_substream *pcm = READ_ONCE(s->pcm);
if (pcm)
@ -794,7 +795,7 @@ static void generate_pkt_descs(struct amdtp_stream *s, struct pkt_desc *descs,
static inline void cancel_stream(struct amdtp_stream *s)
{
s->packet_index = -1;
if (in_interrupt())
if (current_work() == &s->period_work)
amdtp_stream_pcm_abort(s);
WRITE_ONCE(s->pcm_buffer_pointer, SNDRV_PCM_POS_XRUN);
}
@ -1184,7 +1185,7 @@ unsigned long amdtp_domain_stream_pcm_pointer(struct amdtp_domain *d,
if (irq_target && amdtp_stream_running(irq_target)) {
// This function is called in software IRQ context of
// period_tasklet or process context.
// period_work or process context.
//
// When the software IRQ context was scheduled by software IRQ
// context of IT contexts, queued packets were already handled.
@ -1195,9 +1196,9 @@ unsigned long amdtp_domain_stream_pcm_pointer(struct amdtp_domain *d,
// immediately to keep better granularity of PCM pointer.
//
// Later, the process context will sometimes schedules software
// IRQ context of the period_tasklet. Then, no need to flush the
// IRQ context of the period_work. Then, no need to flush the
// queue by the same reason as described in the above
if (!in_interrupt()) {
if (current_work() != &s->period_work) {
// Queued packet should be processed without any kernel
// preemption to keep latency against bus cycle.
preempt_disable();
@ -1263,7 +1264,7 @@ static void amdtp_stream_stop(struct amdtp_stream *s)
return;
}
tasklet_kill(&s->period_tasklet);
cancel_work_sync(&s->period_work);
fw_iso_context_stop(s->context);
fw_iso_context_destroy(s->context);
s->context = ERR_PTR(-1);

View File

@ -163,7 +163,7 @@ struct amdtp_stream {
/* For a PCM substream processing. */
struct snd_pcm_substream *pcm;
struct tasklet_struct period_tasklet;
struct work_struct period_work;
snd_pcm_uframes_t pcm_buffer_pointer;
unsigned int pcm_period_pointer;

View File

@ -36,12 +36,11 @@ hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
}
memset(&event, 0, sizeof(event));
count = min_t(long, count, sizeof(event.lock_status));
if (bebob->dev_lock_changed) {
event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
event.lock_status.status = (bebob->dev_lock_count > 0);
bebob->dev_lock_changed = false;
count = min_t(long, count, sizeof(event.lock_status));
}
spin_unlock_irq(&bebob->lock);

View File

@ -148,7 +148,7 @@ pcm_init_hw_params(struct snd_efw *efw,
}
/* limit rates */
runtime->hw.rates = efw->supported_sampling_rate,
runtime->hw.rates = efw->supported_sampling_rate;
snd_pcm_limit_hw_rates(runtime);
limit_channels(&runtime->hw, pcm_channels);

View File

@ -70,11 +70,12 @@ static void default_release(struct device *dev)
* @bus: hdac bus to attach to
* @addr: codec address
* @hdev: hdac device to init
* @type: codec type (HDAC_DEV_*) to use for this device
*
* Returns zero for success or a negative error code.
*/
int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr,
struct hdac_device *hdev)
struct hdac_device *hdev, int type)
{
char name[15];
int ret;
@ -88,7 +89,7 @@ int snd_hdac_ext_bus_device_init(struct hdac_bus *bus, int addr,
dev_err(bus->dev, "device init failed for hdac device\n");
return ret;
}
hdev->type = HDA_DEV_ASOC;
hdev->type = type;
hdev->dev.release = default_release;
ret = snd_hdac_device_register(hdev);

View File

@ -210,12 +210,14 @@ static int hdac_component_master_bind(struct device *dev)
goto module_put;
}
complete_all(&acomp->master_bind_complete);
return 0;
module_put:
module_put(acomp->ops->owner);
out_unbind:
component_unbind_all(dev, acomp);
complete_all(&acomp->master_bind_complete);
return ret;
}
@ -296,6 +298,7 @@ int snd_hdac_acomp_init(struct hdac_bus *bus,
if (!acomp)
return -ENOMEM;
acomp->audio_ops = aops;
init_completion(&acomp->master_bind_complete);
bus->audio_component = acomp;
devres_add(dev, acomp);

View File

@ -11,9 +11,7 @@
#include <sound/hda_i915.h>
#include <sound/hda_register.h>
static struct completion bind_complete;
#define CONTROLLER_IN_GPU(pci) (((pci)->device == 0x0a0c) || \
#define IS_HSW_CONTROLLER(pci) (((pci)->device == 0x0a0c) || \
((pci)->device == 0x0c0c) || \
((pci)->device == 0x0d0c) || \
((pci)->device == 0x160c))
@ -41,7 +39,7 @@ void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq)
return; /* only for i915 binding */
if (!CONTROLLER_IN_GPU(pci))
if (!IS_HSW_CONTROLLER(pci))
return; /* only HSW/BDW */
cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev);
@ -73,11 +71,49 @@ void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
}
EXPORT_SYMBOL_GPL(snd_hdac_i915_set_bclk);
/* returns true if the devices can be connected for audio */
static bool connectivity_check(struct pci_dev *i915, struct pci_dev *hdac)
{
struct pci_bus *bus_a = i915->bus, *bus_b = hdac->bus;
/* directly connected on the same bus */
if (bus_a == bus_b)
return true;
/*
* on i915 discrete GPUs with embedded HDA audio, the two
* devices are connected via 2nd level PCI bridge
*/
bus_a = bus_a->parent;
bus_b = bus_b->parent;
if (!bus_a || !bus_b)
return false;
bus_a = bus_a->parent;
bus_b = bus_b->parent;
if (bus_a && bus_a == bus_b)
return true;
return false;
}
static int i915_component_master_match(struct device *dev, int subcomponent,
void *data)
{
return !strcmp(dev->driver->name, "i915") &&
subcomponent == I915_COMPONENT_AUDIO;
struct pci_dev *hdac_pci, *i915_pci;
struct hdac_bus *bus = data;
if (!dev_is_pci(dev))
return 0;
hdac_pci = to_pci_dev(bus->dev);
i915_pci = to_pci_dev(dev);
if (!strcmp(dev->driver->name, "i915") &&
subcomponent == I915_COMPONENT_AUDIO &&
connectivity_check(i915_pci, hdac_pci))
return 1;
return 0;
}
/* check whether intel graphics is present */
@ -92,19 +128,6 @@ static bool i915_gfx_present(void)
return pci_dev_present(ids);
}
static int i915_master_bind(struct device *dev,
struct drm_audio_component *acomp)
{
complete_all(&bind_complete);
/* clear audio_ops here as it was needed only for completion call */
acomp->audio_ops = NULL;
return 0;
}
static const struct drm_audio_component_audio_ops i915_init_ops = {
.master_bind = i915_master_bind
};
/**
* snd_hdac_i915_init - Initialize i915 audio component
* @bus: HDA core bus
@ -125,9 +148,7 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
if (!i915_gfx_present())
return -ENODEV;
init_completion(&bind_complete);
err = snd_hdac_acomp_init(bus, &i915_init_ops,
err = snd_hdac_acomp_init(bus, NULL,
i915_component_master_match,
sizeof(struct i915_audio_component) - sizeof(*acomp));
if (err < 0)
@ -139,8 +160,8 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
if (!IS_ENABLED(CONFIG_MODULES) ||
!request_module("i915")) {
/* 60s timeout */
wait_for_completion_timeout(&bind_complete,
msecs_to_jiffies(60 * 1000));
wait_for_completion_timeout(&acomp->master_bind_complete,
msecs_to_jiffies(60 * 1000));
}
}
if (!acomp->ops) {

View File

@ -117,7 +117,6 @@ struct snd_card_asihpi {
* snd_card_asihpi_timer_function().
*/
struct snd_card_asihpi_pcm *llmode_streampriv;
struct tasklet_struct t;
void (*pcm_start)(struct snd_pcm_substream *substream);
void (*pcm_stop)(struct snd_pcm_substream *substream);
@ -258,15 +257,6 @@ static inline u16 hpi_stream_group_reset(u32 h_stream)
return hpi_instream_group_reset(h_stream);
}
static inline u16 hpi_stream_group_get_map(
u32 h_stream, u32 *mo, u32 *mi)
{
if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
return hpi_outstream_group_get_map(h_stream, mo, mi);
else
return hpi_instream_group_get_map(h_stream, mo, mi);
}
static u16 handle_error(u16 err, int line, char *filename)
{
if (err)
@ -547,9 +537,7 @@ static void snd_card_asihpi_pcm_int_start(struct snd_pcm_substream *substream)
card = snd_pcm_substream_chip(substream);
WARN_ON(in_interrupt());
tasklet_disable(&card->t);
card->llmode_streampriv = dpcm;
tasklet_enable(&card->t);
hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
HPI_ADAPTER_PROPERTY_IRQ_RATE,
@ -565,13 +553,7 @@ static void snd_card_asihpi_pcm_int_stop(struct snd_pcm_substream *substream)
hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0));
if (in_interrupt())
card->llmode_streampriv = NULL;
else {
tasklet_disable(&card->t);
card->llmode_streampriv = NULL;
tasklet_enable(&card->t);
}
card->llmode_streampriv = NULL;
}
static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
@ -921,25 +903,15 @@ static void snd_card_asihpi_timer_function(struct timer_list *t)
add_timer(&dpcm->timer);
}
static void snd_card_asihpi_int_task(struct tasklet_struct *t)
{
struct snd_card_asihpi *asihpi = from_tasklet(asihpi, t, t);
struct hpi_adapter *a = asihpi->hpi;
WARN_ON(!a || !a->snd_card || !a->snd_card->private_data);
asihpi = (struct snd_card_asihpi *)a->snd_card->private_data;
if (asihpi->llmode_streampriv)
snd_card_asihpi_timer_function(
&asihpi->llmode_streampriv->timer);
}
static void snd_card_asihpi_isr(struct hpi_adapter *a)
{
struct snd_card_asihpi *asihpi;
WARN_ON(!a || !a->snd_card || !a->snd_card->private_data);
asihpi = (struct snd_card_asihpi *)a->snd_card->private_data;
tasklet_schedule(&asihpi->t);
if (asihpi->llmode_streampriv)
snd_card_asihpi_timer_function(
&asihpi->llmode_streampriv->timer);
}
/***************************** PLAYBACK OPS ****************/
@ -2871,7 +2843,6 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev,
if (hpi->interrupt_mode) {
asihpi->pcm_start = snd_card_asihpi_pcm_int_start;
asihpi->pcm_stop = snd_card_asihpi_pcm_int_stop;
tasklet_setup(&asihpi->t, snd_card_asihpi_int_task);
hpi->interrupt_callback = snd_card_asihpi_isr;
} else {
asihpi->pcm_start = snd_card_asihpi_pcm_timer_start;
@ -2960,14 +2931,12 @@ static int snd_asihpi_probe(struct pci_dev *pci_dev,
static void snd_asihpi_remove(struct pci_dev *pci_dev)
{
struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
struct snd_card_asihpi *asihpi = hpi->snd_card->private_data;
/* Stop interrupts */
if (hpi->interrupt_mode) {
hpi->interrupt_callback = NULL;
hpi_handle_error(hpi_adapter_set_property(hpi->adapter->index,
HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0));
tasklet_kill(&asihpi->t);
}
snd_card_free(hpi->snd_card);

View File

@ -329,11 +329,20 @@ static irqreturn_t asihpi_isr(int irq, void *dev_id)
asihpi_irq_count, a->adapter->type, a->adapter->index); */
if (a->interrupt_callback)
a->interrupt_callback(a);
return IRQ_WAKE_THREAD;
return IRQ_HANDLED;
}
static irqreturn_t asihpi_isr_thread(int irq, void *dev_id)
{
struct hpi_adapter *a = dev_id;
if (a->interrupt_callback)
a->interrupt_callback(a);
return IRQ_HANDLED;
}
int asihpi_adapter_probe(struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
@ -478,8 +487,9 @@ int asihpi_adapter_probe(struct pci_dev *pci_dev,
}
/* Note: request_irq calls asihpi_isr here */
if (request_irq(pci_dev->irq, asihpi_isr, IRQF_SHARED,
"asihpi", &adapters[adapter_index])) {
if (request_threaded_irq(pci_dev->irq, asihpi_isr,
asihpi_isr_thread, IRQF_SHARED,
"asihpi", &adapters[adapter_index])) {
dev_err(&pci_dev->dev, "request_irq(%d) failed\n",
pci_dev->irq);
goto err;

View File

@ -67,7 +67,7 @@ struct hpi_ioctl_linux {
};
/* Conflict?: H is already used by a number of drivers hid, bluetooth hci,
and some sound drivers sb16, hdsp, emu10k. AFAIK 0xFC is ununsed command
and some sound drivers sb16, hdsp, emu10k. AFAIK 0xFC is unused command
*/
#define HPI_IOCTL_LINUX _IOWR('H', 0xFC, struct hpi_ioctl_linux)

View File

@ -350,7 +350,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
*/
if (!cfg->line_outs && cfg->hp_outs > 1 &&
!(cond_flags & HDA_PINCFG_NO_HP_FIXUP)) {
int i = 0;
i = 0;
while (i < cfg->hp_outs) {
/* The real HPs should have the sequence 0x0f */
if ((hp_out[i].seq & 0x0f) == 0x0f) {

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