mirror of https://gitee.com/openkylin/linux.git
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:
commit
c48b75b727
|
@ -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.
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
};
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
};
|
|
@ -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.
|
||||
|
|
|
@ -17,6 +17,7 @@ properties:
|
|||
compatible:
|
||||
enum:
|
||||
- intel,keembay-i2s
|
||||
- intel,keembay-tdm
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
|
|
|
@ -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";
|
||||
};
|
|
@ -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>;
|
||||
};
|
|
@ -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>;
|
||||
};
|
||||
|
||||
...
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
};
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>;
|
||||
};
|
|
@ -27,6 +27,7 @@ properties:
|
|||
- enum:
|
||||
- rockchip,rk3188-spdif
|
||||
- rockchip,rk3288-spdif
|
||||
- rockchip,rk3308-spdif
|
||||
- const: rockchip,rk3066-spdif
|
||||
|
||||
reg:
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
|
@ -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>;
|
||||
};
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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*
|
||||
|
||||
|
|
|
@ -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 = {
|
|||
>a02_buttons_device,
|
||||
&s3c_device_adc,
|
||||
&s3c_device_ts,
|
||||
>a02_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(>a02_audio_gpio_table);
|
||||
platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
|
||||
pm_power_off = gta02_poweroff;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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__ */
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -174,9 +174,12 @@ odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
if (snd_BUG_ON(!dp))
|
||||
return -ENXIO;
|
||||
|
||||
mutex_lock(®ister_mutex);
|
||||
if (cmd != SNDCTL_SEQ_SYNC &&
|
||||
mutex_lock_interruptible(®ister_mutex))
|
||||
return -ERESTARTSYS;
|
||||
rc = snd_seq_oss_ioctl(dp, cmd, arg);
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (cmd != SNDCTL_SEQ_SYNC)
|
||||
mutex_unlock(®ister_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -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(®ister_mutex);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue