sound updates for 5.18
It's been a fairly calm development cycle. There are a few last-minute ALSA core fixes, most notably for covering PCM ioctl races, but the most of rest are device-specific changes. Below are some highlights: * ALSA core: - Fixes for PCM ioctl races that may lead to UAF - Fix for oversized allocations in PCM OSS layer * ASoC: - Start of moving SoF to support multiple IPC mechanisms - Use of NHLT ACPI table to reduce the amount of quirking required for Intel systems - Preliminary works forthcoming Intel AVS driver for legacy Intel DSP firmwares - Support for AMD PDM, Atmel PDMC, Awinic AW8738, i.MX cards with TLV320AIC31xx, Intel machines with CS35L41 and ESSX8336, Mediatek MT8181 wideband bluetooth, nVidia Tegra234, Qualcomm SC7280, Renesas RZ/V2L, Texas Instruments TAS585M * HD-audio: - Driver re-binding fix for HD-audio - Updates for Intel ADL and Tegra234, various platform quirks for Dell, HP, Lenovo, ASUS, Samsung and Clevo machines * USB-audio: - Quirk updates for Scarlett2, RODE, Corsair devices -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmI7AkUOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE/faBAAvPFODmyJlt16UG7bSlqwoSafWho+Bp4GSH4O +pEm47+kULgkKOm9k2NK7sci6nOsNIabQsVhMeryCLgDlNlFqR4FQjIswbgtRWsO lmu3TMw26I0vS2joNE+tpqCOyJuEGI/ekQru3aKAZx6JyBlXmrzuf7L4BNomVORr fgBgpMg/tRcE9ceWjc1qHMggueAfkcjnI4ioFYxaWYXp4wyVX1mx3mVHEf6WQnff ZXsgQLhupUKLvyBr2D1vkN6JcRyTahkBprbLEtZhKszR8hl6tFlnyILkzsiZ/B+K oJAvtEoC6z2PW+suPSPPl2qnbyOJyX32m43iCXW8uSG1KG/K2JshZIJshMbVw3pV rLK3XYr2zoE3VzzNUL+QyGYhLpdDPSNF+E19z7jfWU/wKwCUu8qWuejhf9uAlQgx XtlrZuyCpnsNVyILqLM2Sgzvc1U8vJd68uYwhecchTmP0Aurld5NM2PiAagcvVpW RtEMbTJbIBYbou3UPhxDjEdQOeT+KZUYrClEjb61pJQ9sHAbC4l0LoRyS4NEWCZH J7Z5DNPqPf6CFU1AVpfktL4Dh+VtM7nb4DVyyyLWWZgG3NcXSVLLbUA8Uo9qoDV5 7tHnV+1MURBwEq1CUvZtb3sRC5tyNVkzXMMAJfcVWlv7JkoXs8pzwK9w685aP2zl YDOfau8= =5cCU -----END PGP SIGNATURE----- Merge tag 'sound-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound updates from Takashi Iwai: "It's been a fairly calm development cycle. There are a few last-minute ALSA core fixes, most notably for covering PCM ioctl races, but the most of rest are device-specific changes. Below are some highlights: ALSA core: - Fixes for PCM ioctl races that may lead to UAF - Fix for oversized allocations in PCM OSS layer ASoC: - Start of moving SoF to support multiple IPC mechanisms - Use of NHLT ACPI table to reduce the amount of quirking required for Intel systems - Preliminary works forthcoming Intel AVS driver for legacy Intel DSP firmwares - Support for AMD PDM, Atmel PDMC, Awinic AW8738, i.MX cards with TLV320AIC31xx, Intel machines with CS35L41 and ESSX8336, Mediatek MT8181 wideband bluetooth, nVidia Tegra234, Qualcomm SC7280, Renesas RZ/V2L, Texas Instruments TAS585M HD-audio: - Driver re-binding fix for HD-audio - Updates for Intel ADL and Tegra234, various platform quirks for Dell, HP, Lenovo, ASUS, Samsung and Clevo machines USB-audio: - Quirk updates for Scarlett2, RODE, Corsair devices" * tag 'sound-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (486 commits) ALSA: hda/realtek: Add alc256-samsung-headphone fixup ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec ALSA: pcm: Add stream lock during PCM reset ioctl operations ALSA: pcm: Fix races among concurrent prealloc proc writes ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls ALSA: pcm: Fix races among concurrent read/write and buffer changes ALSA: pcm: Fix races among concurrent hw_params and hw_free calls ASoC: atmel: mchp-pdmc: print the correct property name MAINTAINERS: Add Shengjiu to maintainer list of sound/soc/fsl ASoC: SOF: Add a new dai_get_clk topology IPC op ASoC: SOF: topology: Add ops for setting up and tearing down pipelines ASoC: SOF: expose sof_route_setup() ASoC: SOF: Add dai_link_fixup PCM op for IPC3 ASoC: SOF: Add trigger PCM op for IPC3 ASoC: SOF: Define hw_params PCM op for IPC3 ASoC: SOF: Introduce IPC3 PCM hw_free op ASoC: SOF: pcm: expose the sof_pcm_setup_connected_widgets() function ASoC: SOF: Introduce IPC-specific PCM ops ASoC: SOF: Add bytes_ext control IPC ops for IPC3 ASoC: SOF: Add bytes_get/put control IPC ops for IPC3 ...
This commit is contained in:
commit
40037e4f8b
|
@ -21,6 +21,7 @@ properties:
|
|||
- const: nvidia,tegra210-aconnect
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra234-aconnect
|
||||
- nvidia,tegra186-aconnect
|
||||
- nvidia,tegra194-aconnect
|
||||
- const: nvidia,tegra210-aconnect
|
||||
|
|
|
@ -23,7 +23,9 @@ properties:
|
|||
- nvidia,tegra210-adma
|
||||
- nvidia,tegra186-adma
|
||||
- items:
|
||||
- const: nvidia,tegra194-adma
|
||||
- enum:
|
||||
- nvidia,tegra234-adma
|
||||
- nvidia,tegra194-adma
|
||||
- const: nvidia,tegra186-adma
|
||||
|
||||
reg:
|
||||
|
|
|
@ -58,6 +58,7 @@ properties:
|
|||
- enum:
|
||||
- nvidia,tegra186-agic
|
||||
- nvidia,tegra194-agic
|
||||
- nvidia,tegra234-agic
|
||||
- const: nvidia,tegra210-agic
|
||||
|
||||
interrupt-controller: true
|
||||
|
|
|
@ -31,6 +31,10 @@ properties:
|
|||
- const: allwinner,sun50i-a64-i2s
|
||||
- const: allwinner,sun8i-h3-i2s
|
||||
- const: allwinner,sun50i-h6-i2s
|
||||
- const: allwinner,sun50i-r329-i2s
|
||||
- items:
|
||||
- const: allwinner,sun20i-d1-i2s
|
||||
- const: allwinner,sun50i-r329-i2s
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -67,6 +71,7 @@ allOf:
|
|||
- allwinner,sun8i-h3-i2s
|
||||
- allwinner,sun50i-a64-codec-i2s
|
||||
- allwinner,sun50i-h6-i2s
|
||||
- allwinner,sun50i-r329-i2s
|
||||
|
||||
then:
|
||||
required:
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
Audio Binding for Arndale boards
|
||||
|
||||
Required properties:
|
||||
- compatible : Can be one of the following:
|
||||
"samsung,arndale-rt5631",
|
||||
"samsung,arndale-wm1811"
|
||||
|
||||
- samsung,audio-cpu: The phandle of the Samsung I2S controller
|
||||
- samsung,audio-codec: The phandle of the audio codec
|
||||
|
||||
Optional:
|
||||
- samsung,model: The name of the sound-card
|
||||
|
||||
Arndale Boards has many audio daughter cards, one of them is
|
||||
rt5631/alc5631. Below example shows audio bindings for rt5631/
|
||||
alc5631 based codec.
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "samsung,arndale-rt5631";
|
||||
|
||||
samsung,audio-cpu = <&i2s0>
|
||||
samsung,audio-codec = <&rt5631>;
|
||||
};
|
|
@ -71,4 +71,24 @@ patternProperties:
|
|||
description: CPU to Codec rate channels.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
dai-tdm-slot-width-map:
|
||||
description: Mapping of sample widths to slot widths. For hardware
|
||||
that cannot support a fixed slot width or a slot width always
|
||||
equal to sample width. A matrix of one or more 3-tuples.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-matrix
|
||||
items:
|
||||
items:
|
||||
-
|
||||
description: Sample width in bits
|
||||
minimum: 8
|
||||
maximum: 64
|
||||
-
|
||||
description: Slot width in bits
|
||||
minimum: 8
|
||||
maximum: 256
|
||||
-
|
||||
description: Slot count
|
||||
minimum: 1
|
||||
maximum: 64
|
||||
|
||||
additionalProperties: true
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/awinic,aw8738.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Awinic AW8738 Audio Amplifier
|
||||
|
||||
maintainers:
|
||||
- Stephan Gerhold <stephan@gerhold.net>
|
||||
|
||||
description:
|
||||
The Awinic AW8738 is a simple audio amplifier with different operation modes
|
||||
(set using one-wire pulse control). The mode configures the speaker-guard
|
||||
function (primarily the power limit for the amplifier).
|
||||
|
||||
allOf:
|
||||
- $ref: name-prefix.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: awinic,aw8738
|
||||
|
||||
mode-gpios:
|
||||
description:
|
||||
GPIO used for one-wire pulse control. The pin is typically called SHDN
|
||||
(active-low), but this is misleading since it is actually more than
|
||||
just a simple shutdown/enable control.
|
||||
maxItems: 1
|
||||
|
||||
awinic,mode:
|
||||
description: Operation mode (number of pulses for one-wire pulse control)
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 1
|
||||
maximum: 7
|
||||
|
||||
sound-name-prefix: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- mode-gpios
|
||||
- awinic,mode
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
audio-amplifier {
|
||||
compatible = "awinic,aw8738";
|
||||
mode-gpios = <&msmgpio 114 GPIO_ACTIVE_HIGH>;
|
||||
awinic,mode = <5>;
|
||||
sound-name-prefix = "Speaker Amp";
|
||||
};
|
|
@ -1,86 +0,0 @@
|
|||
Texas Instruments McASP controller
|
||||
|
||||
Required properties:
|
||||
- compatible :
|
||||
"ti,dm646x-mcasp-audio" : for DM646x platforms
|
||||
"ti,da830-mcasp-audio" : for both DA830 & DA850 platforms
|
||||
"ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx)
|
||||
"ti,dra7-mcasp-audio" : for DRA7xx platforms
|
||||
"ti,omap4-mcasp-audio" : for OMAP4
|
||||
|
||||
- reg : Should contain reg specifiers for the entries in the reg-names property.
|
||||
- reg-names : Should contain:
|
||||
* "mpu" for the main registers (required). For compatibility with
|
||||
existing software, it is recommended this is the first entry.
|
||||
* "dat" for separate data port register access (optional).
|
||||
- op-mode : I2S/DIT ops mode. 0 for I2S mode. 1 for DIT mode used for S/PDIF,
|
||||
IEC60958-1, and AES-3 formats.
|
||||
- tdm-slots : Slots for TDM operation. Indicates number of channels transmitted
|
||||
or received over one serializer.
|
||||
- serial-dir : A list of serializer configuration. Each entry is a number
|
||||
indication for serializer pin direction.
|
||||
(0 - INACTIVE, 1 - TX, 2 - RX)
|
||||
- dmas: two element list of DMA controller phandles and DMA request line
|
||||
ordered pairs.
|
||||
- dma-names: identifier string for each DMA request line in the dmas property.
|
||||
These strings correspond 1:1 with the ordered pairs in dmas. The dma
|
||||
identifiers must be "rx" and "tx".
|
||||
|
||||
Optional properties:
|
||||
|
||||
- ti,hwmods : Must be "mcasp<n>", n is controller instance starting 0
|
||||
- tx-num-evt : FIFO levels.
|
||||
- rx-num-evt : FIFO levels.
|
||||
- dismod : Specify the drive on TX pin during inactive slots
|
||||
0 : 3-state
|
||||
2 : logic low
|
||||
3 : logic high
|
||||
Defaults to 'logic low' when the property is not present
|
||||
- sram-size-playback : size of sram to be allocated during playback
|
||||
- sram-size-capture : size of sram to be allocated during capture
|
||||
- interrupts : Interrupt numbers for McASP
|
||||
- interrupt-names : Known interrupt names are "tx" and "rx"
|
||||
- pinctrl-0: Should specify pin control group used for this controller.
|
||||
- pinctrl-names: Should contain only one value - "default", for more details
|
||||
please refer to pinctrl-bindings.txt
|
||||
- fck_parent : Should contain a valid clock name which will be used as parent
|
||||
for the McASP fck
|
||||
- auxclk-fs-ratio: When McASP is bus master indicates the ratio between AUCLK
|
||||
and FS rate if applicable:
|
||||
AUCLK rate = auxclk-fs-ratio * FS rate
|
||||
|
||||
Optional GPIO support:
|
||||
If any McASP pin need to be used as GPIO then the McASP node must have:
|
||||
...
|
||||
gpio-controller
|
||||
#gpio-cells = <2>;
|
||||
...
|
||||
|
||||
When requesting a GPIO, the first parameter is the PIN index in McASP_P*
|
||||
registers.
|
||||
For example to request the AXR2 pin of mcasp8:
|
||||
function-gpios = <&mcasp8 2 0>;
|
||||
|
||||
Or to request the ACLKR pin of mcasp8:
|
||||
function-gpios = <&mcasp8 29 0>;
|
||||
|
||||
For generic gpio information, please refer to bindings/gpio/gpio.txt
|
||||
|
||||
Example:
|
||||
|
||||
mcasp0: mcasp0@1d00000 {
|
||||
compatible = "ti,da830-mcasp-audio";
|
||||
reg = <0x100000 0x3000>;
|
||||
reg-names "mpu";
|
||||
interrupts = <82>, <83>;
|
||||
interrupt-names = "tx", "rx";
|
||||
op-mode = <0>; /* MCASP_IIS_MODE */
|
||||
tdm-slots = <2>;
|
||||
serial-dir = <
|
||||
0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */
|
||||
0 0 0 0
|
||||
0 0 0 1
|
||||
2 0 0 0 >;
|
||||
tx-num-evt = <1>;
|
||||
rx-num-evt = <1>;
|
||||
};
|
|
@ -0,0 +1,201 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/davinci-mcasp-audio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: McASP Controller for TI SoCs
|
||||
|
||||
maintainers:
|
||||
- Jayesh Choudhary <j-choudhary@ti.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,dm646x-mcasp-audio
|
||||
- ti,da830-mcasp-audio
|
||||
- ti,am33xx-mcasp-audio
|
||||
- ti,dra7-mcasp-audio
|
||||
- ti,omap4-mcasp-audio
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: CFG registers
|
||||
- description: data registers
|
||||
|
||||
reg-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: mpu
|
||||
- const: dat
|
||||
|
||||
op-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: 0 - I2S or 1 - DIT operation mode
|
||||
enum:
|
||||
- 0
|
||||
- 1
|
||||
|
||||
tdm-slots:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
number of channels over one serializer
|
||||
the property is ignored in DIT mode
|
||||
minimum: 2
|
||||
maximum: 32
|
||||
|
||||
serial-dir:
|
||||
description:
|
||||
A list of serializer configuration
|
||||
Entry is indication for serializer pin direction
|
||||
0 - Inactive, 1 - TX, 2 - RX
|
||||
All AXR pins should be present in the array even if inactive
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 25
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 2
|
||||
|
||||
dmas:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: transmission DMA channel
|
||||
- description: reception DMA channel
|
||||
|
||||
dma-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: tx
|
||||
- const: rx
|
||||
|
||||
ti,hwmods:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: Name of hwmod associated with McASP
|
||||
maxItems: 1
|
||||
deprecated: true
|
||||
|
||||
tx-num-evt:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
configures WFIFO threshold
|
||||
0 disables the FIFO use
|
||||
if property is missing, then also FIFO use is disabled
|
||||
|
||||
rx-num-evt:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
configures RFIFO threshold
|
||||
0 disables the FIFO use
|
||||
if property is missing, then also FIFO use is disabled
|
||||
|
||||
dismod:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
specify the drive on TX pin during inactive time slots
|
||||
0 - 3-state, 2 - logic low, 3 - logic high
|
||||
enum:
|
||||
- 0
|
||||
- 2
|
||||
- 3
|
||||
default: 2
|
||||
|
||||
interrupts:
|
||||
anyOf:
|
||||
- minItems: 1
|
||||
items:
|
||||
- description: TX interrupt
|
||||
- description: RX interrupt
|
||||
- items:
|
||||
- description: common/combined interrupt
|
||||
|
||||
interrupt-names:
|
||||
oneOf:
|
||||
- minItems: 1
|
||||
items:
|
||||
- const: tx
|
||||
- const: rx
|
||||
- const: common
|
||||
|
||||
fck_parent:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: parent clock name for McASP fck
|
||||
maxItems: 1
|
||||
|
||||
auxclk-fs-ratio:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: ratio of AUCLK and FS rate if applicable
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
"#gpio-cells":
|
||||
const: 2
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: functional clock
|
||||
- description: module specific optional ahclkx clock
|
||||
- description: module specific optional ahclkr clock
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: fck
|
||||
- const: ahclkx
|
||||
- const: ahclkr
|
||||
|
||||
power-domains:
|
||||
description: phandle to the corresponding power-domain
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
port:
|
||||
description: connection for when McASP is used via graph card
|
||||
type: object
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- dmas
|
||||
- dma-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
opmode:
|
||||
enum:
|
||||
- 0
|
||||
|
||||
then:
|
||||
required:
|
||||
- tdm-slots
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mcasp0: mcasp0@1d00000 {
|
||||
compatible = "ti,da830-mcasp-audio";
|
||||
reg = <0x100000 0x3000>;
|
||||
reg-names = "mpu";
|
||||
interrupts = <82>, <83>;
|
||||
interrupt-names = "tx", "rx";
|
||||
op-mode = <0>; /* MCASP_IIS_MODE */
|
||||
tdm-slots = <2>;
|
||||
dmas = <&main_udmap 0xc400>, <&main_udmap 0x4400>;
|
||||
dma-names = "tx", "rx";
|
||||
serial-dir = <
|
||||
0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */
|
||||
0 0 0 0
|
||||
0 0 0 1
|
||||
2 0 0 0 >;
|
||||
tx-num-evt = <1>;
|
||||
rx-num-evt = <1>;
|
||||
};
|
|
@ -40,6 +40,8 @@ The compatible list for this generic sound card currently:
|
|||
|
||||
"fsl,imx-audio-tlv320aic32x4"
|
||||
|
||||
"fsl,imx-audio-tlv320aic31xx"
|
||||
|
||||
"fsl,imx-audio-si476x"
|
||||
|
||||
"fsl,imx-audio-wm8958"
|
||||
|
@ -82,6 +84,7 @@ Optional properties:
|
|||
- dai-format : audio format, for details see simple-card.yaml.
|
||||
- frame-inversion : dai-link uses frame clock inversion, for details see simple-card.yaml.
|
||||
- bitclock-inversion : dai-link uses bit clock inversion, for details see simple-card.yaml.
|
||||
- mclk-id : main clock id, specific for each card configuration.
|
||||
|
||||
Optional unless SSI is selected as a CPU DAI:
|
||||
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/google,sc7280-herobrine.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Google SC7280-Herobrine ASoC sound card driver
|
||||
|
||||
maintainers:
|
||||
- Srinivasa Rao Mandadapu <srivasam@codeaurora.org>
|
||||
- Judy Hsiao <judyhsiao@chromium.org>
|
||||
|
||||
description:
|
||||
This binding describes the SC7280 sound card which uses LPASS for audio.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- google,sc7280-herobrine
|
||||
|
||||
audio-routing:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
description:
|
||||
A list of the connections between audio components. Each entry is a
|
||||
pair of strings, the first being the connection's sink, the second
|
||||
being the connection's source.
|
||||
|
||||
model:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: User specified audio sound card name
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"^dai-link@[0-9a-f]$":
|
||||
description:
|
||||
Each subnode represents a dai link. Subnodes of each dai links would be
|
||||
cpu/codec dais.
|
||||
|
||||
type: object
|
||||
|
||||
properties:
|
||||
link-name:
|
||||
description: Indicates dai-link name and PCM stream name.
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
maxItems: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: dai link address.
|
||||
|
||||
cpu:
|
||||
description: Holds subnode which indicates cpu dai.
|
||||
type: object
|
||||
properties:
|
||||
sound-dai: true
|
||||
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
codec:
|
||||
description: Holds subnode which indicates codec dai.
|
||||
type: object
|
||||
properties:
|
||||
sound-dai: true
|
||||
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- link-name
|
||||
- cpu
|
||||
- codec
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- model
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
||||
- |
|
||||
#include <dt-bindings/sound/qcom,lpass.h>
|
||||
sound {
|
||||
compatible = "google,sc7280-herobrine";
|
||||
model = "sc7280-wcd938x-max98360a-4dmic";
|
||||
|
||||
audio-routing =
|
||||
"IN1_HPHL", "HPHL_OUT",
|
||||
"IN2_HPHR", "HPHR_OUT",
|
||||
"AMIC1", "MIC BIAS1",
|
||||
"AMIC2", "MIC BIAS2",
|
||||
"VA DMIC0", "MIC BIAS3",
|
||||
"VA DMIC1", "MIC BIAS3",
|
||||
"VA DMIC2", "MIC BIAS4",
|
||||
"VA DMIC3", "MIC BIAS4",
|
||||
"TX SWR_ADC0", "ADC1_OUTPUT",
|
||||
"TX SWR_ADC1", "ADC2_OUTPUT",
|
||||
"TX SWR_ADC2", "ADC3_OUTPUT",
|
||||
"TX SWR_DMIC0", "DMIC1_OUTPUT",
|
||||
"TX SWR_DMIC1", "DMIC2_OUTPUT",
|
||||
"TX SWR_DMIC2", "DMIC3_OUTPUT",
|
||||
"TX SWR_DMIC3", "DMIC4_OUTPUT";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
dai-link@0 {
|
||||
link-name = "WCD Playback";
|
||||
reg = <LPASS_CDC_DMA_RX0>;
|
||||
cpu {
|
||||
sound-dai = <&lpass_cpu LPASS_CDC_DMA_RX0>;
|
||||
};
|
||||
|
||||
codec {
|
||||
sound-dai = <&wcd938x 0>, <&swr0 0>, <&rxmacro 0>;
|
||||
};
|
||||
};
|
||||
dai-link@1 {
|
||||
link-name = "WCD Capture";
|
||||
reg = <LPASS_CDC_DMA_TX3>;
|
||||
cpu {
|
||||
sound-dai = <&lpass_cpu LPASS_CDC_DMA_TX3>;
|
||||
};
|
||||
|
||||
codec {
|
||||
sound-dai = <&wcd938x 1>, <&swr1 0>, <&txmacro 0>;
|
||||
};
|
||||
};
|
||||
|
||||
dai-link@2 {
|
||||
link-name = "MI2S Playback";
|
||||
reg = <MI2S_SECONDARY>;
|
||||
cpu {
|
||||
sound-dai = <&lpass_cpu MI2S_SECONDARY>;
|
||||
};
|
||||
|
||||
codec {
|
||||
sound-dai = <&max98360a>;
|
||||
};
|
||||
};
|
||||
|
||||
dai-link@3 {
|
||||
link-name = "DMIC Capture";
|
||||
reg = <LPASS_CDC_DMA_VA_TX0>;
|
||||
cpu {
|
||||
sound-dai = <&lpass_cpu LPASS_CDC_DMA_VA_TX0>;
|
||||
};
|
||||
|
||||
codec {
|
||||
sound-dai = <&vamacro 0>;
|
||||
};
|
||||
};
|
||||
|
||||
dai-link@5 {
|
||||
link-name = "DP Playback";
|
||||
reg = <LPASS_DP_RX>;
|
||||
cpu {
|
||||
sound-dai = <&lpass_cpu LPASS_DP_RX>;
|
||||
};
|
||||
|
||||
codec {
|
||||
sound-dai = <&mdss_dp>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,100 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/microchip,pdmc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip Pulse Density Microphone Controller
|
||||
|
||||
maintainers:
|
||||
- Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
|
||||
|
||||
description:
|
||||
The Microchip Pulse Density Microphone Controller (PDMC) interfaces up to 4
|
||||
digital microphones having Pulse Density Modulated (PDM) outputs.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: microchip,sama7g5-pdmc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 0
|
||||
|
||||
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
|
||||
|
||||
microchip,mic-pos:
|
||||
description: |
|
||||
Position of PDM microphones on the DS line and the sampling edge (rising
|
||||
or falling) of the CLK line. A microphone is represented as a pair of DS
|
||||
line and the sampling edge. The first microphone is mapped to channel 0,
|
||||
the second to channel 1, etc.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-matrix
|
||||
items:
|
||||
items:
|
||||
- description: value for DS line
|
||||
- description: value for sampling edge
|
||||
anyOf:
|
||||
- enum:
|
||||
- [0, 0]
|
||||
- [0, 1]
|
||||
- [1, 0]
|
||||
- [1, 1]
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
uniqueItems: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#sound-dai-cells"
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- dmas
|
||||
- dma-names
|
||||
- microchip,mic-pos
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/at91.h>
|
||||
#include <dt-bindings/dma/at91.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/sound/microchip,pdmc.h>
|
||||
|
||||
pdmc: sound@e1608000 {
|
||||
compatible = "microchip,sama7g5-pdmc";
|
||||
reg = <0xe1608000 0x4000>;
|
||||
#sound-dai-cells = <0>;
|
||||
interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
|
||||
dmas = <&dma0 AT91_XDMAC_DT_PERID(37)>;
|
||||
dma-names = "rx";
|
||||
clocks = <&pmc PMC_TYPE_PERIPHERAL 68>, <&pmc PMC_TYPE_GCK 68>;
|
||||
clock-names = "pclk", "gclk";
|
||||
microchip,mic-pos = <MCHP_PDMC_DS0 MCHP_PDMC_CLK_POSITIVE>,
|
||||
<MCHP_PDMC_DS0 MCHP_PDMC_CLK_NEGATIVE>,
|
||||
<MCHP_PDMC_DS1 MCHP_PDMC_CLK_POSITIVE>,
|
||||
<MCHP_PDMC_DS1 MCHP_PDMC_CLK_NEGATIVE>;
|
||||
};
|
|
@ -19,6 +19,12 @@ properties:
|
|||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
const: audiosys
|
||||
|
||||
memory-region:
|
||||
maxItems: 1
|
||||
description: |
|
||||
|
@ -127,6 +133,8 @@ required:
|
|||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- resets
|
||||
- reset-names
|
||||
- mediatek,topckgen
|
||||
- power-domains
|
||||
- clocks
|
||||
|
@ -144,6 +152,8 @@ examples:
|
|||
compatible = "mediatek,mt8195-audio";
|
||||
reg = <0x10890000 0x10000>;
|
||||
interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
resets = <&watchdog 14>;
|
||||
reset-names = "audiosys";
|
||||
mediatek,topckgen = <&topckgen>;
|
||||
power-domains = <&spm 7>; //MT8195_POWER_DOMAIN_AUDIO
|
||||
memory-region = <&snd_dma_mem_reserved>;
|
||||
|
|
|
@ -28,7 +28,9 @@ properties:
|
|||
oneOf:
|
||||
- const: nvidia,tegra186-dspk
|
||||
- items:
|
||||
- const: nvidia,tegra194-dspk
|
||||
- enum:
|
||||
- nvidia,tegra234-dspk
|
||||
- nvidia,tegra194-dspk
|
||||
- const: nvidia,tegra186-dspk
|
||||
|
||||
reg:
|
||||
|
|
|
@ -27,7 +27,9 @@ properties:
|
|||
- nvidia,tegra210-admaif
|
||||
- nvidia,tegra186-admaif
|
||||
- items:
|
||||
- const: nvidia,tegra194-admaif
|
||||
- enum:
|
||||
- nvidia,tegra234-admaif
|
||||
- nvidia,tegra194-admaif
|
||||
- const: nvidia,tegra186-admaif
|
||||
|
||||
reg:
|
||||
|
|
|
@ -30,6 +30,7 @@ properties:
|
|||
- const: nvidia,tegra210-adx
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra234-adx
|
||||
- nvidia,tegra194-adx
|
||||
- nvidia,tegra186-adx
|
||||
- const: nvidia,tegra210-adx
|
||||
|
|
|
@ -26,6 +26,7 @@ properties:
|
|||
- enum:
|
||||
- nvidia,tegra210-ahub
|
||||
- nvidia,tegra186-ahub
|
||||
- nvidia,tegra234-ahub
|
||||
- items:
|
||||
- const: nvidia,tegra194-ahub
|
||||
- const: nvidia,tegra186-ahub
|
||||
|
|
|
@ -31,6 +31,9 @@ properties:
|
|||
- const: nvidia,tegra186-amx
|
||||
- const: nvidia,tegra210-amx
|
||||
- const: nvidia,tegra194-amx
|
||||
- items:
|
||||
- const: nvidia,tegra234-amx
|
||||
- const: nvidia,tegra194-amx
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
@ -28,6 +28,7 @@ properties:
|
|||
- const: nvidia,tegra210-dmic
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra234-dmic
|
||||
- nvidia,tegra194-dmic
|
||||
- nvidia,tegra186-dmic
|
||||
- const: nvidia,tegra210-dmic
|
||||
|
|
|
@ -28,6 +28,7 @@ properties:
|
|||
- const: nvidia,tegra210-i2s
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra234-i2s
|
||||
- nvidia,tegra194-i2s
|
||||
- nvidia,tegra186-i2s
|
||||
- const: nvidia,tegra210-i2s
|
||||
|
|
|
@ -28,6 +28,7 @@ properties:
|
|||
- const: nvidia,tegra210-amixer
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra234-amixer
|
||||
- nvidia,tegra194-amixer
|
||||
- nvidia,tegra186-amixer
|
||||
- const: nvidia,tegra210-amixer
|
||||
|
|
|
@ -31,6 +31,7 @@ properties:
|
|||
- const: nvidia,tegra210-mvc
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra234-mvc
|
||||
- nvidia,tegra194-mvc
|
||||
- nvidia,tegra186-mvc
|
||||
- const: nvidia,tegra210-mvc
|
||||
|
|
|
@ -28,6 +28,7 @@ properties:
|
|||
- const: nvidia,tegra210-sfc
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra234-sfc
|
||||
- nvidia,tegra194-sfc
|
||||
- nvidia,tegra186-sfc
|
||||
- const: nvidia,tegra210-sfc
|
||||
|
|
|
@ -23,6 +23,7 @@ properties:
|
|||
- const: nvidia,tegra30-hda
|
||||
- items:
|
||||
- enum:
|
||||
- nvidia,tegra234-hda
|
||||
- nvidia,tegra194-hda
|
||||
- nvidia,tegra186-hda
|
||||
- nvidia,tegra210-hda
|
||||
|
@ -41,9 +42,11 @@ properties:
|
|||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
items:
|
||||
- const: hda
|
||||
- const: hda2hdmi
|
||||
|
|
|
@ -22,35 +22,41 @@ properties:
|
|||
- qcom,lpass-cpu
|
||||
- qcom,apq8016-lpass-cpu
|
||||
- qcom,sc7180-lpass-cpu
|
||||
- qcom,sc7280-lpass-cpu
|
||||
|
||||
reg:
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
maxItems: 6
|
||||
description: LPAIF core registers
|
||||
|
||||
reg-names:
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
maxItems: 6
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
maxItems: 6
|
||||
maxItems: 7
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
maxItems: 6
|
||||
maxItems: 7
|
||||
|
||||
interrupts:
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
description: LPAIF DMA buffer interrupt
|
||||
|
||||
interrupt-names:
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
|
||||
qcom,adsp:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: Phandle for the audio DSP node
|
||||
|
||||
iommus:
|
||||
maxItems: 2
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
description: Phandle to apps_smmu node with sid mask
|
||||
|
||||
power-domains:
|
||||
|
@ -69,7 +75,7 @@ patternProperties:
|
|||
"^dai-link@[0-9a-f]$":
|
||||
type: object
|
||||
description: |
|
||||
LPASS CPU dai node for each I2S device. Bindings of each node
|
||||
LPASS CPU dai node for each I2S device or Soundwire device. Bindings of each node
|
||||
depends on the specific driver providing the functionality and
|
||||
properties.
|
||||
properties:
|
||||
|
@ -174,6 +180,59 @@ allOf:
|
|||
- iommus
|
||||
- power-domains
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,sc7280-lpass-cpu
|
||||
|
||||
then:
|
||||
properties:
|
||||
clock-names:
|
||||
oneOf:
|
||||
- items: #for I2S
|
||||
- const: aon_cc_audio_hm_h
|
||||
- const: core_cc_sysnoc_mport_core
|
||||
- const: core_cc_ext_if1_ibit
|
||||
- items: #for Soundwire
|
||||
- const: aon_cc_audio_hm_h
|
||||
- const: audio_cc_codec_mem0
|
||||
- const: audio_cc_codec_mem1
|
||||
- const: audio_cc_codec_mem2
|
||||
- items: #for HDMI
|
||||
- const: aon_cc_audio_hm_h
|
||||
|
||||
reg-names:
|
||||
anyOf:
|
||||
- items: #for I2S
|
||||
- const: lpass-lpaif
|
||||
- items: #for I2S and HDMI
|
||||
- const: lpass-hdmiif
|
||||
- const: lpass-lpaif
|
||||
- items: #for I2S, soundwire and HDMI
|
||||
- const: lpass-hdmiif
|
||||
- const: lpass-lpaif
|
||||
- const: lpass-rxtx-cdc-dma-lpm
|
||||
- const: lpass-rxtx-lpaif
|
||||
- const: lpass-va-lpaif
|
||||
- const: lpass-va-cdc-dma-lpm
|
||||
interrupt-names:
|
||||
anyOf:
|
||||
- items: #for I2S
|
||||
- const: lpass-irq-lpaif
|
||||
- items: #for I2S and HDMI
|
||||
- const: lpass-irq-lpaif
|
||||
- const: lpass-irq-hdmi
|
||||
- items: #for I2S, soundwire and HDMI
|
||||
- const: lpass-irq-lpaif
|
||||
- const: lpass-irq-hdmi
|
||||
- const: lpass-irq-vaif
|
||||
- const: lpass-irq-rxtxif
|
||||
|
||||
required:
|
||||
- iommus
|
||||
- power-domains
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/sound/sc7180-lpass.h>
|
||||
|
|
|
@ -39,6 +39,14 @@ properties:
|
|||
items:
|
||||
- const: mclk
|
||||
|
||||
power-domains:
|
||||
maxItems: 2
|
||||
|
||||
power-domain-names:
|
||||
items:
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
|
|
@ -39,6 +39,14 @@ properties:
|
|||
items:
|
||||
- const: mclk
|
||||
|
||||
power-domains:
|
||||
maxItems: 2
|
||||
|
||||
power-domain-names:
|
||||
items:
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
|
||||
qcom,dmic-sample-rate:
|
||||
description: dmic sample rate
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
|
|
@ -37,6 +37,14 @@ properties:
|
|||
items:
|
||||
- const: fsgen
|
||||
|
||||
power-domains:
|
||||
maxItems: 2
|
||||
|
||||
power-domain-names:
|
||||
items:
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
|
||||
qcom,dmic-sample-rate:
|
||||
description: dmic sample rate
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
|
|
@ -23,6 +23,10 @@ properties:
|
|||
description: GPIO spec for reset line to use
|
||||
maxItems: 1
|
||||
|
||||
us-euro-gpios:
|
||||
description: GPIO spec for swapping gnd and mic segments
|
||||
maxItems: 1
|
||||
|
||||
vdd-buck-supply:
|
||||
description: A reference to the 1.8V buck supply
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ properties:
|
|||
description: I2C address of the device.
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description: The CODEC's interrupt output.
|
||||
|
||||
realtek,dmic1-data-pin:
|
||||
|
@ -94,7 +95,7 @@ required:
|
|||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/tegra-gpio.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
|
@ -104,10 +105,9 @@ examples:
|
|||
codec@1a {
|
||||
compatible = "realtek,rt5682s";
|
||||
reg = <0x1a>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <TEGRA_GPIO(U, 6) IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <6 IRQ_TYPE_LEVEL_HIGH>;
|
||||
realtek,ldo1-en-gpios =
|
||||
<&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
|
||||
<&gpio 2 GPIO_ACTIVE_HIGH>;
|
||||
realtek,dmic1-data-pin = <1>;
|
||||
realtek,dmic1-clk-pin = <1>;
|
||||
realtek,jd-src = <1>;
|
||||
|
|
|
@ -123,9 +123,7 @@ properties:
|
|||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
# use patternProperties to avoid naming "xxx,yyy" issue
|
||||
patternProperties:
|
||||
"^rcar_sound,dvc$":
|
||||
rcar_sound,dvc:
|
||||
description: DVC subnode.
|
||||
type: object
|
||||
patternProperties:
|
||||
|
@ -141,7 +139,7 @@ patternProperties:
|
|||
- dma-names
|
||||
additionalProperties: false
|
||||
|
||||
"^rcar_sound,mix$":
|
||||
rcar_sound,mix:
|
||||
description: MIX subnode.
|
||||
type: object
|
||||
patternProperties:
|
||||
|
@ -150,7 +148,7 @@ patternProperties:
|
|||
# no properties
|
||||
additionalProperties: false
|
||||
|
||||
"^rcar_sound,ctu$":
|
||||
rcar_sound,ctu:
|
||||
description: CTU subnode.
|
||||
type: object
|
||||
patternProperties:
|
||||
|
@ -159,7 +157,7 @@ patternProperties:
|
|||
# no properties
|
||||
additionalProperties: false
|
||||
|
||||
"^rcar_sound,src$":
|
||||
rcar_sound,src:
|
||||
description: SRC subnode.
|
||||
type: object
|
||||
patternProperties:
|
||||
|
@ -182,7 +180,7 @@ patternProperties:
|
|||
- dma-names
|
||||
additionalProperties: false
|
||||
|
||||
"^rcar_sound,ssiu$":
|
||||
rcar_sound,ssiu:
|
||||
description: SSIU subnode.
|
||||
type: object
|
||||
patternProperties:
|
||||
|
@ -202,7 +200,7 @@ patternProperties:
|
|||
- dma-names
|
||||
additionalProperties: false
|
||||
|
||||
"^rcar_sound,ssi$":
|
||||
rcar_sound,ssi:
|
||||
description: SSI subnode.
|
||||
type: object
|
||||
patternProperties:
|
||||
|
@ -239,7 +237,7 @@ patternProperties:
|
|||
additionalProperties: false
|
||||
|
||||
# For DAI base
|
||||
"^rcar_sound,dai$":
|
||||
rcar_sound,dai:
|
||||
description: DAI subnode.
|
||||
type: object
|
||||
patternProperties:
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
$id: http://devicetree.org/schemas/sound/renesas,rz-ssi.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas RZ/G2L ASoC Sound Serial Interface (SSIF-2)
|
||||
title: Renesas RZ/{G2L,V2L} ASoC Sound Serial Interface (SSIF-2)
|
||||
|
||||
maintainers:
|
||||
- Biju Das <biju.das.jz@bp.renesas.com>
|
||||
|
@ -14,6 +14,7 @@ properties:
|
|||
items:
|
||||
- enum:
|
||||
- renesas,r9a07g044-ssi # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-ssi # RZ/V2L
|
||||
- const: renesas,rz-ssi
|
||||
|
||||
reg:
|
||||
|
|
|
@ -31,6 +31,8 @@ properties:
|
|||
description: |
|
||||
phandles to the I2S controller and bluetooth codec,
|
||||
in that order
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
codec:
|
||||
type: object
|
||||
|
@ -38,6 +40,8 @@ properties:
|
|||
sound-dai:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: phandle to the WM8994 CODEC
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
samsung,audio-routing:
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/samsung,arndale.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Insignal Arndale boards audio complex
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
|
||||
- Sylwester Nawrocki <s.nawrocki@samsung.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- samsung,arndale-alc5631
|
||||
- samsung,arndale-rt5631
|
||||
- samsung,arndale-wm1811
|
||||
|
||||
samsung,audio-codec:
|
||||
description: Phandle to the audio codec.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
samsung,audio-cpu:
|
||||
description: Phandle to the Samsung I2S controller.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
samsung,model:
|
||||
description: The user-visible name of this sound complex.
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- samsung,audio-codec
|
||||
- samsung,audio-cpu
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sound {
|
||||
compatible = "samsung,arndale-rt5631";
|
||||
samsung,audio-cpu = <&i2s0>;
|
||||
samsung,audio-codec = <&rt5631>;
|
||||
};
|
|
@ -1,14 +0,0 @@
|
|||
Samsung SMDK audio complex
|
||||
|
||||
Required properties:
|
||||
- compatible : "samsung,smdk-wm8994"
|
||||
- samsung,i2s-controller: The phandle of the Samsung I2S0 controller
|
||||
- samsung,audio-codec: The phandle of the WM8994 audio codec
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "samsung,smdk-wm8994";
|
||||
|
||||
samsung,i2s-controller = <&i2s0>;
|
||||
samsung,audio-codec = <&wm8994>;
|
||||
};
|
|
@ -0,0 +1,38 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/samsung,smdk5250.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung SMDK5250 audio complex with WM8994 codec
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
|
||||
- Sylwester Nawrocki <s.nawrocki@samsung.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: samsung,smdk-wm8994
|
||||
|
||||
samsung,audio-codec:
|
||||
description: Phandle to the audio codec.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
samsung,i2s-controller:
|
||||
description: Phandle to the Samsung I2S controller.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- samsung,audio-codec
|
||||
- samsung,i2s-controller
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sound {
|
||||
compatible = "samsung,smdk-wm8994";
|
||||
samsung,i2s-controller = <&i2s0>;
|
||||
samsung,audio-codec = <&wm8994>;
|
||||
};
|
|
@ -0,0 +1,74 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/samsung,snow.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Google Snow audio complex with MAX9809x codec
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
|
||||
- Sylwester Nawrocki <s.nawrocki@samsung.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- google,snow-audio-max98090
|
||||
- google,snow-audio-max98091
|
||||
- google,snow-audio-max98095
|
||||
|
||||
codec:
|
||||
type: object
|
||||
properties:
|
||||
sound-dai:
|
||||
description: List of phandles to the CODEC and HDMI IP nodes.
|
||||
items:
|
||||
- description: Phandle to the MAX98090, MAX98091 or MAX98095 CODEC.
|
||||
- description: Phandle to the HDMI IP block node.
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
cpu:
|
||||
type: object
|
||||
properties:
|
||||
sound-dai:
|
||||
description: Phandle to the Samsung I2S controller.
|
||||
maxItems: 1
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
samsung,audio-codec:
|
||||
description: Phandle to the audio codec.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
deprecated: true
|
||||
|
||||
samsung,i2s-controller:
|
||||
description: Phandle to the Samsung I2S controller.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
deprecated: true
|
||||
|
||||
samsung,model:
|
||||
description: The user-visible name of this sound complex.
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- codec
|
||||
- cpu
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sound {
|
||||
compatible = "google,snow-audio-max98095";
|
||||
samsung,model = "Snow-I2S-MAX98095";
|
||||
|
||||
cpu {
|
||||
sound-dai = <&i2s0 0>;
|
||||
};
|
||||
|
||||
codec {
|
||||
sound-dai = <&max98095 0>, <&hdmi>;
|
||||
};
|
||||
};
|
|
@ -1,42 +0,0 @@
|
|||
Samsung Exynos5433 TM2(E) audio complex with WM5110 codec
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "samsung,tm2-audio"
|
||||
- model : the user-visible name of this sound complex
|
||||
- audio-codec : the first entry should be phandle of the wm5110 audio
|
||||
codec node, as described in ../mfd/arizona.txt;
|
||||
the second entry should be phandle of the HDMI
|
||||
transmitter node
|
||||
- i2s-controller : the list of phandle and argument tuples pointing to
|
||||
I2S controllers, the first entry should be I2S0 and
|
||||
the second one I2S1
|
||||
- audio-amplifier : the phandle of the MAX98504 amplifier
|
||||
- samsung,audio-routing : a list of the connections between audio components;
|
||||
each entry is a pair of strings, the first being the
|
||||
connection's sink, the second being the connection's
|
||||
source; valid names for sources and sinks are the
|
||||
WM5110's and MAX98504's pins and the jacks on the
|
||||
board: HP, SPK, Main Mic, Sub Mic, Third Mic,
|
||||
Headset Mic
|
||||
- mic-bias-gpios : GPIO pin that enables the Main Mic bias regulator
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "samsung,tm2-audio";
|
||||
audio-codec = <&wm5110>, <&hdmi>;
|
||||
i2s-controller = <&i2s0 0>, <&i2s1 0>;
|
||||
audio-amplifier = <&max98504>;
|
||||
mic-bias-gpios = <&gpr3 2 0>;
|
||||
model = "wm5110";
|
||||
samsung,audio-routing =
|
||||
"HP", "HPOUT1L",
|
||||
"HP", "HPOUT1R",
|
||||
"SPK", "SPKOUT",
|
||||
"SPKOUT", "HPOUT2L",
|
||||
"SPKOUT", "HPOUT2R",
|
||||
"Main Mic", "MICBIAS2",
|
||||
"IN1R", "Main Mic";
|
||||
};
|
|
@ -0,0 +1,80 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/samsung,tm2.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung Exynos5433 TM2(E) audio complex with WM5110 codec
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
|
||||
- Sylwester Nawrocki <s.nawrocki@samsung.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: samsung,tm2-audio
|
||||
|
||||
audio-amplifier:
|
||||
description: Phandle to the MAX98504 amplifier.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
audio-codec:
|
||||
description: Phandles to the codecs.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
- description: Phandle to the WM5110 audio codec.
|
||||
- description: Phandle to the HDMI transmitter node.
|
||||
|
||||
samsung,audio-routing:
|
||||
description: |
|
||||
List of the connections between audio components; each entry is
|
||||
a pair of strings, the first being the connection's sink, the second
|
||||
being the connection's source; valid names for sources and sinks are the
|
||||
WM5110's and MAX98504's pins and the jacks on the board: HP, SPK, Main
|
||||
Mic, Sub Mic, Third Mic, Headset Mic.
|
||||
$ref: /schemas/types.yaml#/definitions/non-unique-string-array
|
||||
|
||||
i2s-controller:
|
||||
description: Phandles to the I2S controllers.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
- description: Phandle to I2S0.
|
||||
- description: Phandle to I2S1.
|
||||
|
||||
mic-bias-gpios:
|
||||
description: GPIO pin that enables the Main Mic bias regulator.
|
||||
|
||||
model:
|
||||
description: The user-visible name of this sound complex.
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- audio-amplifier
|
||||
- audio-codec
|
||||
- samsung,audio-routing
|
||||
- i2s-controller
|
||||
- mic-bias-gpios
|
||||
- model
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
sound {
|
||||
compatible = "samsung,tm2-audio";
|
||||
audio-codec = <&wm5110>, <&hdmi>;
|
||||
i2s-controller = <&i2s0 0>, <&i2s1 0>;
|
||||
audio-amplifier = <&max98504>;
|
||||
mic-bias-gpios = <&gpr3 2 GPIO_ACTIVE_HIGH>;
|
||||
model = "wm5110";
|
||||
samsung,audio-routing = "HP", "HPOUT1L",
|
||||
"HP", "HPOUT1R",
|
||||
"SPK", "SPKOUT",
|
||||
"SPKOUT", "HPOUT2L",
|
||||
"SPKOUT", "HPOUT2R",
|
||||
"RCV", "HPOUT3L",
|
||||
"RCV", "HPOUT3R";
|
||||
};
|
|
@ -48,6 +48,15 @@ definitions:
|
|||
It is useful for some aCPUs with fixed clocks.
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
|
||||
system-clock-fixed:
|
||||
description: |
|
||||
Specifies that the clock frequency should not be modified.
|
||||
Implied when system-clock-frequency is specified, but can be used when
|
||||
a clock is mapped to the device whose frequency cannot or should not be
|
||||
changed. When mclk-fs is also specified, this restricts the device to a
|
||||
single fixed sampling rate.
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
|
||||
mclk-fs:
|
||||
description: |
|
||||
Multiplication factor between stream rate and codec mclk.
|
||||
|
@ -134,6 +143,8 @@ definitions:
|
|||
$ref: "#/definitions/system-clock-frequency"
|
||||
system-clock-direction-out:
|
||||
$ref: "#/definitions/system-clock-direction-out"
|
||||
system-clock-fixed:
|
||||
$ref: "#/definitions/system-clock-fixed"
|
||||
required:
|
||||
- sound-dai
|
||||
|
||||
|
@ -156,45 +167,45 @@ properties:
|
|||
description: User specified audio sound card name.
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
|
||||
# use patternProperties to avoid naming "xxx,yyy" issue
|
||||
patternProperties:
|
||||
"^simple-audio-card,widgets$":
|
||||
simple-audio-card,widgets:
|
||||
$ref: "#/definitions/widgets"
|
||||
"^simple-audio-card,routing$":
|
||||
simple-audio-card,routing:
|
||||
$ref: "#/definitions/routing"
|
||||
"^simple-audio-card,cpu(@[0-9a-f]+)?":
|
||||
$ref: "#/definitions/dai"
|
||||
"^simple-audio-card,codec(@[0-9a-f]+)?":
|
||||
$ref: "#/definitions/dai"
|
||||
|
||||
# common properties
|
||||
"^simple-audio-card,frame-master$":
|
||||
simple-audio-card,frame-master:
|
||||
$ref: "#/definitions/frame-master"
|
||||
"^simple-audio-card,bitclock-master$":
|
||||
simple-audio-card,bitclock-master:
|
||||
$ref: "#/definitions/bitclock-master"
|
||||
"^simple-audio-card,frame-inversion$":
|
||||
simple-audio-card,frame-inversion:
|
||||
$ref: "#/definitions/frame-inversion"
|
||||
"^simple-audio-card,bitclock-inversion$":
|
||||
simple-audio-card,bitclock-inversion:
|
||||
$ref: "#/definitions/bitclock-inversion"
|
||||
"^simple-audio-card,format$":
|
||||
simple-audio-card,format:
|
||||
$ref: "#/definitions/format"
|
||||
"^simple-audio-card,mclk-fs$":
|
||||
simple-audio-card,mclk-fs:
|
||||
$ref: "#/definitions/mclk-fs"
|
||||
"^simple-audio-card,aux-devs$":
|
||||
simple-audio-card,aux-devs:
|
||||
$ref: "#/definitions/aux-devs"
|
||||
"^simple-audio-card,convert-rate$":
|
||||
simple-audio-card,convert-rate:
|
||||
$ref: "#/definitions/convert-rate"
|
||||
"^simple-audio-card,convert-channels$":
|
||||
simple-audio-card,convert-channels:
|
||||
$ref: "#/definitions/convert-channels"
|
||||
"^simple-audio-card,prefix$":
|
||||
simple-audio-card,prefix:
|
||||
$ref: "#/definitions/prefix"
|
||||
"^simple-audio-card,pin-switches$":
|
||||
simple-audio-card,pin-switches:
|
||||
$ref: "#/definitions/pin-switches"
|
||||
"^simple-audio-card,hp-det-gpio$":
|
||||
simple-audio-card,hp-det-gpio:
|
||||
maxItems: 1
|
||||
"^simple-audio-card,mic-det-gpio$":
|
||||
simple-audio-card,mic-det-gpio:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
"^simple-audio-card,cpu(@[0-9a-f]+)?$":
|
||||
$ref: "#/definitions/dai"
|
||||
"^simple-audio-card,codec(@[0-9a-f]+)?$":
|
||||
$ref: "#/definitions/dai"
|
||||
|
||||
"^simple-audio-card,dai-link(@[0-9a-f]+)?$":
|
||||
description: |
|
||||
Container for dai-link level properties and the CPU and CODEC sub-nodes.
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
Audio Binding for Snow boards
|
||||
|
||||
Required properties:
|
||||
- compatible : Can be one of the following,
|
||||
"google,snow-audio-max98090" or
|
||||
"google,snow-audio-max98091" or
|
||||
"google,snow-audio-max98095"
|
||||
- samsung,i2s-controller (deprecated): The phandle of the Samsung I2S controller
|
||||
- samsung,audio-codec (deprecated): The phandle of the audio codec
|
||||
|
||||
Required sub-nodes:
|
||||
|
||||
- 'cpu' subnode with a 'sound-dai' property containing the phandle of the I2S
|
||||
controller
|
||||
- 'codec' subnode with a 'sound-dai' property containing list of phandles
|
||||
to the CODEC nodes, first entry must be the phandle of the MAX98090,
|
||||
MAX98091 or MAX98095 CODEC (exact device type is indicated by the compatible
|
||||
string) and the second entry must be the phandle of the HDMI IP block node
|
||||
|
||||
Optional:
|
||||
- samsung,model: The name of the sound-card
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "google,snow-audio-max98095";
|
||||
|
||||
samsung,model = "Snow-I2S-MAX98095";
|
||||
samsung,i2s-controller = <&i2s0>;
|
||||
samsung,audio-codec = <&max98095>;
|
||||
};
|
|
@ -0,0 +1,56 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/tas5805m.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TAS5805M audio amplifier
|
||||
|
||||
maintainers:
|
||||
- Daniel Beer <daniel.beer@igorinstitute.com>
|
||||
|
||||
description: |
|
||||
The TAS5805M is a class D audio amplifier with a built-in DSP.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,tas5805m
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: |
|
||||
I2C address of the amplifier. See the datasheet for possible values.
|
||||
|
||||
pvdd-supply:
|
||||
description: |
|
||||
Regulator for audio power supply (PVDD in the datasheet).
|
||||
|
||||
pdn-gpios:
|
||||
description: |
|
||||
Power-down control GPIO (PDN pin in the datasheet).
|
||||
|
||||
ti,dsp-config-name:
|
||||
description: |
|
||||
The name of the DSP configuration that should be loaded for this
|
||||
instance. Configuration blobs are sequences of register writes
|
||||
generated from TI's PPC3 tool.
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
tas5805m: tas5805m@2c {
|
||||
reg = <0x2c>;
|
||||
compatible = "ti,tas5805m";
|
||||
|
||||
pvdd-supply = <&audiopwr>;
|
||||
pdn-gpios = <&tlmm 160 0>;
|
||||
|
||||
ti,dsp-config-name = "mono_pbtl_48khz";
|
||||
};
|
||||
};
|
||||
|
||||
additionalProperties: true
|
|
@ -58,7 +58,7 @@ The pins can be used in referring sound node's audio-routing property.
|
|||
|
||||
Example:
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/sound/tlv320aic31xx-micbias.h>
|
||||
#include <dt-bindings/sound/tlv320aic31xx.h>
|
||||
|
||||
tlv320aic31xx: tlv320aic31xx@18 {
|
||||
compatible = "ti,tlv320aic311x";
|
||||
|
|
|
@ -34,7 +34,7 @@ CHANNEL
|
|||
Front front left/right channels
|
||||
Surround rear left/right in 4.0/5.1 surround
|
||||
CLFE C/LFE channels
|
||||
Center center cannel
|
||||
Center center channel
|
||||
LFE LFE channel
|
||||
Side side left/right for 7.1 surround
|
||||
============ ==================================================
|
||||
|
|
|
@ -261,6 +261,10 @@ alc-sense-combo
|
|||
huawei-mbx-stereo
|
||||
Enable initialization verbs for Huawei MBX stereo speakers;
|
||||
might be risky, try this at your own risk
|
||||
alc298-samsung-headphone
|
||||
Samsung laptops with ALC298
|
||||
alc256-samsung-headphone
|
||||
Samsung laptops with ALC256
|
||||
|
||||
ALC66x/67x/892
|
||||
==============
|
||||
|
|
|
@ -389,11 +389,11 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
|||
S: Maintained
|
||||
F: drivers/acpi/arm64
|
||||
|
||||
ACPI I2C MULTI INSTANTIATE DRIVER
|
||||
ACPI SERIAL MULTI INSTANTIATE DRIVER
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/platform/x86/i2c-multi-instantiate.c
|
||||
F: drivers/platform/x86/serial-multi-instantiate.c
|
||||
|
||||
ACPI PCC(Platform Communication Channel) MAILBOX DRIVER
|
||||
M: Sudeep Holla <sudeep.holla@arm.com>
|
||||
|
@ -7812,10 +7812,10 @@ F: drivers/net/ethernet/freescale/fs_enet/
|
|||
F: include/linux/fs_enet_pd.h
|
||||
|
||||
FREESCALE SOC SOUND DRIVERS
|
||||
M: Nicolin Chen <nicoleotsuka@gmail.com>
|
||||
M: Shengjiu Wang <shengjiu.wang@gmail.com>
|
||||
M: Xiubo Li <Xiubo.Lee@gmail.com>
|
||||
R: Fabio Estevam <festevam@gmail.com>
|
||||
R: Shengjiu Wang <shengjiu.wang@gmail.com>
|
||||
R: Nicolin Chen <nicoleotsuka@gmail.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
S: Maintained
|
||||
|
@ -19184,6 +19184,7 @@ TEXAS INSTRUMENTS ASoC DRIVERS
|
|||
M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
|
||||
F: sound/soc/ti/
|
||||
|
||||
TEXAS INSTRUMENTS' DAC7612 DAC DRIVER
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <dt-bindings/pinctrl/am43xx.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pwm/pwm.h>
|
||||
#include <dt-bindings/sound/tlv320aic31xx-micbias.h>
|
||||
#include <dt-bindings/sound/tlv320aic31xx.h>
|
||||
|
||||
/ {
|
||||
model = "TI AM43x EPOS EVM";
|
||||
|
|
|
@ -1735,17 +1735,21 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
|
|||
bool is_serial_bus_slave = false;
|
||||
static const struct acpi_device_id ignore_serial_bus_ids[] = {
|
||||
/*
|
||||
* These devices have multiple I2cSerialBus resources and an i2c-client
|
||||
* must be instantiated for each, each with its own i2c_device_id.
|
||||
* Normally we only instantiate an i2c-client for the first resource,
|
||||
* using the ACPI HID as id. These special cases are handled by the
|
||||
* drivers/platform/x86/i2c-multi-instantiate.c driver, which knows
|
||||
* which i2c_device_id to use for each resource.
|
||||
* These devices have multiple SerialBus resources and a client
|
||||
* device must be instantiated for each of them, each with
|
||||
* its own device id.
|
||||
* Normally we only instantiate one client device for the first
|
||||
* resource, using the ACPI HID as id. These special cases are handled
|
||||
* by the drivers/platform/x86/serial-multi-instantiate.c driver, which
|
||||
* knows which client device id to use for each resource.
|
||||
*/
|
||||
{"BSG1160", },
|
||||
{"BSG2150", },
|
||||
{"CSC3551", },
|
||||
{"INT33FE", },
|
||||
{"INT3515", },
|
||||
/* Non-conforming _HID for Cirrus Logic already released */
|
||||
{"CLSA0100", },
|
||||
/*
|
||||
* HIDs of device with an UartSerialBusV2 resource for which userspace
|
||||
* expects a regular tty cdev to be created (instead of the in kernel
|
||||
|
|
|
@ -586,6 +586,13 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
|
|||
return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes));
|
||||
}
|
||||
|
||||
static void cdn_dp_audio_handle_plugged_change(struct cdn_dp_device *dp,
|
||||
bool plugged)
|
||||
{
|
||||
if (dp->codec_dev)
|
||||
dp->plugged_cb(dp->codec_dev, plugged);
|
||||
}
|
||||
|
||||
static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
|
||||
{
|
||||
struct cdn_dp_device *dp = encoder_to_dp(encoder);
|
||||
|
@ -641,6 +648,9 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
|
|||
DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
cdn_dp_audio_handle_plugged_change(dp, true);
|
||||
|
||||
out:
|
||||
mutex_unlock(&dp->lock);
|
||||
}
|
||||
|
@ -651,6 +661,8 @@ static void cdn_dp_encoder_disable(struct drm_encoder *encoder)
|
|||
int ret;
|
||||
|
||||
mutex_lock(&dp->lock);
|
||||
cdn_dp_audio_handle_plugged_change(dp, false);
|
||||
|
||||
if (dp->active) {
|
||||
ret = cdn_dp_disable(dp);
|
||||
if (ret) {
|
||||
|
@ -846,11 +858,27 @@ static int cdn_dp_audio_get_eld(struct device *dev, void *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cdn_dp_audio_hook_plugged_cb(struct device *dev, void *data,
|
||||
hdmi_codec_plugged_cb fn,
|
||||
struct device *codec_dev)
|
||||
{
|
||||
struct cdn_dp_device *dp = dev_get_drvdata(dev);
|
||||
|
||||
mutex_lock(&dp->lock);
|
||||
dp->plugged_cb = fn;
|
||||
dp->codec_dev = codec_dev;
|
||||
cdn_dp_audio_handle_plugged_change(dp, dp->connected);
|
||||
mutex_unlock(&dp->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hdmi_codec_ops audio_codec_ops = {
|
||||
.hw_params = cdn_dp_audio_hw_params,
|
||||
.audio_shutdown = cdn_dp_audio_shutdown,
|
||||
.mute_stream = cdn_dp_audio_mute_stream,
|
||||
.get_eld = cdn_dp_audio_get_eld,
|
||||
.hook_plugged_cb = cdn_dp_audio_hook_plugged_cb,
|
||||
.no_capture_mute = 1,
|
||||
};
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <drm/drm_dp_helper.h>
|
||||
#include <drm/drm_panel.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <sound/hdmi-codec.h>
|
||||
|
||||
#include "rockchip_drm_drv.h"
|
||||
|
||||
|
@ -101,5 +102,8 @@ struct cdn_dp_device {
|
|||
|
||||
u8 dpcd[DP_RECEIVER_CAP_SIZE];
|
||||
bool sink_has_audio;
|
||||
|
||||
hdmi_codec_plugged_cb plugged_cb;
|
||||
struct device *codec_dev;
|
||||
};
|
||||
#endif /* _CDN_DP_CORE_H */
|
||||
|
|
|
@ -990,16 +990,16 @@ config TOPSTAR_LAPTOP
|
|||
|
||||
If you have a Topstar laptop, say Y or M here.
|
||||
|
||||
config I2C_MULTI_INSTANTIATE
|
||||
tristate "I2C multi instantiate pseudo device driver"
|
||||
depends on I2C && ACPI
|
||||
config SERIAL_MULTI_INSTANTIATE
|
||||
tristate "Serial bus multi instantiate pseudo device driver"
|
||||
depends on I2C && SPI && ACPI
|
||||
help
|
||||
Some ACPI-based systems list multiple i2c-devices in a single ACPI
|
||||
firmware-node. This driver will instantiate separate i2c-clients
|
||||
Some ACPI-based systems list multiple devices in a single ACPI
|
||||
firmware-node. This driver will instantiate separate clients
|
||||
for each device in the firmware-node.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called i2c-multi-instantiate.
|
||||
will be called serial-multi-instantiate.
|
||||
|
||||
config MLX_PLATFORM
|
||||
tristate "Mellanox Technologies platform support"
|
||||
|
|
|
@ -110,7 +110,7 @@ obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
|
|||
|
||||
# Platform drivers
|
||||
obj-$(CONFIG_FW_ATTR_CLASS) += firmware_attributes_class.o
|
||||
obj-$(CONFIG_I2C_MULTI_INSTANTIATE) += i2c-multi-instantiate.o
|
||||
obj-$(CONFIG_SERIAL_MULTI_INSTANTIATE) += serial-multi-instantiate.o
|
||||
obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.o
|
||||
obj-$(CONFIG_WIRELESS_HOTKEY) += wireless-hotkey.o
|
||||
|
|
|
@ -1,174 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* I2C multi-instantiate driver, pseudo driver to instantiate multiple
|
||||
* i2c-clients from a single fwnode.
|
||||
*
|
||||
* Copyright 2018 Hans de Goede <hdegoede@redhat.com>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define IRQ_RESOURCE_TYPE GENMASK(1, 0)
|
||||
#define IRQ_RESOURCE_NONE 0
|
||||
#define IRQ_RESOURCE_GPIO 1
|
||||
#define IRQ_RESOURCE_APIC 2
|
||||
|
||||
struct i2c_inst_data {
|
||||
const char *type;
|
||||
unsigned int flags;
|
||||
int irq_idx;
|
||||
};
|
||||
|
||||
struct i2c_multi_inst_data {
|
||||
int num_clients;
|
||||
struct i2c_client *clients[];
|
||||
};
|
||||
|
||||
static int i2c_multi_inst_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_multi_inst_data *multi;
|
||||
const struct i2c_inst_data *inst_data;
|
||||
struct i2c_board_info board_info = {};
|
||||
struct device *dev = &pdev->dev;
|
||||
struct acpi_device *adev;
|
||||
char name[32];
|
||||
int i, ret;
|
||||
|
||||
inst_data = device_get_match_data(dev);
|
||||
if (!inst_data) {
|
||||
dev_err(dev, "Error ACPI match data is missing\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
adev = ACPI_COMPANION(dev);
|
||||
|
||||
/* Count number of clients to instantiate */
|
||||
ret = i2c_acpi_client_count(adev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
multi = devm_kmalloc(dev, struct_size(multi, clients, ret), GFP_KERNEL);
|
||||
if (!multi)
|
||||
return -ENOMEM;
|
||||
|
||||
multi->num_clients = ret;
|
||||
|
||||
for (i = 0; i < multi->num_clients && inst_data[i].type; i++) {
|
||||
memset(&board_info, 0, sizeof(board_info));
|
||||
strlcpy(board_info.type, inst_data[i].type, I2C_NAME_SIZE);
|
||||
snprintf(name, sizeof(name), "%s-%s.%d", dev_name(dev),
|
||||
inst_data[i].type, i);
|
||||
board_info.dev_name = name;
|
||||
switch (inst_data[i].flags & IRQ_RESOURCE_TYPE) {
|
||||
case IRQ_RESOURCE_GPIO:
|
||||
ret = acpi_dev_gpio_irq_get(adev, inst_data[i].irq_idx);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Error requesting irq at index %d: %d\n",
|
||||
inst_data[i].irq_idx, ret);
|
||||
goto error;
|
||||
}
|
||||
board_info.irq = ret;
|
||||
break;
|
||||
case IRQ_RESOURCE_APIC:
|
||||
ret = platform_get_irq(pdev, inst_data[i].irq_idx);
|
||||
if (ret < 0) {
|
||||
dev_dbg(dev, "Error requesting irq at index %d: %d\n",
|
||||
inst_data[i].irq_idx, ret);
|
||||
goto error;
|
||||
}
|
||||
board_info.irq = ret;
|
||||
break;
|
||||
default:
|
||||
board_info.irq = 0;
|
||||
break;
|
||||
}
|
||||
multi->clients[i] = i2c_acpi_new_device(dev, i, &board_info);
|
||||
if (IS_ERR(multi->clients[i])) {
|
||||
ret = dev_err_probe(dev, PTR_ERR(multi->clients[i]),
|
||||
"Error creating i2c-client, idx %d\n", i);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (i < multi->num_clients) {
|
||||
dev_err(dev, "Error finding driver, idx %d\n", i);
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, multi);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
while (--i >= 0)
|
||||
i2c_unregister_device(multi->clients[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i2c_multi_inst_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct i2c_multi_inst_data *multi = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < multi->num_clients; i++)
|
||||
i2c_unregister_device(multi->clients[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_inst_data bsg1160_data[] = {
|
||||
{ "bmc150_accel", IRQ_RESOURCE_GPIO, 0 },
|
||||
{ "bmc150_magn" },
|
||||
{ "bmg160" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct i2c_inst_data bsg2150_data[] = {
|
||||
{ "bmc150_accel", IRQ_RESOURCE_GPIO, 0 },
|
||||
{ "bmc150_magn" },
|
||||
/* The resources describe a 3th client, but it is not really there. */
|
||||
{ "bsg2150_dummy_dev" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct i2c_inst_data int3515_data[] = {
|
||||
{ "tps6598x", IRQ_RESOURCE_APIC, 0 },
|
||||
{ "tps6598x", IRQ_RESOURCE_APIC, 1 },
|
||||
{ "tps6598x", IRQ_RESOURCE_APIC, 2 },
|
||||
{ "tps6598x", IRQ_RESOURCE_APIC, 3 },
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* Note new device-ids must also be added to i2c_multi_instantiate_ids in
|
||||
* drivers/acpi/scan.c: acpi_device_enumeration_by_parent().
|
||||
*/
|
||||
static const struct acpi_device_id i2c_multi_inst_acpi_ids[] = {
|
||||
{ "BSG1160", (unsigned long)bsg1160_data },
|
||||
{ "BSG2150", (unsigned long)bsg2150_data },
|
||||
{ "INT3515", (unsigned long)int3515_data },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, i2c_multi_inst_acpi_ids);
|
||||
|
||||
static struct platform_driver i2c_multi_inst_driver = {
|
||||
.driver = {
|
||||
.name = "I2C multi instantiate pseudo device driver",
|
||||
.acpi_match_table = i2c_multi_inst_acpi_ids,
|
||||
},
|
||||
.probe = i2c_multi_inst_probe,
|
||||
.remove = i2c_multi_inst_remove,
|
||||
};
|
||||
module_platform_driver(i2c_multi_inst_driver);
|
||||
|
||||
MODULE_DESCRIPTION("I2C multi instantiate pseudo device driver");
|
||||
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,348 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Serial multi-instantiate driver, pseudo driver to instantiate multiple
|
||||
* client devices from a single fwnode.
|
||||
*
|
||||
* Copyright 2018 Hans de Goede <hdegoede@redhat.com>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define IRQ_RESOURCE_TYPE GENMASK(1, 0)
|
||||
#define IRQ_RESOURCE_NONE 0
|
||||
#define IRQ_RESOURCE_GPIO 1
|
||||
#define IRQ_RESOURCE_APIC 2
|
||||
|
||||
enum smi_bus_type {
|
||||
SMI_I2C,
|
||||
SMI_SPI,
|
||||
SMI_AUTO_DETECT,
|
||||
};
|
||||
|
||||
struct smi_instance {
|
||||
const char *type;
|
||||
unsigned int flags;
|
||||
int irq_idx;
|
||||
};
|
||||
|
||||
struct smi_node {
|
||||
enum smi_bus_type bus_type;
|
||||
struct smi_instance instances[];
|
||||
};
|
||||
|
||||
struct smi {
|
||||
int i2c_num;
|
||||
int spi_num;
|
||||
struct i2c_client **i2c_devs;
|
||||
struct spi_device **spi_devs;
|
||||
};
|
||||
|
||||
static int smi_get_irq(struct platform_device *pdev, struct acpi_device *adev,
|
||||
const struct smi_instance *inst)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (inst->flags & IRQ_RESOURCE_TYPE) {
|
||||
case IRQ_RESOURCE_GPIO:
|
||||
ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx);
|
||||
break;
|
||||
case IRQ_RESOURCE_APIC:
|
||||
ret = platform_get_irq(pdev, inst->irq_idx);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
dev_err_probe(&pdev->dev, ret, "Error requesting irq at index %d: %d\n",
|
||||
inst->irq_idx, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void smi_devs_unregister(struct smi *smi)
|
||||
{
|
||||
while (smi->i2c_num > 0)
|
||||
i2c_unregister_device(smi->i2c_devs[--smi->i2c_num]);
|
||||
|
||||
while (smi->spi_num > 0)
|
||||
spi_unregister_device(smi->spi_devs[--smi->spi_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* smi_spi_probe - Instantiate multiple SPI devices from inst array
|
||||
* @pdev: Platform device
|
||||
* @adev: ACPI device
|
||||
* @smi: Internal struct for Serial multi instantiate driver
|
||||
* @inst_array: Array of instances to probe
|
||||
*
|
||||
* Returns the number of SPI devices instantiate, Zero if none is found or a negative error code.
|
||||
*/
|
||||
static int smi_spi_probe(struct platform_device *pdev, struct acpi_device *adev, struct smi *smi,
|
||||
const struct smi_instance *inst_array)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct spi_controller *ctlr;
|
||||
struct spi_device *spi_dev;
|
||||
char name[50];
|
||||
int i, ret, count;
|
||||
|
||||
ret = acpi_spi_count_resources(adev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (!ret)
|
||||
return -ENODEV;
|
||||
|
||||
count = ret;
|
||||
|
||||
smi->spi_devs = devm_kcalloc(dev, count, sizeof(*smi->spi_devs), GFP_KERNEL);
|
||||
if (!smi->spi_devs)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < count && inst_array[i].type; i++) {
|
||||
|
||||
spi_dev = acpi_spi_device_alloc(NULL, adev, i);
|
||||
if (IS_ERR(spi_dev)) {
|
||||
ret = PTR_ERR(spi_dev);
|
||||
dev_err_probe(dev, ret, "failed to allocate SPI device %s from ACPI: %d\n",
|
||||
dev_name(&adev->dev), ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ctlr = spi_dev->controller;
|
||||
|
||||
strscpy(spi_dev->modalias, inst_array[i].type, sizeof(spi_dev->modalias));
|
||||
|
||||
ret = smi_get_irq(pdev, adev, &inst_array[i]);
|
||||
if (ret < 0) {
|
||||
spi_dev_put(spi_dev);
|
||||
goto error;
|
||||
}
|
||||
spi_dev->irq = ret;
|
||||
|
||||
snprintf(name, sizeof(name), "%s-%s-%s.%d", dev_name(&ctlr->dev), dev_name(dev),
|
||||
inst_array[i].type, i);
|
||||
spi_dev->dev.init_name = name;
|
||||
|
||||
ret = spi_add_device(spi_dev);
|
||||
if (ret) {
|
||||
dev_err_probe(&ctlr->dev, ret,
|
||||
"failed to add SPI device %s from ACPI: %d\n",
|
||||
dev_name(&adev->dev), ret);
|
||||
spi_dev_put(spi_dev);
|
||||
goto error;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "SPI device %s using chip select %u", name, spi_dev->chip_select);
|
||||
|
||||
smi->spi_devs[i] = spi_dev;
|
||||
smi->spi_num++;
|
||||
}
|
||||
|
||||
if (smi->spi_num < count) {
|
||||
dev_dbg(dev, "Error finding driver, idx %d\n", i);
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
dev_info(dev, "Instantiated %d SPI devices.\n", smi->spi_num);
|
||||
|
||||
return 0;
|
||||
error:
|
||||
smi_devs_unregister(smi);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* smi_i2c_probe - Instantiate multiple I2C devices from inst array
|
||||
* @pdev: Platform device
|
||||
* @adev: ACPI device
|
||||
* @smi: Internal struct for Serial multi instantiate driver
|
||||
* @inst_array: Array of instances to probe
|
||||
*
|
||||
* Returns the number of I2C devices instantiate, Zero if none is found or a negative error code.
|
||||
*/
|
||||
static int smi_i2c_probe(struct platform_device *pdev, struct acpi_device *adev, struct smi *smi,
|
||||
const struct smi_instance *inst_array)
|
||||
{
|
||||
struct i2c_board_info board_info = {};
|
||||
struct device *dev = &pdev->dev;
|
||||
char name[32];
|
||||
int i, ret, count;
|
||||
|
||||
ret = i2c_acpi_client_count(adev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else if (!ret)
|
||||
return -ENODEV;
|
||||
|
||||
count = ret;
|
||||
|
||||
smi->i2c_devs = devm_kcalloc(dev, count, sizeof(*smi->i2c_devs), GFP_KERNEL);
|
||||
if (!smi->i2c_devs)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < count && inst_array[i].type; i++) {
|
||||
memset(&board_info, 0, sizeof(board_info));
|
||||
strscpy(board_info.type, inst_array[i].type, I2C_NAME_SIZE);
|
||||
snprintf(name, sizeof(name), "%s-%s.%d", dev_name(dev), inst_array[i].type, i);
|
||||
board_info.dev_name = name;
|
||||
|
||||
ret = smi_get_irq(pdev, adev, &inst_array[i]);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
board_info.irq = ret;
|
||||
|
||||
smi->i2c_devs[i] = i2c_acpi_new_device(dev, i, &board_info);
|
||||
if (IS_ERR(smi->i2c_devs[i])) {
|
||||
ret = dev_err_probe(dev, PTR_ERR(smi->i2c_devs[i]),
|
||||
"Error creating i2c-client, idx %d\n", i);
|
||||
goto error;
|
||||
}
|
||||
smi->i2c_num++;
|
||||
}
|
||||
if (smi->i2c_num < count) {
|
||||
dev_dbg(dev, "Error finding driver, idx %d\n", i);
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
|
||||
dev_info(dev, "Instantiated %d I2C devices.\n", smi->i2c_num);
|
||||
|
||||
return 0;
|
||||
error:
|
||||
smi_devs_unregister(smi);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int smi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct smi_node *node;
|
||||
struct acpi_device *adev;
|
||||
struct smi *smi;
|
||||
|
||||
adev = ACPI_COMPANION(dev);
|
||||
if (!adev)
|
||||
return -ENODEV;
|
||||
|
||||
node = device_get_match_data(dev);
|
||||
if (!node) {
|
||||
dev_dbg(dev, "Error ACPI match data is missing\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
smi = devm_kzalloc(dev, sizeof(*smi), GFP_KERNEL);
|
||||
if (!smi)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, smi);
|
||||
|
||||
switch (node->bus_type) {
|
||||
case SMI_I2C:
|
||||
return smi_i2c_probe(pdev, adev, smi, node->instances);
|
||||
case SMI_SPI:
|
||||
return smi_spi_probe(pdev, adev, smi, node->instances);
|
||||
case SMI_AUTO_DETECT:
|
||||
if (i2c_acpi_client_count(adev) > 0)
|
||||
return smi_i2c_probe(pdev, adev, smi, node->instances);
|
||||
else
|
||||
return smi_spi_probe(pdev, adev, smi, node->instances);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0; /* never reached */
|
||||
}
|
||||
|
||||
static int smi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct smi *smi = platform_get_drvdata(pdev);
|
||||
|
||||
smi_devs_unregister(smi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct smi_node bsg1160_data = {
|
||||
.instances = {
|
||||
{ "bmc150_accel", IRQ_RESOURCE_GPIO, 0 },
|
||||
{ "bmc150_magn" },
|
||||
{ "bmg160" },
|
||||
{}
|
||||
},
|
||||
.bus_type = SMI_I2C,
|
||||
};
|
||||
|
||||
static const struct smi_node bsg2150_data = {
|
||||
.instances = {
|
||||
{ "bmc150_accel", IRQ_RESOURCE_GPIO, 0 },
|
||||
{ "bmc150_magn" },
|
||||
/* The resources describe a 3th client, but it is not really there. */
|
||||
{ "bsg2150_dummy_dev" },
|
||||
{}
|
||||
},
|
||||
.bus_type = SMI_I2C,
|
||||
};
|
||||
|
||||
static const struct smi_node int3515_data = {
|
||||
.instances = {
|
||||
{ "tps6598x", IRQ_RESOURCE_APIC, 0 },
|
||||
{ "tps6598x", IRQ_RESOURCE_APIC, 1 },
|
||||
{ "tps6598x", IRQ_RESOURCE_APIC, 2 },
|
||||
{ "tps6598x", IRQ_RESOURCE_APIC, 3 },
|
||||
{}
|
||||
},
|
||||
.bus_type = SMI_I2C,
|
||||
};
|
||||
|
||||
static const struct smi_node cs35l41_hda = {
|
||||
.instances = {
|
||||
{ "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 },
|
||||
{ "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 },
|
||||
{ "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 },
|
||||
{ "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 },
|
||||
{}
|
||||
},
|
||||
.bus_type = SMI_AUTO_DETECT,
|
||||
};
|
||||
|
||||
/*
|
||||
* Note new device-ids must also be added to ignore_serial_bus_ids in
|
||||
* drivers/acpi/scan.c: acpi_device_enumeration_by_parent().
|
||||
*/
|
||||
static const struct acpi_device_id smi_acpi_ids[] = {
|
||||
{ "BSG1160", (unsigned long)&bsg1160_data },
|
||||
{ "BSG2150", (unsigned long)&bsg2150_data },
|
||||
{ "INT3515", (unsigned long)&int3515_data },
|
||||
{ "CSC3551", (unsigned long)&cs35l41_hda },
|
||||
/* Non-conforming _HID for Cirrus Logic already released */
|
||||
{ "CLSA0100", (unsigned long)&cs35l41_hda },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, smi_acpi_ids);
|
||||
|
||||
static struct platform_driver smi_driver = {
|
||||
.driver = {
|
||||
.name = "Serial bus multi instantiate pseudo device driver",
|
||||
.acpi_match_table = smi_acpi_ids,
|
||||
},
|
||||
.probe = smi_probe,
|
||||
.remove = smi_remove,
|
||||
};
|
||||
module_platform_driver(smi_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Serial multi instantiate pseudo device driver");
|
||||
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -59,7 +59,7 @@ static const struct dmi_system_id adr_remap_quirk_table[] = {
|
|||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Conv"),
|
||||
},
|
||||
.driver_data = (void *)intel_tgl_bios,
|
||||
},
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DT_BINDINGS_MICROCHIP_PDMC_H__
|
||||
#define __DT_BINDINGS_MICROCHIP_PDMC_H__
|
||||
|
||||
/* PDM microphone's pin placement */
|
||||
#define MCHP_PDMC_DS0 0
|
||||
#define MCHP_PDMC_DS1 1
|
||||
|
||||
/* PDM microphone clock edge sampling */
|
||||
#define MCHP_PDMC_CLK_POSITIVE 0
|
||||
#define MCHP_PDMC_CLK_NEGATIVE 1
|
||||
|
||||
#endif /* __DT_BINDINGS_MICROCHIP_PDMC_H__ */
|
|
@ -1,9 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DT_TLV320AIC31XX_MICBIAS_H
|
||||
#define __DT_TLV320AIC31XX_MICBIAS_H
|
||||
|
||||
#define MICBIAS_2_0V 1
|
||||
#define MICBIAS_2_5V 2
|
||||
#define MICBIAS_AVDDV 3
|
||||
|
||||
#endif /* __DT_TLV320AIC31XX_MICBIAS_H */
|
|
@ -0,0 +1,14 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DT_TLV320AIC31XX_H
|
||||
#define __DT_TLV320AIC31XX_H
|
||||
|
||||
#define MICBIAS_2_0V 1
|
||||
#define MICBIAS_2_5V 2
|
||||
#define MICBIAS_AVDDV 3
|
||||
|
||||
#define PLL_CLKIN_MCLK 0x00
|
||||
#define PLL_CLKIN_BCLK 0x01
|
||||
#define PLL_CLKIN_GPIO1 0x02
|
||||
#define PLL_CLKIN_DIN 0x03
|
||||
|
||||
#endif /* __DT_TLV320AIC31XX_H */
|
|
@ -306,12 +306,19 @@ struct hda_codec {
|
|||
/*
|
||||
* constructors
|
||||
*/
|
||||
__printf(3, 4) struct hda_codec *
|
||||
snd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr,
|
||||
const char *fmt, ...);
|
||||
int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
|
||||
unsigned int codec_addr, struct hda_codec **codecp);
|
||||
int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
|
||||
unsigned int codec_addr, struct hda_codec *codec);
|
||||
unsigned int codec_addr, struct hda_codec *codec,
|
||||
bool snddev_managed);
|
||||
int snd_hda_codec_configure(struct hda_codec *codec);
|
||||
int snd_hda_codec_update_widgets(struct hda_codec *codec);
|
||||
void snd_hda_codec_register(struct hda_codec *codec);
|
||||
void snd_hda_codec_unregister(struct hda_codec *codec);
|
||||
void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec);
|
||||
|
||||
/*
|
||||
* low level functions
|
||||
|
@ -490,9 +497,11 @@ int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid)
|
|||
#define snd_hda_power_down(codec) snd_hdac_power_down(&(codec)->core)
|
||||
#define snd_hda_power_down_pm(codec) snd_hdac_power_down_pm(&(codec)->core)
|
||||
#ifdef CONFIG_PM
|
||||
void snd_hda_codec_set_power_save(struct hda_codec *codec, int delay);
|
||||
void snd_hda_set_power_save(struct hda_bus *bus, int delay);
|
||||
void snd_hda_update_power_acct(struct hda_codec *codec);
|
||||
#else
|
||||
static inline void snd_hda_codec_set_power_save(struct hda_codec *codec, int delay) {}
|
||||
static inline void snd_hda_set_power_save(struct hda_bus *bus, int delay) {}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -461,7 +461,7 @@ enum {
|
|||
#define AC_DE_ELDV (1<<1)
|
||||
#define AC_DE_IA (1<<2)
|
||||
|
||||
/* device device types (0x0-0xf) */
|
||||
/* device types (0x0-0xf) */
|
||||
enum {
|
||||
AC_JACK_LINE_OUT,
|
||||
AC_JACK_SPEAKER,
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/timecounter.h>
|
||||
#include <sound/core.h>
|
||||
|
@ -448,6 +449,8 @@ static inline u16 snd_hdac_reg_readw(struct hdac_bus *bus, void __iomem *addr)
|
|||
|
||||
#define snd_hdac_reg_writel(bus, addr, val) writel(val, addr)
|
||||
#define snd_hdac_reg_readl(bus, addr) readl(addr)
|
||||
#define snd_hdac_reg_writeq(bus, addr, val) writeq(val, addr)
|
||||
#define snd_hdac_reg_readq(bus, addr) readq(addr)
|
||||
|
||||
/*
|
||||
* macros for easy use
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#ifndef __SOUND_HDAUDIO_EXT_H
|
||||
#define __SOUND_HDAUDIO_EXT_H
|
||||
|
||||
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <sound/hdaudio.h>
|
||||
|
||||
int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
|
||||
|
@ -28,6 +30,7 @@ void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *chip,
|
|||
bool enable, int index);
|
||||
|
||||
int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus);
|
||||
struct hdac_ext_link *snd_hdac_ext_bus_link_at(struct hdac_bus *bus, int addr);
|
||||
struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus,
|
||||
const char *codec_name);
|
||||
|
||||
|
@ -143,6 +146,54 @@ void snd_hdac_ext_bus_link_power(struct hdac_device *codec, bool enable);
|
|||
writew(((readw(addr + reg) & ~(mask)) | (val)), \
|
||||
addr + reg)
|
||||
|
||||
#define snd_hdac_adsp_writeb(chip, reg, value) \
|
||||
snd_hdac_reg_writeb(chip, (chip)->dsp_ba + (reg), value)
|
||||
#define snd_hdac_adsp_readb(chip, reg) \
|
||||
snd_hdac_reg_readb(chip, (chip)->dsp_ba + (reg))
|
||||
#define snd_hdac_adsp_writew(chip, reg, value) \
|
||||
snd_hdac_reg_writew(chip, (chip)->dsp_ba + (reg), value)
|
||||
#define snd_hdac_adsp_readw(chip, reg) \
|
||||
snd_hdac_reg_readw(chip, (chip)->dsp_ba + (reg))
|
||||
#define snd_hdac_adsp_writel(chip, reg, value) \
|
||||
snd_hdac_reg_writel(chip, (chip)->dsp_ba + (reg), value)
|
||||
#define snd_hdac_adsp_readl(chip, reg) \
|
||||
snd_hdac_reg_readl(chip, (chip)->dsp_ba + (reg))
|
||||
#define snd_hdac_adsp_writeq(chip, reg, value) \
|
||||
snd_hdac_reg_writeq(chip, (chip)->dsp_ba + (reg), value)
|
||||
#define snd_hdac_adsp_readq(chip, reg) \
|
||||
snd_hdac_reg_readq(chip, (chip)->dsp_ba + (reg))
|
||||
|
||||
#define snd_hdac_adsp_updateb(chip, reg, mask, val) \
|
||||
snd_hdac_adsp_writeb(chip, reg, \
|
||||
(snd_hdac_adsp_readb(chip, reg) & ~(mask)) | (val))
|
||||
#define snd_hdac_adsp_updatew(chip, reg, mask, val) \
|
||||
snd_hdac_adsp_writew(chip, reg, \
|
||||
(snd_hdac_adsp_readw(chip, reg) & ~(mask)) | (val))
|
||||
#define snd_hdac_adsp_updatel(chip, reg, mask, val) \
|
||||
snd_hdac_adsp_writel(chip, reg, \
|
||||
(snd_hdac_adsp_readl(chip, reg) & ~(mask)) | (val))
|
||||
#define snd_hdac_adsp_updateq(chip, reg, mask, val) \
|
||||
snd_hdac_adsp_writeq(chip, reg, \
|
||||
(snd_hdac_adsp_readq(chip, reg) & ~(mask)) | (val))
|
||||
|
||||
#define snd_hdac_adsp_readb_poll(chip, reg, val, cond, delay_us, timeout_us) \
|
||||
readb_poll_timeout((chip)->dsp_ba + (reg), val, cond, \
|
||||
delay_us, timeout_us)
|
||||
#define snd_hdac_adsp_readw_poll(chip, reg, val, cond, delay_us, timeout_us) \
|
||||
readw_poll_timeout((chip)->dsp_ba + (reg), val, cond, \
|
||||
delay_us, timeout_us)
|
||||
#define snd_hdac_adsp_readl_poll(chip, reg, val, cond, delay_us, timeout_us) \
|
||||
readl_poll_timeout((chip)->dsp_ba + (reg), val, cond, \
|
||||
delay_us, timeout_us)
|
||||
#define snd_hdac_adsp_readq_poll(chip, reg, val, cond, delay_us, timeout_us) \
|
||||
readq_poll_timeout((chip)->dsp_ba + (reg), val, cond, \
|
||||
delay_us, timeout_us)
|
||||
#define snd_hdac_stream_readb_poll(strm, reg, val, cond, delay_us, timeout_us) \
|
||||
readb_poll_timeout((strm)->sd_addr + AZX_REG_ ## reg, val, cond, \
|
||||
delay_us, timeout_us)
|
||||
#define snd_hdac_stream_readl_poll(strm, reg, val, cond, delay_us, timeout_us) \
|
||||
readl_poll_timeout((strm)->sd_addr + AZX_REG_ ## reg, val, cond, \
|
||||
delay_us, timeout_us)
|
||||
|
||||
struct hdac_ext_device;
|
||||
|
||||
|
|
|
@ -18,6 +18,13 @@ enum nhlt_link_type {
|
|||
NHLT_LINK_INVALID
|
||||
};
|
||||
|
||||
enum nhlt_device_type {
|
||||
NHLT_DEVICE_BT = 0,
|
||||
NHLT_DEVICE_DMIC = 1,
|
||||
NHLT_DEVICE_I2S = 4,
|
||||
NHLT_DEVICE_INVALID
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT)
|
||||
|
||||
struct wav_fmt {
|
||||
|
@ -41,13 +48,6 @@ struct wav_fmt_ext {
|
|||
u8 sub_fmt[16];
|
||||
} __packed;
|
||||
|
||||
enum nhlt_device_type {
|
||||
NHLT_DEVICE_BT = 0,
|
||||
NHLT_DEVICE_DMIC = 1,
|
||||
NHLT_DEVICE_I2S = 4,
|
||||
NHLT_DEVICE_INVALID
|
||||
};
|
||||
|
||||
struct nhlt_specific_cfg {
|
||||
u32 size;
|
||||
u8 caps[];
|
||||
|
@ -133,6 +133,9 @@ void intel_nhlt_free(struct nhlt_acpi_table *addr);
|
|||
int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt);
|
||||
|
||||
bool intel_nhlt_has_endpoint_type(struct nhlt_acpi_table *nhlt, u8 link_type);
|
||||
|
||||
int intel_nhlt_ssp_endpoint_mask(struct nhlt_acpi_table *nhlt, u8 device_type);
|
||||
|
||||
struct nhlt_specific_cfg *
|
||||
intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
|
||||
u32 bus_id, u8 link_type, u8 vbps, u8 bps,
|
||||
|
@ -163,6 +166,11 @@ static inline bool intel_nhlt_has_endpoint_type(struct nhlt_acpi_table *nhlt,
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline int intel_nhlt_ssp_endpoint_mask(struct nhlt_acpi_table *nhlt, u8 device_type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct nhlt_specific_cfg *
|
||||
intel_nhlt_get_endpoint_blob(struct device *dev, struct nhlt_acpi_table *nhlt,
|
||||
u32 bus_id, u8 link_type, u8 vbps, u8 bps,
|
||||
|
|
|
@ -401,6 +401,7 @@ struct snd_pcm_runtime {
|
|||
wait_queue_head_t tsleep; /* transfer sleep */
|
||||
struct fasync_struct *fasync;
|
||||
bool stop_operating; /* sync_stop will be called */
|
||||
struct mutex buffer_mutex; /* protect for buffer changes */
|
||||
|
||||
/* -- private section -- */
|
||||
void *private_data;
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
#define asoc_simple_init_mic(card, sjack, prefix) \
|
||||
asoc_simple_init_jack(card, sjack, 0, prefix, NULL)
|
||||
|
||||
struct asoc_simple_tdm_width_map {
|
||||
u8 sample_bits;
|
||||
u8 slot_count;
|
||||
u16 slot_width;
|
||||
};
|
||||
|
||||
struct asoc_simple_dai {
|
||||
const char *name;
|
||||
unsigned int sysclk;
|
||||
|
@ -25,6 +31,9 @@ struct asoc_simple_dai {
|
|||
unsigned int tx_slot_mask;
|
||||
unsigned int rx_slot_mask;
|
||||
struct clk *clk;
|
||||
bool clk_fixed;
|
||||
struct asoc_simple_tdm_width_map *tdm_width_map;
|
||||
int n_tdm_widths;
|
||||
};
|
||||
|
||||
struct asoc_simple_data {
|
||||
|
@ -131,6 +140,9 @@ int asoc_simple_parse_daifmt(struct device *dev,
|
|||
struct device_node *codec,
|
||||
char *prefix,
|
||||
unsigned int *retfmt);
|
||||
int asoc_simple_parse_tdm_width_map(struct device *dev, struct device_node *np,
|
||||
struct asoc_simple_dai *dai);
|
||||
|
||||
__printf(3, 4)
|
||||
int asoc_simple_set_dailink_name(struct device *dev,
|
||||
struct snd_soc_dai_link *dai_link,
|
||||
|
|
|
@ -60,9 +60,11 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
|
|||
* @acpi_ipc_irq_index: used for BYT-CR detection
|
||||
* @platform: string used for HDAudio codec support
|
||||
* @codec_mask: used for HDAudio support
|
||||
* @dmic_num: number of SoC- or chipset-attached PDM digital microphones
|
||||
* @common_hdmi_codec_drv: use commom HDAudio HDMI codec driver
|
||||
* @link_mask: links enabled on the board
|
||||
* @links: array of link _ADR descriptors, null terminated
|
||||
* @link_mask: SoundWire links enabled on the board
|
||||
* @links: array of SoundWire link _ADR descriptors, null terminated
|
||||
* @i2s_link_mask: I2S/TDM links enabled on the board
|
||||
* @num_dai_drivers: number of elements in @dai_drivers
|
||||
* @dai_drivers: pointer to dai_drivers, used e.g. in nocodec mode
|
||||
*/
|
||||
|
@ -74,6 +76,7 @@ struct snd_soc_acpi_mach_params {
|
|||
bool common_hdmi_codec_drv;
|
||||
u32 link_mask;
|
||||
const struct snd_soc_acpi_link_adr *links;
|
||||
u32 i2s_link_mask;
|
||||
u32 num_dai_drivers;
|
||||
struct snd_soc_dai_driver *dai_drivers;
|
||||
};
|
||||
|
@ -122,6 +125,24 @@ struct snd_soc_acpi_link_adr {
|
|||
const struct snd_soc_acpi_adr_device *adr_d;
|
||||
};
|
||||
|
||||
/*
|
||||
* when set the topology uses the -ssp<N> suffix, where N is determined based on
|
||||
* BIOS or DMI information
|
||||
*/
|
||||
#define SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER BIT(0)
|
||||
|
||||
/*
|
||||
* when more than one SSP is reported in the link mask, use the most significant.
|
||||
* This choice was found to be valid on platforms with ES8336 codecs.
|
||||
*/
|
||||
#define SND_SOC_ACPI_TPLG_INTEL_SSP_MSB BIT(1)
|
||||
|
||||
/*
|
||||
* when set the topology uses the -dmic<N>ch suffix, where N is determined based on
|
||||
* BIOS or DMI information
|
||||
*/
|
||||
#define SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER BIT(2)
|
||||
|
||||
/**
|
||||
* snd_soc_acpi_mach: ACPI-based machine descriptor. Most of the fields are
|
||||
* related to the hardware, except for the firmware and topology file names.
|
||||
|
@ -142,8 +163,8 @@ struct snd_soc_acpi_link_adr {
|
|||
* audio codecs whose presence if checked with ACPI
|
||||
* @pdata: intended for platform data or machine specific-ops. This structure
|
||||
* is not constant since this field may be updated at run-time
|
||||
* @sof_fw_filename: Sound Open Firmware file name, if enabled
|
||||
* @sof_tplg_filename: Sound Open Firmware topology file name, if enabled
|
||||
* @tplg_quirk_mask: quirks to select different topology files dynamically
|
||||
*/
|
||||
/* Descriptor for SST ASoC machine driver */
|
||||
struct snd_soc_acpi_mach {
|
||||
|
@ -158,8 +179,8 @@ struct snd_soc_acpi_mach {
|
|||
const void *quirk_data;
|
||||
void *pdata;
|
||||
struct snd_soc_acpi_mach_params mach_params;
|
||||
const char *sof_fw_filename;
|
||||
const char *sof_tplg_filename;
|
||||
const u32 tplg_quirk_mask;
|
||||
};
|
||||
|
||||
#define SND_SOC_ACPI_MAX_CODECS 3
|
||||
|
|
|
@ -429,6 +429,7 @@ struct snd_soc_dapm_widget *snd_soc_dapm_new_control_unlocked(
|
|||
const struct snd_soc_dapm_widget *widget);
|
||||
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
|
||||
struct snd_soc_dai *dai);
|
||||
void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w);
|
||||
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
|
||||
void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);
|
||||
|
||||
|
|
|
@ -39,6 +39,14 @@ enum sof_fw_state {
|
|||
SOF_FW_CRASHED,
|
||||
};
|
||||
|
||||
/* DSP power states */
|
||||
enum sof_dsp_power_states {
|
||||
SOF_DSP_PM_D0,
|
||||
SOF_DSP_PM_D1,
|
||||
SOF_DSP_PM_D2,
|
||||
SOF_DSP_PM_D3,
|
||||
};
|
||||
|
||||
/*
|
||||
* SOF Platform data.
|
||||
*/
|
||||
|
|
|
@ -116,4 +116,9 @@ struct sof_ipc_dai_config {
|
|||
};
|
||||
} __packed;
|
||||
|
||||
struct sof_dai_private_data {
|
||||
struct sof_ipc_comp_dai *comp_dai;
|
||||
struct sof_ipc_dai_config *dai_config;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
/* Global Message - Generic */
|
||||
#define SOF_GLB_TYPE_SHIFT 28
|
||||
#define SOF_GLB_TYPE_MASK (0xfL << SOF_GLB_TYPE_SHIFT)
|
||||
#define SOF_GLB_TYPE_MASK (0xfUL << SOF_GLB_TYPE_SHIFT)
|
||||
#define SOF_GLB_TYPE(x) ((x) << SOF_GLB_TYPE_SHIFT)
|
||||
|
||||
/* Command Message - Generic */
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#define SOF_IPC_INFO_LOCKS BIT(1)
|
||||
#define SOF_IPC_INFO_LOCKSV BIT(2)
|
||||
#define SOF_IPC_INFO_GDB BIT(3)
|
||||
#define SOF_IPC_INFO_D3_PERSISTENT BIT(4)
|
||||
|
||||
/* extended data types that can be appended onto end of sof_ipc_fw_ready */
|
||||
enum sof_ipc_ext_data {
|
||||
|
|
|
@ -87,9 +87,6 @@ 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;
|
||||
|
@ -237,7 +234,7 @@ struct sof_ipc_comp_process {
|
|||
/* reserved for future use */
|
||||
uint32_t reserved[7];
|
||||
|
||||
uint8_t data[0];
|
||||
uint8_t data[];
|
||||
} __packed;
|
||||
|
||||
/* frees components, buffers and pipelines
|
||||
|
@ -303,9 +300,4 @@ 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
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
|
||||
/* SOF ABI version major, minor and patch numbers */
|
||||
#define SOF_ABI_MAJOR 3
|
||||
#define SOF_ABI_MINOR 18
|
||||
#define SOF_ABI_PATCH 0
|
||||
#define SOF_ABI_MINOR 19
|
||||
#define SOF_ABI_PATCH 1
|
||||
|
||||
/* SOF ABI version number. Format within 32bit word is MMmmmppp */
|
||||
#define SOF_ABI_MAJOR_SHIFT 24
|
||||
|
|
|
@ -84,7 +84,7 @@ config SND_PCM_TIMER
|
|||
help
|
||||
If you disable this option, pcm timer will be unavailable, so
|
||||
those stubs that use pcm timer (e.g. dmix, dsnoop & co) may work
|
||||
incorrectlly.
|
||||
incorrectly.
|
||||
|
||||
For some embedded devices, we may disable it to reduce memory
|
||||
footprint, about 20KB on x86_64 platform.
|
||||
|
|
|
@ -774,6 +774,11 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
|
|||
|
||||
if (oss_period_size < 16)
|
||||
return -EINVAL;
|
||||
|
||||
/* don't allocate too large period; 1MB period must be enough */
|
||||
if (oss_period_size > 1024 * 1024)
|
||||
return -ENOMEM;
|
||||
|
||||
runtime->oss.period_bytes = oss_period_size;
|
||||
runtime->oss.period_frames = 1;
|
||||
runtime->oss.periods = oss_periods;
|
||||
|
@ -837,6 +842,17 @@ static void unlock_params(struct snd_pcm_runtime *runtime)
|
|||
mutex_unlock(&runtime->oss.params_lock);
|
||||
}
|
||||
|
||||
static void snd_pcm_oss_release_buffers(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
|
||||
kvfree(runtime->oss.buffer);
|
||||
runtime->oss.buffer = NULL;
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
snd_pcm_oss_plugin_clear(substream);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* call with params_lock held */
|
||||
static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
|
||||
{
|
||||
|
@ -967,12 +983,10 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
|
|||
snd_pcm_oss_plugin_clear(substream);
|
||||
if (!direct) {
|
||||
/* add necessary plugins */
|
||||
snd_pcm_oss_plugin_clear(substream);
|
||||
err = snd_pcm_plug_format_plugins(substream, params, sparams);
|
||||
if (err < 0) {
|
||||
pcm_dbg(substream->pcm,
|
||||
"snd_pcm_plug_format_plugins failed: %i\n", err);
|
||||
snd_pcm_oss_plugin_clear(substream);
|
||||
goto failure;
|
||||
}
|
||||
if (runtime->oss.plugin_first) {
|
||||
|
@ -981,7 +995,6 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
|
|||
if (err < 0) {
|
||||
pcm_dbg(substream->pcm,
|
||||
"snd_pcm_plugin_build_io failed: %i\n", err);
|
||||
snd_pcm_oss_plugin_clear(substream);
|
||||
goto failure;
|
||||
}
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
|
@ -989,10 +1002,8 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
|
|||
} else {
|
||||
err = snd_pcm_plugin_insert(plugin);
|
||||
}
|
||||
if (err < 0) {
|
||||
snd_pcm_oss_plugin_clear(substream);
|
||||
if (err < 0)
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1043,10 +1054,9 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
|
|||
goto failure;
|
||||
}
|
||||
#endif
|
||||
oss_period_size *= oss_frame_size;
|
||||
|
||||
oss_buffer_size = oss_period_size * runtime->oss.periods;
|
||||
if (oss_buffer_size < 0) {
|
||||
oss_period_size = array_size(oss_period_size, oss_frame_size);
|
||||
oss_buffer_size = array_size(oss_period_size, runtime->oss.periods);
|
||||
if (oss_buffer_size <= 0) {
|
||||
err = -EINVAL;
|
||||
goto failure;
|
||||
}
|
||||
|
@ -1082,6 +1092,8 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
|
|||
|
||||
err = 0;
|
||||
failure:
|
||||
if (err)
|
||||
snd_pcm_oss_release_buffers(substream);
|
||||
kfree(sw_params);
|
||||
kfree(params);
|
||||
kfree(sparams);
|
||||
|
@ -2351,13 +2363,7 @@ static void snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream,
|
|||
|
||||
static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime;
|
||||
runtime = substream->runtime;
|
||||
kvfree(runtime->oss.buffer);
|
||||
runtime->oss.buffer = NULL;
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
snd_pcm_oss_plugin_clear(substream);
|
||||
#endif
|
||||
snd_pcm_oss_release_buffers(substream);
|
||||
substream->oss.oss = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,10 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t
|
|||
width = snd_pcm_format_physical_width(format->format);
|
||||
if (width < 0)
|
||||
return width;
|
||||
size = frames * format->channels * width;
|
||||
size = array3_size(frames, format->channels, width);
|
||||
/* check for too large period size once again */
|
||||
if (size > 1024 * 1024)
|
||||
return -ENOMEM;
|
||||
if (snd_BUG_ON(size % 8))
|
||||
return -ENXIO;
|
||||
size /= 8;
|
||||
|
|
|
@ -969,6 +969,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
|
|||
init_waitqueue_head(&runtime->tsleep);
|
||||
|
||||
runtime->status->state = SNDRV_PCM_STATE_OPEN;
|
||||
mutex_init(&runtime->buffer_mutex);
|
||||
|
||||
substream->runtime = runtime;
|
||||
substream->private_data = pcm->private_data;
|
||||
|
@ -1002,6 +1003,7 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
|
|||
} else {
|
||||
substream->runtime = NULL;
|
||||
}
|
||||
mutex_destroy(&runtime->buffer_mutex);
|
||||
kfree(runtime);
|
||||
put_pid(substream->pid);
|
||||
substream->pid = NULL;
|
||||
|
|
|
@ -1906,9 +1906,11 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
|
|||
if (avail >= runtime->twake)
|
||||
break;
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
mutex_unlock(&runtime->buffer_mutex);
|
||||
|
||||
tout = schedule_timeout(wait_time);
|
||||
|
||||
mutex_lock(&runtime->buffer_mutex);
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
switch (runtime->status->state) {
|
||||
|
@ -2219,6 +2221,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
|
|||
|
||||
nonblock = !!(substream->f_flags & O_NONBLOCK);
|
||||
|
||||
mutex_lock(&runtime->buffer_mutex);
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
err = pcm_accessible_state(runtime);
|
||||
if (err < 0)
|
||||
|
@ -2310,6 +2313,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
|
|||
if (xfer > 0 && err >= 0)
|
||||
snd_pcm_update_state(substream, runtime);
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
mutex_unlock(&runtime->buffer_mutex);
|
||||
return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
|
||||
}
|
||||
EXPORT_SYMBOL(__snd_pcm_lib_xfer);
|
||||
|
|
|
@ -163,19 +163,20 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
|
|||
size_t size;
|
||||
struct snd_dma_buffer new_dmab;
|
||||
|
||||
mutex_lock(&substream->pcm->open_mutex);
|
||||
if (substream->runtime) {
|
||||
buffer->error = -EBUSY;
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
if (!snd_info_get_line(buffer, line, sizeof(line))) {
|
||||
snd_info_get_str(str, line, sizeof(str));
|
||||
size = simple_strtoul(str, NULL, 10) * 1024;
|
||||
if ((size != 0 && size < 8192) || size > substream->dma_max) {
|
||||
buffer->error = -EINVAL;
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
if (substream->dma_buffer.bytes == size)
|
||||
return;
|
||||
goto unlock;
|
||||
memset(&new_dmab, 0, sizeof(new_dmab));
|
||||
new_dmab.dev = substream->dma_buffer.dev;
|
||||
if (size > 0) {
|
||||
|
@ -189,7 +190,7 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
|
|||
substream->pcm->card->number, substream->pcm->device,
|
||||
substream->stream ? 'c' : 'p', substream->number,
|
||||
substream->pcm->name, size);
|
||||
return;
|
||||
goto unlock;
|
||||
}
|
||||
substream->buffer_bytes_max = size;
|
||||
} else {
|
||||
|
@ -201,6 +202,8 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
|
|||
} else {
|
||||
buffer->error = -EINVAL;
|
||||
}
|
||||
unlock:
|
||||
mutex_unlock(&substream->pcm->open_mutex);
|
||||
}
|
||||
|
||||
static inline void preallocate_info_init(struct snd_pcm_substream *substream)
|
||||
|
|
|
@ -685,33 +685,40 @@ static int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
|
||||
#define is_oss_stream(substream) ((substream)->oss.oss)
|
||||
#else
|
||||
#define is_oss_stream(substream) false
|
||||
#endif
|
||||
|
||||
static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime;
|
||||
int err, usecs;
|
||||
int err = 0, usecs;
|
||||
unsigned int bits;
|
||||
snd_pcm_uframes_t frames;
|
||||
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
mutex_lock(&runtime->buffer_mutex);
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
switch (runtime->status->state) {
|
||||
case SNDRV_PCM_STATE_OPEN:
|
||||
case SNDRV_PCM_STATE_SETUP:
|
||||
case SNDRV_PCM_STATE_PREPARED:
|
||||
if (!is_oss_stream(substream) &&
|
||||
atomic_read(&substream->mmap_count))
|
||||
err = -EBADFD;
|
||||
break;
|
||||
default:
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return -EBADFD;
|
||||
err = -EBADFD;
|
||||
break;
|
||||
}
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
|
||||
if (!substream->oss.oss)
|
||||
#endif
|
||||
if (atomic_read(&substream->mmap_count))
|
||||
return -EBADFD;
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
snd_pcm_sync_stop(substream, true);
|
||||
|
||||
|
@ -799,16 +806,21 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||
if (usecs >= 0)
|
||||
cpu_latency_qos_add_request(&substream->latency_pm_qos_req,
|
||||
usecs);
|
||||
return 0;
|
||||
err = 0;
|
||||
_error:
|
||||
/* hardware might be unusable from this time,
|
||||
so we force application to retry to set
|
||||
the correct hardware parameter settings */
|
||||
snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
|
||||
if (substream->ops->hw_free != NULL)
|
||||
substream->ops->hw_free(substream);
|
||||
if (substream->managed_buffer_alloc)
|
||||
snd_pcm_lib_free_pages(substream);
|
||||
if (err) {
|
||||
/* hardware might be unusable from this time,
|
||||
* so we force application to retry to set
|
||||
* the correct hardware parameter settings
|
||||
*/
|
||||
snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
|
||||
if (substream->ops->hw_free != NULL)
|
||||
substream->ops->hw_free(substream);
|
||||
if (substream->managed_buffer_alloc)
|
||||
snd_pcm_lib_free_pages(substream);
|
||||
}
|
||||
unlock:
|
||||
mutex_unlock(&runtime->buffer_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -848,26 +860,31 @@ static int do_hw_free(struct snd_pcm_substream *substream)
|
|||
static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime;
|
||||
int result;
|
||||
int result = 0;
|
||||
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
runtime = substream->runtime;
|
||||
mutex_lock(&runtime->buffer_mutex);
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
switch (runtime->status->state) {
|
||||
case SNDRV_PCM_STATE_SETUP:
|
||||
case SNDRV_PCM_STATE_PREPARED:
|
||||
if (atomic_read(&substream->mmap_count))
|
||||
result = -EBADFD;
|
||||
break;
|
||||
default:
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return -EBADFD;
|
||||
result = -EBADFD;
|
||||
break;
|
||||
}
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
if (atomic_read(&substream->mmap_count))
|
||||
return -EBADFD;
|
||||
if (result)
|
||||
goto unlock;
|
||||
result = do_hw_free(substream);
|
||||
snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
|
||||
cpu_latency_qos_remove_request(&substream->latency_pm_qos_req);
|
||||
unlock:
|
||||
mutex_unlock(&runtime->buffer_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1173,15 +1190,17 @@ struct action_ops {
|
|||
static int snd_pcm_action_group(const struct action_ops *ops,
|
||||
struct snd_pcm_substream *substream,
|
||||
snd_pcm_state_t state,
|
||||
bool do_lock)
|
||||
bool stream_lock)
|
||||
{
|
||||
struct snd_pcm_substream *s = NULL;
|
||||
struct snd_pcm_substream *s1;
|
||||
int res = 0, depth = 1;
|
||||
|
||||
snd_pcm_group_for_each_entry(s, substream) {
|
||||
if (do_lock && s != substream) {
|
||||
if (s->pcm->nonatomic)
|
||||
if (s != substream) {
|
||||
if (!stream_lock)
|
||||
mutex_lock_nested(&s->runtime->buffer_mutex, depth);
|
||||
else if (s->pcm->nonatomic)
|
||||
mutex_lock_nested(&s->self_group.mutex, depth);
|
||||
else
|
||||
spin_lock_nested(&s->self_group.lock, depth);
|
||||
|
@ -1209,18 +1228,18 @@ static int snd_pcm_action_group(const struct action_ops *ops,
|
|||
ops->post_action(s, state);
|
||||
}
|
||||
_unlock:
|
||||
if (do_lock) {
|
||||
/* unlock streams */
|
||||
snd_pcm_group_for_each_entry(s1, substream) {
|
||||
if (s1 != substream) {
|
||||
if (s1->pcm->nonatomic)
|
||||
mutex_unlock(&s1->self_group.mutex);
|
||||
else
|
||||
spin_unlock(&s1->self_group.lock);
|
||||
}
|
||||
if (s1 == s) /* end */
|
||||
break;
|
||||
/* unlock streams */
|
||||
snd_pcm_group_for_each_entry(s1, substream) {
|
||||
if (s1 != substream) {
|
||||
if (!stream_lock)
|
||||
mutex_unlock(&s1->runtime->buffer_mutex);
|
||||
else if (s1->pcm->nonatomic)
|
||||
mutex_unlock(&s1->self_group.mutex);
|
||||
else
|
||||
spin_unlock(&s1->self_group.lock);
|
||||
}
|
||||
if (s1 == s) /* end */
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -1350,10 +1369,12 @@ static int snd_pcm_action_nonatomic(const struct action_ops *ops,
|
|||
|
||||
/* Guarantee the group members won't change during non-atomic action */
|
||||
down_read(&snd_pcm_link_rwsem);
|
||||
mutex_lock(&substream->runtime->buffer_mutex);
|
||||
if (snd_pcm_stream_linked(substream))
|
||||
res = snd_pcm_action_group(ops, substream, state, false);
|
||||
else
|
||||
res = snd_pcm_action_single(ops, substream, state);
|
||||
mutex_unlock(&substream->runtime->buffer_mutex);
|
||||
up_read(&snd_pcm_link_rwsem);
|
||||
return res;
|
||||
}
|
||||
|
@ -1843,11 +1864,13 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream,
|
|||
int err = snd_pcm_ops_ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
runtime->hw_ptr_base = 0;
|
||||
runtime->hw_ptr_interrupt = runtime->status->hw_ptr -
|
||||
runtime->status->hw_ptr % runtime->period_size;
|
||||
runtime->silence_start = runtime->status->hw_ptr;
|
||||
runtime->silence_filled = 0;
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1855,10 +1878,12 @@ static void snd_pcm_post_reset(struct snd_pcm_substream *substream,
|
|||
snd_pcm_state_t state)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
runtime->control->appl_ptr = runtime->status->hw_ptr;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
|
||||
runtime->silence_size > 0)
|
||||
snd_pcm_playback_silence(substream, ULONG_MAX);
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
}
|
||||
|
||||
static const struct action_ops snd_pcm_action_reset = {
|
||||
|
|
|
@ -66,7 +66,7 @@ snd_seq_oss_create_client(void)
|
|||
struct snd_seq_port_info *port;
|
||||
struct snd_seq_port_callback port_callback;
|
||||
|
||||
port = kmalloc(sizeof(*port), GFP_KERNEL);
|
||||
port = kzalloc(sizeof(*port), GFP_KERNEL);
|
||||
if (!port) {
|
||||
rc = -ENOMEM;
|
||||
goto __error;
|
||||
|
@ -80,8 +80,7 @@ snd_seq_oss_create_client(void)
|
|||
|
||||
system_client = rc;
|
||||
|
||||
/* create annoucement receiver port */
|
||||
memset(port, 0, sizeof(*port));
|
||||
/* create announcement receiver port */
|
||||
strcpy(port->name, "Receiver");
|
||||
port->addr.client = system_client;
|
||||
port->capability = SNDRV_SEQ_PORT_CAP_WRITE; /* receive only */
|
||||
|
|
|
@ -240,9 +240,7 @@ int fcp_avc_transaction(struct fw_unit *unit,
|
|||
t.response_match_bytes = response_match_bytes;
|
||||
t.state = STATE_PENDING;
|
||||
init_waitqueue_head(&t.wait);
|
||||
|
||||
if (*(const u8 *)command == 0x00 || *(const u8 *)command == 0x03)
|
||||
t.deferrable = true;
|
||||
t.deferrable = (*(const u8 *)command == 0x00 || *(const u8 *)command == 0x03);
|
||||
|
||||
spin_lock_irq(&transactions_lock);
|
||||
list_add_tail(&t.list, &transactions);
|
||||
|
|
|
@ -132,6 +132,26 @@ void snd_hdac_link_free_all(struct hdac_bus *bus)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_link_free_all);
|
||||
|
||||
/**
|
||||
* snd_hdac_ext_bus_link_at - get link at specified address
|
||||
* @bus: link's parent bus device
|
||||
* @addr: codec device address
|
||||
*
|
||||
* Returns link object or NULL if matching link is not found.
|
||||
*/
|
||||
struct hdac_ext_link *snd_hdac_ext_bus_link_at(struct hdac_bus *bus, int addr)
|
||||
{
|
||||
struct hdac_ext_link *hlink;
|
||||
int i;
|
||||
|
||||
list_for_each_entry(hlink, &bus->hlink_list, list)
|
||||
for (i = 0; i < HDA_MAX_CODECS; i++)
|
||||
if (hlink->lsdiid & (0x1 << addr))
|
||||
return hlink;
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_at);
|
||||
|
||||
/**
|
||||
* snd_hdac_ext_bus_get_link - get link based on codec name
|
||||
* @bus: the pointer to HDAC bus object
|
||||
|
@ -140,8 +160,6 @@ EXPORT_SYMBOL_GPL(snd_hdac_link_free_all);
|
|||
struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus,
|
||||
const char *codec_name)
|
||||
{
|
||||
int i;
|
||||
struct hdac_ext_link *hlink = NULL;
|
||||
int bus_idx, addr;
|
||||
|
||||
if (sscanf(codec_name, "ehdaudio%dD%d", &bus_idx, &addr) != 2)
|
||||
|
@ -151,14 +169,7 @@ struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus,
|
|||
if (addr < 0 || addr > 31)
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(hlink, &bus->hlink_list, list) {
|
||||
for (i = 0; i < HDA_MAX_CODECS; i++) {
|
||||
if (hlink->lsdiid & (0x1 << addr))
|
||||
return hlink;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return snd_hdac_ext_bus_link_at(bus, addr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_link);
|
||||
|
||||
|
|
|
@ -160,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(&acomp->master_bind_complete,
|
||||
msecs_to_jiffies(60 * 1000));
|
||||
wait_for_completion_killable_timeout(&acomp->master_bind_complete,
|
||||
msecs_to_jiffies(60 * 1000));
|
||||
}
|
||||
}
|
||||
if (!acomp->ops) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <sound/core.h>
|
||||
#include <sound/intel-dsp-config.h>
|
||||
#include <sound/intel-nhlt.h>
|
||||
#include <sound/soc-acpi.h>
|
||||
|
||||
static int dsp_driver;
|
||||
|
||||
|
@ -31,7 +32,12 @@ struct config_entry {
|
|||
u16 device;
|
||||
u8 acpi_hid[ACPI_ID_LEN];
|
||||
const struct dmi_system_id *dmi_table;
|
||||
u8 codec_hid[ACPI_ID_LEN];
|
||||
const struct snd_soc_acpi_codecs *codec_hid;
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_codecs __maybe_unused essx_83x6 = {
|
||||
.num_codecs = 3,
|
||||
.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -77,7 +83,7 @@ static const struct config_entry config_table[] = {
|
|||
{
|
||||
.flags = FLAG_SOF,
|
||||
.device = 0x5a98,
|
||||
.codec_hid = "ESSX8336",
|
||||
.codec_hid = &essx_83x6,
|
||||
},
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL)
|
||||
|
@ -163,7 +169,7 @@ static const struct config_entry config_table[] = {
|
|||
{
|
||||
.flags = FLAG_SOF,
|
||||
.device = 0x3198,
|
||||
.codec_hid = "ESSX8336",
|
||||
.codec_hid = &essx_83x6,
|
||||
},
|
||||
#endif
|
||||
|
||||
|
@ -193,6 +199,11 @@ static const struct config_entry config_table[] = {
|
|||
{}
|
||||
}
|
||||
},
|
||||
{
|
||||
.flags = FLAG_SOF,
|
||||
.device = 0x09dc8,
|
||||
.codec_hid = &essx_83x6,
|
||||
},
|
||||
{
|
||||
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
|
||||
.device = 0x9dc8,
|
||||
|
@ -251,7 +262,7 @@ static const struct config_entry config_table[] = {
|
|||
{
|
||||
.flags = FLAG_SOF,
|
||||
.device = 0x02c8,
|
||||
.codec_hid = "ESSX8336",
|
||||
.codec_hid = &essx_83x6,
|
||||
},
|
||||
{
|
||||
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
|
||||
|
@ -280,7 +291,7 @@ static const struct config_entry config_table[] = {
|
|||
{
|
||||
.flags = FLAG_SOF,
|
||||
.device = 0x06c8,
|
||||
.codec_hid = "ESSX8336",
|
||||
.codec_hid = &essx_83x6,
|
||||
},
|
||||
{
|
||||
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
|
||||
|
@ -327,7 +338,7 @@ static const struct config_entry config_table[] = {
|
|||
{
|
||||
.flags = FLAG_SOF,
|
||||
.device = 0x4dc8,
|
||||
.codec_hid = "ESSX8336",
|
||||
.codec_hid = &essx_83x6,
|
||||
},
|
||||
{
|
||||
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC,
|
||||
|
@ -353,7 +364,7 @@ static const struct config_entry config_table[] = {
|
|||
{
|
||||
.flags = FLAG_SOF,
|
||||
.device = 0xa0c8,
|
||||
.codec_hid = "ESSX8336",
|
||||
.codec_hid = &essx_83x6,
|
||||
},
|
||||
{
|
||||
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
|
||||
|
@ -414,8 +425,15 @@ static const struct config_entry *snd_intel_dsp_find_config
|
|||
continue;
|
||||
if (table->dmi_table && !dmi_check_system(table->dmi_table))
|
||||
continue;
|
||||
if (table->codec_hid[0] && !acpi_dev_present(table->codec_hid, NULL, -1))
|
||||
continue;
|
||||
if (table->codec_hid) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < table->codec_hid->num_codecs; i++)
|
||||
if (acpi_dev_present(table->codec_hid->codecs[i], NULL, -1))
|
||||
break;
|
||||
if (i == table->codec_hid->num_codecs)
|
||||
continue;
|
||||
}
|
||||
return table;
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
@ -130,6 +130,28 @@ bool intel_nhlt_has_endpoint_type(struct nhlt_acpi_table *nhlt, u8 link_type)
|
|||
}
|
||||
EXPORT_SYMBOL(intel_nhlt_has_endpoint_type);
|
||||
|
||||
int intel_nhlt_ssp_endpoint_mask(struct nhlt_acpi_table *nhlt, u8 device_type)
|
||||
{
|
||||
struct nhlt_endpoint *epnt;
|
||||
int ssp_mask = 0;
|
||||
int i;
|
||||
|
||||
if (!nhlt || (device_type != NHLT_DEVICE_BT && device_type != NHLT_DEVICE_I2S))
|
||||
return 0;
|
||||
|
||||
epnt = (struct nhlt_endpoint *)nhlt->desc;
|
||||
for (i = 0; i < nhlt->endpoint_count; i++) {
|
||||
if (epnt->linktype == NHLT_LINK_SSP && epnt->device_type == device_type) {
|
||||
/* for SSP the virtual bus id is the SSP port */
|
||||
ssp_mask |= BIT(epnt->virtual_bus_id);
|
||||
}
|
||||
epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
|
||||
}
|
||||
|
||||
return ssp_mask;
|
||||
}
|
||||
EXPORT_SYMBOL(intel_nhlt_ssp_endpoint_mask);
|
||||
|
||||
static struct nhlt_specific_cfg *
|
||||
nhlt_get_specific_cfg(struct device *dev, struct nhlt_fmt *fmt, u8 num_ch,
|
||||
u32 rate, u8 vbps, u8 bps)
|
||||
|
|
|
@ -289,8 +289,7 @@ static int __init n64audio_probe(struct platform_device *pdev)
|
|||
struct snd_card *card;
|
||||
struct snd_pcm *pcm;
|
||||
struct n64audio *priv;
|
||||
struct resource *res;
|
||||
int err;
|
||||
int err, irq;
|
||||
|
||||
err = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1,
|
||||
SNDRV_DEFAULT_STR1,
|
||||
|
@ -337,12 +336,12 @@ static int __init n64audio_probe(struct platform_device *pdev)
|
|||
strcpy(card->shortname, "N64 Audio");
|
||||
strcpy(card->longname, "N64 Audio");
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!res) {
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
err = -EINVAL;
|
||||
goto fail_dma_alloc;
|
||||
}
|
||||
if (devm_request_irq(&pdev->dev, res->start, n64audio_isr,
|
||||
if (devm_request_irq(&pdev->dev, irq, n64audio_isr,
|
||||
IRQF_SHARED, "N64 Audio", priv)) {
|
||||
err = -EBUSY;
|
||||
goto fail_dma_alloc;
|
||||
|
|
|
@ -938,8 +938,8 @@ static int snd_ac97_ad18xx_pcm_get_volume(struct snd_kcontrol *kcontrol, struct
|
|||
int codec = kcontrol->private_value & 3;
|
||||
|
||||
mutex_lock(&ac97->page_mutex);
|
||||
ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31);
|
||||
ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31);
|
||||
ucontrol->value.integer.value[0] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 8) & 31);
|
||||
ucontrol->value.integer.value[1] = 31 - ((ac97->spec.ad18xx.pcmreg[codec] >> 0) & 31);
|
||||
mutex_unlock(&ac97->page_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -59,15 +59,15 @@
|
|||
/* PCI function 0 registers, address = <val> + PCIBASE0 */
|
||||
/************************************************************************************************/
|
||||
|
||||
#define PTR 0x00 /* Indexed register set pointer register */
|
||||
#define CA0106_PTR 0x00 /* Indexed register set pointer register */
|
||||
/* NOTE: The CHANNELNUM and ADDRESS words can */
|
||||
/* be modified independently of each other. */
|
||||
/* CNL[1:0], ADDR[27:16] */
|
||||
|
||||
#define DATA 0x04 /* Indexed register set data register */
|
||||
#define CA0106_DATA 0x04 /* Indexed register set data register */
|
||||
/* DATA[31:0] */
|
||||
|
||||
#define IPR 0x08 /* Global interrupt pending register */
|
||||
#define CA0106_IPR 0x08 /* Global interrupt pending register */
|
||||
/* Clear pending interrupts by writing a 1 to */
|
||||
/* the relevant bits and zero to the other bits */
|
||||
#define IPR_MIDI_RX_B 0x00020000 /* MIDI UART-B Receive buffer non-empty */
|
||||
|
@ -88,7 +88,7 @@
|
|||
#define IPR_MIDI_TX_A 0x00000002 /* MIDI UART-A Transmit buffer empty */
|
||||
#define IPR_PCI 0x00000001 /* PCI Bus error */
|
||||
|
||||
#define INTE 0x0c /* Interrupt enable register */
|
||||
#define CA0106_INTE 0x0c /* Interrupt enable register */
|
||||
|
||||
#define INTE_MIDI_RX_B 0x00020000 /* MIDI UART-B Receive buffer non-empty */
|
||||
#define INTE_MIDI_TX_B 0x00010000 /* MIDI UART-B Transmit buffer empty */
|
||||
|
@ -108,8 +108,8 @@
|
|||
#define INTE_MIDI_TX_A 0x00000002 /* MIDI UART-A Transmit buffer empty */
|
||||
#define INTE_PCI 0x00000001 /* PCI Bus error */
|
||||
|
||||
#define UNKNOWN10 0x10 /* Unknown ??. Defaults to 0 */
|
||||
#define HCFG 0x14 /* Hardware config register */
|
||||
#define CA0106_UNKNOWN10 0x10 /* Unknown ??. Defaults to 0 */
|
||||
#define CA0106_HCFG 0x14 /* Hardware config register */
|
||||
/* 0x1000 causes AC3 to fails. It adds a dither bit. */
|
||||
|
||||
#define HCFG_STAC 0x10000000 /* Special mode for STAC9460 Codec. */
|
||||
|
@ -133,7 +133,7 @@
|
|||
#define HCFG_AUDIOENABLE 0x00000001 /* 0 = CODECs transmit zero-valued samples */
|
||||
/* Should be set to 1 when the EMU10K1 is */
|
||||
/* completely initialized. */
|
||||
#define GPIO 0x18 /* Defaults: 005f03a3-Analog, 005f02a2-SPDIF. */
|
||||
#define CA0106_GPIO 0x18 /* Defaults: 005f03a3-Analog, 005f02a2-SPDIF. */
|
||||
/* Here pins 0,1,2,3,4,,6 are output. 5,7 are input */
|
||||
/* For the Audigy LS, pin 0 (or bit 8) controls the SPDIF/Analog jack. */
|
||||
/* SB Live 24bit:
|
||||
|
@ -152,9 +152,9 @@
|
|||
* GPO [15:8] Default 0x9. (Default to SPDIF jack enabled for SPDIF)
|
||||
* GPO Enable [23:16] Default 0x0f. Setting a bit to 1, causes the pin to be an output pin.
|
||||
*/
|
||||
#define AC97DATA 0x1c /* AC97 register set data register (16 bit) */
|
||||
#define CA0106_AC97DATA 0x1c /* AC97 register set data register (16 bit) */
|
||||
|
||||
#define AC97ADDRESS 0x1e /* AC97 register set address register (8 bit) */
|
||||
#define CA0106_AC97ADDRESS 0x1e /* AC97 register set address register (8 bit) */
|
||||
|
||||
/********************************************************************************************************/
|
||||
/* CA0106 pointer-offset register set, accessed through the PTR and DATA registers */
|
||||
|
|
|
@ -338,8 +338,8 @@ unsigned int snd_ca0106_ptr_read(struct snd_ca0106 * emu,
|
|||
regptr = (reg << 16) | chn;
|
||||
|
||||
spin_lock_irqsave(&emu->emu_lock, flags);
|
||||
outl(regptr, emu->port + PTR);
|
||||
val = inl(emu->port + DATA);
|
||||
outl(regptr, emu->port + CA0106_PTR);
|
||||
val = inl(emu->port + CA0106_DATA);
|
||||
spin_unlock_irqrestore(&emu->emu_lock, flags);
|
||||
return val;
|
||||
}
|
||||
|
@ -355,8 +355,8 @@ void snd_ca0106_ptr_write(struct snd_ca0106 *emu,
|
|||
regptr = (reg << 16) | chn;
|
||||
|
||||
spin_lock_irqsave(&emu->emu_lock, flags);
|
||||
outl(regptr, emu->port + PTR);
|
||||
outl(data, emu->port + DATA);
|
||||
outl(regptr, emu->port + CA0106_PTR);
|
||||
outl(data, emu->port + CA0106_DATA);
|
||||
spin_unlock_irqrestore(&emu->emu_lock, flags);
|
||||
}
|
||||
|
||||
|
@ -455,8 +455,8 @@ static void snd_ca0106_intr_enable(struct snd_ca0106 *emu, unsigned int intrenb)
|
|||
unsigned int intr_enable;
|
||||
|
||||
spin_lock_irqsave(&emu->emu_lock, flags);
|
||||
intr_enable = inl(emu->port + INTE) | intrenb;
|
||||
outl(intr_enable, emu->port + INTE);
|
||||
intr_enable = inl(emu->port + CA0106_INTE) | intrenb;
|
||||
outl(intr_enable, emu->port + CA0106_INTE);
|
||||
spin_unlock_irqrestore(&emu->emu_lock, flags);
|
||||
}
|
||||
|
||||
|
@ -466,8 +466,8 @@ static void snd_ca0106_intr_disable(struct snd_ca0106 *emu, unsigned int intrenb
|
|||
unsigned int intr_enable;
|
||||
|
||||
spin_lock_irqsave(&emu->emu_lock, flags);
|
||||
intr_enable = inl(emu->port + INTE) & ~intrenb;
|
||||
outl(intr_enable, emu->port + INTE);
|
||||
intr_enable = inl(emu->port + CA0106_INTE) & ~intrenb;
|
||||
outl(intr_enable, emu->port + CA0106_INTE);
|
||||
spin_unlock_irqrestore(&emu->emu_lock, flags);
|
||||
}
|
||||
|
||||
|
@ -786,9 +786,9 @@ static int snd_ca0106_pcm_prepare_playback(struct snd_pcm_substream *substream)
|
|||
hcfg_set = 0;
|
||||
break;
|
||||
}
|
||||
hcfg = inl(emu->port + HCFG) ;
|
||||
hcfg = inl(emu->port + CA0106_HCFG) ;
|
||||
hcfg = (hcfg & ~hcfg_mask) | hcfg_set;
|
||||
outl(hcfg, emu->port + HCFG);
|
||||
outl(hcfg, emu->port + CA0106_HCFG);
|
||||
reg40 = snd_ca0106_ptr_read(emu, 0x40, 0);
|
||||
reg40 = (reg40 & ~reg40_mask) | reg40_set;
|
||||
snd_ca0106_ptr_write(emu, 0x40, 0, reg40);
|
||||
|
@ -888,9 +888,9 @@ static int snd_ca0106_pcm_prepare_capture(struct snd_pcm_substream *substream)
|
|||
hcfg_set = 0;
|
||||
break;
|
||||
}
|
||||
hcfg = inl(emu->port + HCFG) ;
|
||||
hcfg = inl(emu->port + CA0106_HCFG) ;
|
||||
hcfg = (hcfg & ~hcfg_mask) | hcfg_set;
|
||||
outl(hcfg, emu->port + HCFG);
|
||||
outl(hcfg, emu->port + CA0106_HCFG);
|
||||
reg71 = snd_ca0106_ptr_read(emu, 0x71, 0);
|
||||
reg71 = (reg71 & ~reg71_mask) | reg71_set;
|
||||
snd_ca0106_ptr_write(emu, 0x71, 0, reg71);
|
||||
|
@ -1142,8 +1142,8 @@ static unsigned short snd_ca0106_ac97_read(struct snd_ac97 *ac97,
|
|||
unsigned short val;
|
||||
|
||||
spin_lock_irqsave(&emu->emu_lock, flags);
|
||||
outb(reg, emu->port + AC97ADDRESS);
|
||||
val = inw(emu->port + AC97DATA);
|
||||
outb(reg, emu->port + CA0106_AC97ADDRESS);
|
||||
val = inw(emu->port + CA0106_AC97DATA);
|
||||
spin_unlock_irqrestore(&emu->emu_lock, flags);
|
||||
return val;
|
||||
}
|
||||
|
@ -1155,8 +1155,8 @@ static void snd_ca0106_ac97_write(struct snd_ac97 *ac97,
|
|||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&emu->emu_lock, flags);
|
||||
outb(reg, emu->port + AC97ADDRESS);
|
||||
outw(val, emu->port + AC97DATA);
|
||||
outb(reg, emu->port + CA0106_AC97ADDRESS);
|
||||
outw(val, emu->port + CA0106_AC97DATA);
|
||||
spin_unlock_irqrestore(&emu->emu_lock, flags);
|
||||
}
|
||||
|
||||
|
@ -1200,7 +1200,7 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id)
|
|||
unsigned int stat76;
|
||||
struct snd_ca0106_channel *pchannel;
|
||||
|
||||
status = inl(chip->port + IPR);
|
||||
status = inl(chip->port + CA0106_IPR);
|
||||
if (! status)
|
||||
return IRQ_NONE;
|
||||
|
||||
|
@ -1255,7 +1255,7 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
// acknowledge the interrupt if necessary
|
||||
outl(status, chip->port+IPR);
|
||||
outl(status, chip->port + CA0106_IPR);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -1383,7 +1383,7 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
|
|||
int ch;
|
||||
unsigned int def_bits;
|
||||
|
||||
outl(0, chip->port + INTE);
|
||||
outl(0, chip->port + CA0106_INTE);
|
||||
|
||||
/*
|
||||
* Init to 0x02109204 :
|
||||
|
@ -1420,8 +1420,8 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
|
|||
snd_ca0106_ptr_write(chip, CAPTURE_MUTE, 0, 0x00fc0000);
|
||||
|
||||
/* Write 0x8000 to AC97_REC_GAIN to mute it. */
|
||||
outb(AC97_REC_GAIN, chip->port + AC97ADDRESS);
|
||||
outw(0x8000, chip->port + AC97DATA);
|
||||
outb(AC97_REC_GAIN, chip->port + CA0106_AC97ADDRESS);
|
||||
outw(0x8000, chip->port + CA0106_AC97DATA);
|
||||
#if 0 /* FIXME: what are these? */
|
||||
snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006);
|
||||
snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006);
|
||||
|
@ -1495,30 +1495,30 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
|
|||
/* FIXME: Still need to find out what the other GPIO bits do.
|
||||
* E.g. For digital spdif out.
|
||||
*/
|
||||
outl(0x0, chip->port+GPIO);
|
||||
/* outl(0x00f0e000, chip->port+GPIO); */ /* Analog */
|
||||
outl(0x005f5301, chip->port+GPIO); /* Analog */
|
||||
outl(0x0, chip->port + CA0106_GPIO);
|
||||
/* outl(0x00f0e000, chip->port + CA0106_GPIO); */ /* Analog */
|
||||
outl(0x005f5301, chip->port + CA0106_GPIO); /* Analog */
|
||||
} else if (chip->details->gpio_type == 1) {
|
||||
/* The SB0410 and SB0413 use GPIO differently. */
|
||||
/* FIXME: Still need to find out what the other GPIO bits do.
|
||||
* E.g. For digital spdif out.
|
||||
*/
|
||||
outl(0x0, chip->port+GPIO);
|
||||
/* outl(0x00f0e000, chip->port+GPIO); */ /* Analog */
|
||||
outl(0x005f5301, chip->port+GPIO); /* Analog */
|
||||
outl(0x0, chip->port + CA0106_GPIO);
|
||||
/* outl(0x00f0e000, chip->port + CA0106_GPIO); */ /* Analog */
|
||||
outl(0x005f5301, chip->port + CA0106_GPIO); /* Analog */
|
||||
} else {
|
||||
outl(0x0, chip->port+GPIO);
|
||||
outl(0x005f03a3, chip->port+GPIO); /* Analog */
|
||||
/* outl(0x005f02a2, chip->port+GPIO); */ /* SPDIF */
|
||||
outl(0x0, chip->port + CA0106_GPIO);
|
||||
outl(0x005f03a3, chip->port + CA0106_GPIO); /* Analog */
|
||||
/* outl(0x005f02a2, chip->port + CA0106_GPIO); */ /* SPDIF */
|
||||
}
|
||||
snd_ca0106_intr_enable(chip, 0x105); /* Win2000 uses 0x1e0 */
|
||||
|
||||
/* outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG); */
|
||||
/* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
|
||||
/* outl(0x00001409, chip->port+HCFG); */
|
||||
/* outl(0x00000009, chip->port+HCFG); */
|
||||
/* outl(0x00001409, chip->port + CA0106_HCFG); */
|
||||
/* outl(0x00000009, chip->port + CA0106_HCFG); */
|
||||
/* AC97 2.0, Enable outputs. */
|
||||
outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG);
|
||||
outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port + CA0106_HCFG);
|
||||
|
||||
if (chip->details->i2c_adc == 1) {
|
||||
/* The SB0410 and SB0413 use I2C to control ADC. */
|
||||
|
@ -1560,12 +1560,12 @@ static void ca0106_stop_chip(struct snd_ca0106 *chip)
|
|||
{
|
||||
/* disable interrupts */
|
||||
snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0);
|
||||
outl(0, chip->port + INTE);
|
||||
outl(0, chip->port + CA0106_INTE);
|
||||
snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
|
||||
udelay(1000);
|
||||
/* disable audio */
|
||||
/* outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG); */
|
||||
outl(0, chip->port + HCFG);
|
||||
outl(0, chip->port + CA0106_HCFG);
|
||||
/* FIXME: We need to stop and DMA transfers here.
|
||||
* But as I am not sure how yet, we cannot from the dma pages.
|
||||
* So we can fix: snd-malloc: Memory leak? pages not freed = 8
|
||||
|
|
|
@ -70,8 +70,8 @@ static void ca0106_spdif_enable(struct snd_ca0106 *emu)
|
|||
snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
|
||||
val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000;
|
||||
snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
|
||||
val = inl(emu->port + GPIO) & ~0x101;
|
||||
outl(val, emu->port + GPIO);
|
||||
val = inl(emu->port + CA0106_GPIO) & ~0x101;
|
||||
outl(val, emu->port + CA0106_GPIO);
|
||||
|
||||
} else {
|
||||
/* Analog */
|
||||
|
@ -79,8 +79,8 @@ static void ca0106_spdif_enable(struct snd_ca0106 *emu)
|
|||
snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
|
||||
val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000;
|
||||
snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
|
||||
val = inl(emu->port + GPIO) | 0x101;
|
||||
outl(val, emu->port + GPIO);
|
||||
val = inl(emu->port + CA0106_GPIO) | 0x101;
|
||||
outl(val, emu->port + CA0106_GPIO);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,14 +119,14 @@ static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
|
|||
|
||||
if (emu->capture_mic_line_in) {
|
||||
/* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
|
||||
tmp = inl(emu->port+GPIO) & ~0x400;
|
||||
tmp = inl(emu->port + CA0106_GPIO) & ~0x400;
|
||||
tmp = tmp | 0x400;
|
||||
outl(tmp, emu->port+GPIO);
|
||||
outl(tmp, emu->port + CA0106_GPIO);
|
||||
/* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
|
||||
} else {
|
||||
/* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
|
||||
tmp = inl(emu->port+GPIO) & ~0x400;
|
||||
outl(tmp, emu->port+GPIO);
|
||||
tmp = inl(emu->port + CA0106_GPIO) & ~0x400;
|
||||
outl(tmp, emu->port + CA0106_GPIO);
|
||||
/* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -298,7 +298,6 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address.");
|
|||
#define CM_MICGAINZ 0x01 /* mic boost */
|
||||
#define CM_MICGAINZ_SHIFT 0
|
||||
|
||||
#define CM_REG_MIXER3 0x24
|
||||
#define CM_REG_AUX_VOL 0x26
|
||||
#define CM_VAUXL_MASK 0xf0
|
||||
#define CM_VAUXR_MASK 0x0f
|
||||
|
@ -3265,7 +3264,7 @@ static int snd_cmipci_probe(struct pci_dev *pci,
|
|||
*/
|
||||
static const unsigned char saved_regs[] = {
|
||||
CM_REG_FUNCTRL1, CM_REG_CHFORMAT, CM_REG_LEGACY_CTRL, CM_REG_MISC_CTRL,
|
||||
CM_REG_MIXER0, CM_REG_MIXER1, CM_REG_MIXER2, CM_REG_MIXER3, CM_REG_PLL,
|
||||
CM_REG_MIXER0, CM_REG_MIXER1, CM_REG_MIXER2, CM_REG_AUX_VOL, CM_REG_PLL,
|
||||
CM_REG_CH0_FRAME1, CM_REG_CH0_FRAME2,
|
||||
CM_REG_CH1_FRAME1, CM_REG_CH1_FRAME2, CM_REG_EXT_MISC,
|
||||
CM_REG_INT_STATUS, CM_REG_INT_HLDCLR, CM_REG_FUNCTRL0,
|
||||
|
|
|
@ -208,7 +208,7 @@ static void snd_echo_midi_output_write(struct timer_list *t)
|
|||
|
||||
/* No interrupts are involved: we have to check at regular intervals
|
||||
if the card's output buffer has room for new data. */
|
||||
sent = bytes = 0;
|
||||
sent = 0;
|
||||
spin_lock_irqsave(&chip->lock, flags);
|
||||
chip->midi_full = 0;
|
||||
if (!snd_rawmidi_transmit_empty(chip->midi_out)) {
|
||||
|
|
|
@ -285,15 +285,16 @@ config SND_HDA_INTEL_HDMI_SILENT_STREAM
|
|||
bool "Enable Silent Stream always for HDMI"
|
||||
depends on SND_HDA_INTEL
|
||||
help
|
||||
Intel hardware has a feature called 'silent stream', that
|
||||
keeps external HDMI receiver's analog circuitry powered on
|
||||
avoiding 2-3 sec silence during playback start. This mechanism
|
||||
relies on setting channel_id as 0xf, sending info packet and
|
||||
preventing codec D3 entry (increasing platform static power
|
||||
consumption when HDMI receiver is plugged-in). 2-3 sec silence
|
||||
at the playback start is expected whenever there is format change.
|
||||
(default is 2 channel format).
|
||||
Say Y to enable Silent Stream feature.
|
||||
Say Y to enable HD-Audio Keep Alive (KAE) aka Silent Stream
|
||||
for HDMI on hardware that supports the feature.
|
||||
|
||||
When enabled, the HDMI/DisplayPort codec will continue to provide
|
||||
a continuous clock and a valid but silent data stream to
|
||||
any connected external receiver. This allows to avoid gaps
|
||||
at start of playback. Many receivers require multiple seconds
|
||||
to start playing audio after the clock has been stopped.
|
||||
This feature can impact power consumption as resources
|
||||
are kept reserved both at transmitter and receiver.
|
||||
|
||||
endif
|
||||
|
||||
|
|
|
@ -766,6 +766,10 @@ static void codec_release_pcms(struct hda_codec *codec)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hda_codec_cleanup_for_unbind - Prepare codec for removal
|
||||
* @codec: codec device to cleanup
|
||||
*/
|
||||
void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec)
|
||||
{
|
||||
if (codec->registered) {
|
||||
|
@ -813,7 +817,12 @@ void snd_hda_codec_display_power(struct hda_codec *codec, bool enable)
|
|||
snd_hdac_display_power(&codec->bus->core, codec->addr, enable);
|
||||
}
|
||||
|
||||
/* also called from hda_bind.c */
|
||||
/**
|
||||
* snd_hda_codec_register - Finalize codec initialization
|
||||
* @codec: codec device to register
|
||||
*
|
||||
* Also called from hda_bind.c
|
||||
*/
|
||||
void snd_hda_codec_register(struct hda_codec *codec)
|
||||
{
|
||||
if (codec->registered)
|
||||
|
@ -826,6 +835,7 @@ void snd_hda_codec_register(struct hda_codec *codec)
|
|||
codec->registered = 1;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_codec_register);
|
||||
|
||||
static int snd_hda_codec_dev_register(struct snd_device *device)
|
||||
{
|
||||
|
@ -833,10 +843,12 @@ static int snd_hda_codec_dev_register(struct snd_device *device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_hda_codec_dev_free(struct snd_device *device)
|
||||
/**
|
||||
* snd_hda_codec_unregister - Unregister specified codec device
|
||||
* @codec: codec device to unregister
|
||||
*/
|
||||
void snd_hda_codec_unregister(struct hda_codec *codec)
|
||||
{
|
||||
struct hda_codec *codec = device->device_data;
|
||||
|
||||
codec->in_freeing = 1;
|
||||
/*
|
||||
* snd_hda_codec_device_new() is used by legacy HDA and ASoC driver.
|
||||
|
@ -853,7 +865,12 @@ static int snd_hda_codec_dev_free(struct snd_device *device)
|
|||
*/
|
||||
if (codec->core.type == HDA_DEV_LEGACY)
|
||||
put_device(hda_codec_dev(codec));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_codec_unregister);
|
||||
|
||||
static int snd_hda_codec_dev_free(struct snd_device *device)
|
||||
{
|
||||
snd_hda_codec_unregister(device->device_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -877,36 +894,48 @@ static void snd_hda_codec_dev_release(struct device *dev)
|
|||
|
||||
#define DEV_NAME_LEN 31
|
||||
|
||||
static int snd_hda_codec_device_init(struct hda_bus *bus, struct snd_card *card,
|
||||
unsigned int codec_addr, struct hda_codec **codecp)
|
||||
/**
|
||||
* snd_hda_codec_device_init - allocate HDA codec device
|
||||
* @bus: codec's parent bus
|
||||
* @codec_addr: the codec address on the parent bus
|
||||
* @fmt: format string for the device's name
|
||||
*
|
||||
* Returns newly allocated codec device or ERR_PTR() on failure.
|
||||
*/
|
||||
struct hda_codec *
|
||||
snd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list vargs;
|
||||
char name[DEV_NAME_LEN];
|
||||
struct hda_codec *codec;
|
||||
int err;
|
||||
|
||||
dev_dbg(card->dev, "%s: entry\n", __func__);
|
||||
|
||||
if (snd_BUG_ON(!bus))
|
||||
return -EINVAL;
|
||||
return ERR_PTR(-EINVAL);
|
||||
if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
|
||||
return -EINVAL;
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
codec = kzalloc(sizeof(*codec), GFP_KERNEL);
|
||||
if (!codec)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
va_start(vargs, fmt);
|
||||
vsprintf(name, fmt, vargs);
|
||||
va_end(vargs);
|
||||
|
||||
sprintf(name, "hdaudioC%dD%d", card->number, codec_addr);
|
||||
err = snd_hdac_device_init(&codec->core, &bus->core, name, codec_addr);
|
||||
if (err < 0) {
|
||||
kfree(codec);
|
||||
return err;
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
codec->bus = bus;
|
||||
codec->core.type = HDA_DEV_LEGACY;
|
||||
*codecp = codec;
|
||||
|
||||
return err;
|
||||
return codec;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_codec_device_init);
|
||||
|
||||
/**
|
||||
* snd_hda_codec_new - create a HDA codec
|
||||
|
@ -920,18 +949,21 @@ static int snd_hda_codec_device_init(struct hda_bus *bus, struct snd_card *card,
|
|||
int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
|
||||
unsigned int codec_addr, struct hda_codec **codecp)
|
||||
{
|
||||
int ret;
|
||||
struct hda_codec *codec;
|
||||
|
||||
ret = snd_hda_codec_device_init(bus, card, codec_addr, codecp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
codec = snd_hda_codec_device_init(bus, codec_addr, "hdaudioC%dD%d",
|
||||
card->number, codec_addr);
|
||||
if (IS_ERR(codec))
|
||||
return PTR_ERR(codec);
|
||||
*codecp = codec;
|
||||
|
||||
return snd_hda_codec_device_new(bus, card, codec_addr, *codecp);
|
||||
return snd_hda_codec_device_new(bus, card, codec_addr, *codecp, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_codec_new);
|
||||
|
||||
int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
|
||||
unsigned int codec_addr, struct hda_codec *codec)
|
||||
unsigned int codec_addr, struct hda_codec *codec,
|
||||
bool snddev_managed)
|
||||
{
|
||||
char component[31];
|
||||
hda_nid_t fg;
|
||||
|
@ -951,7 +983,6 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
|
|||
codec->core.dev.release = snd_hda_codec_dev_release;
|
||||
codec->core.exec_verb = codec_exec_verb;
|
||||
|
||||
codec->bus = bus;
|
||||
codec->card = card;
|
||||
codec->addr = codec_addr;
|
||||
mutex_init(&codec->spdif_mutex);
|
||||
|
@ -1007,9 +1038,12 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
|
|||
codec->core.subsystem_id, codec->core.revision_id);
|
||||
snd_component_add(card, component);
|
||||
|
||||
err = snd_device_new(card, SNDRV_DEV_CODEC, codec, &dev_ops);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
if (snddev_managed) {
|
||||
/* ASoC features component management instead */
|
||||
err = snd_device_new(card, SNDRV_DEV_CODEC, codec, &dev_ops);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* PM runtime needs to be enabled later after binding codec */
|
||||
pm_runtime_forbid(&codec->core.dev);
|
||||
|
@ -3371,7 +3405,12 @@ int snd_hda_add_new_ctls(struct hda_codec *codec,
|
|||
EXPORT_SYMBOL_GPL(snd_hda_add_new_ctls);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static void codec_set_power_save(struct hda_codec *codec, int delay)
|
||||
/**
|
||||
* snd_hda_codec_set_power_save - Configure codec's runtime PM
|
||||
* @codec: codec device to configure
|
||||
* @delay: autosuspend delay
|
||||
*/
|
||||
void snd_hda_codec_set_power_save(struct hda_codec *codec, int delay)
|
||||
{
|
||||
struct device *dev = hda_codec_dev(codec);
|
||||
|
||||
|
@ -3389,6 +3428,7 @@ static void codec_set_power_save(struct hda_codec *codec, int delay)
|
|||
pm_runtime_forbid(dev);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_save);
|
||||
|
||||
/**
|
||||
* snd_hda_set_power_save - reprogram autosuspend for the given delay
|
||||
|
@ -3402,7 +3442,7 @@ void snd_hda_set_power_save(struct hda_bus *bus, int delay)
|
|||
struct hda_codec *c;
|
||||
|
||||
list_for_each_codec(c, bus)
|
||||
codec_set_power_save(c, delay);
|
||||
snd_hda_codec_set_power_save(c, delay);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_set_power_save);
|
||||
|
||||
|
|
|
@ -2066,14 +2066,16 @@ static const struct hda_controller_ops pci_hda_ops = {
|
|||
.position_check = azx_position_check,
|
||||
};
|
||||
|
||||
static DECLARE_BITMAP(probed_devs, SNDRV_CARDS);
|
||||
|
||||
static int azx_probe(struct pci_dev *pci,
|
||||
const struct pci_device_id *pci_id)
|
||||
{
|
||||
static int dev;
|
||||
struct snd_card *card;
|
||||
struct hda_intel *hda;
|
||||
struct azx *chip;
|
||||
bool schedule_probe;
|
||||
int dev;
|
||||
int err;
|
||||
|
||||
if (pci_match_id(driver_denylist, pci)) {
|
||||
|
@ -2081,10 +2083,11 @@ static int azx_probe(struct pci_dev *pci,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
dev = find_first_zero_bit(probed_devs, SNDRV_CARDS);
|
||||
if (dev >= SNDRV_CARDS)
|
||||
return -ENODEV;
|
||||
if (!enable[dev]) {
|
||||
dev++;
|
||||
set_bit(dev, probed_devs);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
@ -2151,7 +2154,7 @@ static int azx_probe(struct pci_dev *pci,
|
|||
if (schedule_probe)
|
||||
schedule_delayed_work(&hda->probe_work, 0);
|
||||
|
||||
dev++;
|
||||
set_bit(dev, probed_devs);
|
||||
if (chip->disabled)
|
||||
complete_all(&hda->probe_wait);
|
||||
return 0;
|
||||
|
@ -2374,6 +2377,7 @@ static void azx_remove(struct pci_dev *pci)
|
|||
cancel_delayed_work_sync(&hda->probe_work);
|
||||
device_lock(&pci->dev);
|
||||
|
||||
clear_bit(chip->dev_index, probed_devs);
|
||||
pci_set_drvdata(pci, NULL);
|
||||
snd_card_free(card);
|
||||
}
|
||||
|
@ -2495,6 +2499,8 @@ static const struct pci_device_id azx_ids[] = {
|
|||
/* Alderlake-P */
|
||||
{ PCI_DEVICE(0x8086, 0x51c8),
|
||||
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
||||
{ PCI_DEVICE(0x8086, 0x51c9),
|
||||
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
||||
{ PCI_DEVICE(0x8086, 0x51cd),
|
||||
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
||||
/* Alderlake-M */
|
||||
|
@ -2508,6 +2514,17 @@ static const struct pci_device_id azx_ids[] = {
|
|||
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
||||
{ PCI_DEVICE(0x8086, 0x4b58),
|
||||
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
||||
/* Raptor Lake */
|
||||
{ PCI_DEVICE(0x8086, 0x7a50),
|
||||
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
||||
{ PCI_DEVICE(0x8086, 0x51ca),
|
||||
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
||||
{ PCI_DEVICE(0x8086, 0x51cb),
|
||||
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
||||
{ PCI_DEVICE(0x8086, 0x51ce),
|
||||
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
||||
{ PCI_DEVICE(0x8086, 0x51cf),
|
||||
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
|
||||
/* Broxton-P(Apollolake) */
|
||||
{ PCI_DEVICE(0x8086, 0x5a98),
|
||||
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON },
|
||||
|
|
|
@ -135,8 +135,6 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
|
|||
#define snd_hda_add_vmaster(codec, name, tlv, followers, suffix, access) \
|
||||
__snd_hda_add_vmaster(codec, name, tlv, followers, suffix, true, access, NULL)
|
||||
int snd_hda_codec_reset(struct hda_codec *codec);
|
||||
void snd_hda_codec_register(struct hda_codec *codec);
|
||||
void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec);
|
||||
void snd_hda_codec_disconnect_pcms(struct hda_codec *codec);
|
||||
|
||||
#define snd_hda_regmap_sync(codec) snd_hdac_regmap_sync(&(codec)->core)
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
|
||||
struct hda_tegra_soc {
|
||||
bool has_hda2codec_2x_reset;
|
||||
bool has_hda2hdmi;
|
||||
};
|
||||
|
||||
struct hda_tegra {
|
||||
|
@ -314,6 +315,18 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
|
|||
* hardcoded value
|
||||
*/
|
||||
chip->capture_streams = (gcap >> 8) & 0x0f;
|
||||
|
||||
/* The GCAP register on Tegra234 implies no Input Streams(ISS) support,
|
||||
* but the HW output stream descriptor programming should start with
|
||||
* offset 0x20*4 from base stream descriptor address. This will be a
|
||||
* problem while calculating the offset for output stream descriptor
|
||||
* which will be considering input stream also. So here output stream
|
||||
* starts with offset 0 which is wrong as HW register for output stream
|
||||
* offset starts with 4.
|
||||
*/
|
||||
if (of_device_is_compatible(np, "nvidia,tegra234-hda"))
|
||||
chip->capture_streams = 4;
|
||||
|
||||
chip->playback_streams = (gcap >> 12) & 0x0f;
|
||||
if (!chip->playback_streams && !chip->capture_streams) {
|
||||
/* gcap didn't give any info, switching to old method */
|
||||
|
@ -435,15 +448,23 @@ static int hda_tegra_create(struct snd_card *card,
|
|||
|
||||
static const struct hda_tegra_soc tegra30_data = {
|
||||
.has_hda2codec_2x_reset = true,
|
||||
.has_hda2hdmi = true,
|
||||
};
|
||||
|
||||
static const struct hda_tegra_soc tegra194_data = {
|
||||
.has_hda2codec_2x_reset = false,
|
||||
.has_hda2hdmi = true,
|
||||
};
|
||||
|
||||
static const struct hda_tegra_soc tegra234_data = {
|
||||
.has_hda2codec_2x_reset = true,
|
||||
.has_hda2hdmi = false,
|
||||
};
|
||||
|
||||
static const struct of_device_id hda_tegra_match[] = {
|
||||
{ .compatible = "nvidia,tegra30-hda", .data = &tegra30_data },
|
||||
{ .compatible = "nvidia,tegra194-hda", .data = &tegra194_data },
|
||||
{ .compatible = "nvidia,tegra234-hda", .data = &tegra234_data },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, hda_tegra_match);
|
||||
|
@ -473,7 +494,14 @@ static int hda_tegra_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
hda->resets[hda->nresets++].id = "hda";
|
||||
hda->resets[hda->nresets++].id = "hda2hdmi";
|
||||
|
||||
/*
|
||||
* "hda2hdmi" is not applicable for Tegra234. This is because the
|
||||
* codec is separate IP and not under display SOR partition now.
|
||||
*/
|
||||
if (hda->soc->has_hda2hdmi)
|
||||
hda->resets[hda->nresets++].id = "hda2hdmi";
|
||||
|
||||
/*
|
||||
* "hda2codec_2x" reset is not present on Tegra194. Though DT would
|
||||
* be updated to reflect this, but to have backward compatibility
|
||||
|
@ -488,7 +516,8 @@ static int hda_tegra_probe(struct platform_device *pdev)
|
|||
goto out_free;
|
||||
|
||||
hda->clocks[hda->nclocks++].id = "hda";
|
||||
hda->clocks[hda->nclocks++].id = "hda2hdmi";
|
||||
if (hda->soc->has_hda2hdmi)
|
||||
hda->clocks[hda->nclocks++].id = "hda2hdmi";
|
||||
hda->clocks[hda->nclocks++].id = "hda2codec_2x";
|
||||
|
||||
err = devm_clk_bulk_get(&pdev->dev, hda->nclocks, hda->clocks);
|
||||
|
|
|
@ -120,6 +120,12 @@ struct hdmi_pcm {
|
|||
struct snd_kcontrol *eld_ctl;
|
||||
};
|
||||
|
||||
enum {
|
||||
SILENT_STREAM_OFF = 0,
|
||||
SILENT_STREAM_KAE, /* use standard HDA Keep-Alive */
|
||||
SILENT_STREAM_I915, /* Intel i915 extension */
|
||||
};
|
||||
|
||||
struct hdmi_spec {
|
||||
struct hda_codec *codec;
|
||||
int num_cvts;
|
||||
|
@ -162,6 +168,8 @@ struct hdmi_spec {
|
|||
bool dyn_pin_out;
|
||||
bool dyn_pcm_assign;
|
||||
bool dyn_pcm_no_legacy;
|
||||
/* hdmi interrupt trigger control flag for Nvidia codec */
|
||||
bool hdmi_intr_trig_ctrl;
|
||||
bool intel_hsw_fixup; /* apply Intel platform-specific fixups */
|
||||
/*
|
||||
* Non-generic VIA/NVIDIA specific
|
||||
|
@ -179,7 +187,7 @@ struct hdmi_spec {
|
|||
hda_nid_t vendor_nid;
|
||||
const int *port_map;
|
||||
int port_num;
|
||||
bool send_silent_stream; /* Flag to enable silent stream feature */
|
||||
int silent_stream_type;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SND_HDA_COMPONENT
|
||||
|
@ -1665,18 +1673,71 @@ static void hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
|
|||
#define I915_SILENT_FORMAT_BITS 16
|
||||
#define I915_SILENT_FMT_MASK 0xf
|
||||
|
||||
static void silent_stream_enable_i915(struct hda_codec *codec,
|
||||
struct hdmi_spec_per_pin *per_pin)
|
||||
{
|
||||
unsigned int format;
|
||||
|
||||
snd_hdac_sync_audio_rate(&codec->core, per_pin->pin_nid,
|
||||
per_pin->dev_id, I915_SILENT_RATE);
|
||||
|
||||
/* trigger silent stream generation in hw */
|
||||
format = snd_hdac_calc_stream_format(I915_SILENT_RATE, I915_SILENT_CHANNELS,
|
||||
I915_SILENT_FORMAT, I915_SILENT_FORMAT_BITS, 0);
|
||||
snd_hda_codec_setup_stream(codec, per_pin->cvt_nid,
|
||||
I915_SILENT_FMT_MASK, I915_SILENT_FMT_MASK, format);
|
||||
usleep_range(100, 200);
|
||||
snd_hda_codec_setup_stream(codec, per_pin->cvt_nid, I915_SILENT_FMT_MASK, 0, format);
|
||||
|
||||
per_pin->channels = I915_SILENT_CHANNELS;
|
||||
hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
|
||||
}
|
||||
|
||||
static void silent_stream_set_kae(struct hda_codec *codec,
|
||||
struct hdmi_spec_per_pin *per_pin,
|
||||
bool enable)
|
||||
{
|
||||
unsigned int param;
|
||||
|
||||
codec_dbg(codec, "HDMI: KAE %d cvt-NID=0x%x\n", enable, per_pin->cvt_nid);
|
||||
|
||||
param = snd_hda_codec_read(codec, per_pin->cvt_nid, 0, AC_VERB_GET_DIGI_CONVERT_1, 0);
|
||||
param = (param >> 16) & 0xff;
|
||||
|
||||
if (enable)
|
||||
param |= AC_DIG3_KAE;
|
||||
else
|
||||
param &= ~AC_DIG3_KAE;
|
||||
|
||||
snd_hda_codec_write(codec, per_pin->cvt_nid, 0, AC_VERB_SET_DIGI_CONVERT_3, param);
|
||||
}
|
||||
|
||||
static void silent_stream_enable(struct hda_codec *codec,
|
||||
struct hdmi_spec_per_pin *per_pin)
|
||||
{
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
struct hdmi_spec_per_cvt *per_cvt;
|
||||
int cvt_idx, pin_idx, err;
|
||||
unsigned int format;
|
||||
int keep_power = 0;
|
||||
|
||||
/*
|
||||
* Power-up will call hdmi_present_sense, so the PM calls
|
||||
* have to be done without mutex held.
|
||||
*/
|
||||
|
||||
err = snd_hda_power_up_pm(codec);
|
||||
if (err < 0 && err != -EACCES) {
|
||||
codec_err(codec,
|
||||
"Failed to power up codec for silent stream enable ret=[%d]\n", err);
|
||||
snd_hda_power_down_pm(codec);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&per_pin->lock);
|
||||
|
||||
if (per_pin->setup) {
|
||||
codec_dbg(codec, "hdmi: PCM already open, no silent stream\n");
|
||||
err = -EBUSY;
|
||||
goto unlock_out;
|
||||
}
|
||||
|
||||
|
@ -1703,22 +1764,23 @@ static void silent_stream_enable(struct hda_codec *codec,
|
|||
/* configure unused pins to choose other converters */
|
||||
pin_cvt_fixup(codec, per_pin, 0);
|
||||
|
||||
snd_hdac_sync_audio_rate(&codec->core, per_pin->pin_nid,
|
||||
per_pin->dev_id, I915_SILENT_RATE);
|
||||
|
||||
/* trigger silent stream generation in hw */
|
||||
format = snd_hdac_calc_stream_format(I915_SILENT_RATE, I915_SILENT_CHANNELS,
|
||||
I915_SILENT_FORMAT, I915_SILENT_FORMAT_BITS, 0);
|
||||
snd_hda_codec_setup_stream(codec, per_pin->cvt_nid,
|
||||
I915_SILENT_FMT_MASK, I915_SILENT_FMT_MASK, format);
|
||||
usleep_range(100, 200);
|
||||
snd_hda_codec_setup_stream(codec, per_pin->cvt_nid, I915_SILENT_FMT_MASK, 0, format);
|
||||
|
||||
per_pin->channels = I915_SILENT_CHANNELS;
|
||||
hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
|
||||
switch (spec->silent_stream_type) {
|
||||
case SILENT_STREAM_KAE:
|
||||
silent_stream_set_kae(codec, per_pin, true);
|
||||
break;
|
||||
case SILENT_STREAM_I915:
|
||||
silent_stream_enable_i915(codec, per_pin);
|
||||
keep_power = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
unlock_out:
|
||||
mutex_unlock(&per_pin->lock);
|
||||
|
||||
if (err || !keep_power)
|
||||
snd_hda_power_down_pm(codec);
|
||||
}
|
||||
|
||||
static void silent_stream_disable(struct hda_codec *codec,
|
||||
|
@ -1726,7 +1788,16 @@ static void silent_stream_disable(struct hda_codec *codec,
|
|||
{
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
struct hdmi_spec_per_cvt *per_cvt;
|
||||
int cvt_idx;
|
||||
int cvt_idx, err;
|
||||
|
||||
err = snd_hda_power_up_pm(codec);
|
||||
if (err < 0 && err != -EACCES) {
|
||||
codec_err(codec,
|
||||
"Failed to power up codec for silent stream disable ret=[%d]\n",
|
||||
err);
|
||||
snd_hda_power_down_pm(codec);
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&per_pin->lock);
|
||||
if (!per_pin->silent_stream)
|
||||
|
@ -1741,11 +1812,20 @@ static void silent_stream_disable(struct hda_codec *codec,
|
|||
per_cvt->assigned = 0;
|
||||
}
|
||||
|
||||
if (spec->silent_stream_type == SILENT_STREAM_I915) {
|
||||
/* release ref taken in silent_stream_enable() */
|
||||
snd_hda_power_down_pm(codec);
|
||||
} else if (spec->silent_stream_type == SILENT_STREAM_KAE) {
|
||||
silent_stream_set_kae(codec, per_pin, false);
|
||||
}
|
||||
|
||||
per_pin->cvt_nid = 0;
|
||||
per_pin->silent_stream = false;
|
||||
|
||||
unlock_out:
|
||||
mutex_unlock(&per_pin->lock);
|
||||
|
||||
snd_hda_power_down_pm(codec);
|
||||
}
|
||||
|
||||
/* update ELD and jack state via audio component */
|
||||
|
@ -1767,29 +1847,11 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
|
|||
monitor_next = per_pin->sink_eld.monitor_present;
|
||||
mutex_unlock(&per_pin->lock);
|
||||
|
||||
/*
|
||||
* Power-up will call hdmi_present_sense, so the PM calls
|
||||
* have to be done without mutex held.
|
||||
*/
|
||||
|
||||
if (spec->send_silent_stream) {
|
||||
int pm_ret;
|
||||
|
||||
if (!monitor_prev && monitor_next) {
|
||||
pm_ret = snd_hda_power_up_pm(codec);
|
||||
if (pm_ret < 0)
|
||||
codec_err(codec,
|
||||
"Monitor plugged-in, Failed to power up codec ret=[%d]\n",
|
||||
pm_ret);
|
||||
if (spec->silent_stream_type) {
|
||||
if (!monitor_prev && monitor_next)
|
||||
silent_stream_enable(codec, per_pin);
|
||||
} else if (monitor_prev && !monitor_next) {
|
||||
else if (monitor_prev && !monitor_next)
|
||||
silent_stream_disable(codec, per_pin);
|
||||
pm_ret = snd_hda_power_down_pm(codec);
|
||||
if (pm_ret < 0)
|
||||
codec_err(codec,
|
||||
"Monitor plugged-out, Failed to power down codec ret=[%d]\n",
|
||||
pm_ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2982,7 +3044,7 @@ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid,
|
|||
* module param or Kconfig option
|
||||
*/
|
||||
if (send_silent_stream)
|
||||
spec->send_silent_stream = true;
|
||||
spec->silent_stream_type = SILENT_STREAM_I915;
|
||||
|
||||
return parse_intel_hdmi(codec);
|
||||
}
|
||||
|
@ -3035,6 +3097,22 @@ static int patch_i915_tgl_hdmi(struct hda_codec *codec)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int patch_i915_adlp_hdmi(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec;
|
||||
int res;
|
||||
|
||||
res = patch_i915_tgl_hdmi(codec);
|
||||
if (!res) {
|
||||
spec = codec->spec;
|
||||
|
||||
if (spec->silent_stream_type)
|
||||
spec->silent_stream_type = SILENT_STREAM_KAE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Intel Baytrail and Braswell; with eld notifier */
|
||||
static int patch_i915_byt_hdmi(struct hda_codec *codec)
|
||||
{
|
||||
|
@ -3721,8 +3799,11 @@ static int patch_nvhdmi_legacy(struct hda_codec *codec)
|
|||
* +-----------------------------------|
|
||||
*
|
||||
* Note that for the trigger bit to take effect it needs to change value
|
||||
* (i.e. it needs to be toggled).
|
||||
* (i.e. it needs to be toggled). The trigger bit is not applicable from
|
||||
* TEGRA234 chip onwards, as new verb id 0xf80 will be used for interrupt
|
||||
* trigger to hdmi.
|
||||
*/
|
||||
#define NVIDIA_SET_HOST_INTR 0xf80
|
||||
#define NVIDIA_GET_SCRATCH0 0xfa6
|
||||
#define NVIDIA_SET_SCRATCH0_BYTE0 0xfa7
|
||||
#define NVIDIA_SET_SCRATCH0_BYTE1 0xfa8
|
||||
|
@ -3741,25 +3822,38 @@ static int patch_nvhdmi_legacy(struct hda_codec *codec)
|
|||
* The format parameter is the HDA audio format (see AC_FMT_*). If set to 0,
|
||||
* the format is invalidated so that the HDMI codec can be disabled.
|
||||
*/
|
||||
static void tegra_hdmi_set_format(struct hda_codec *codec, unsigned int format)
|
||||
static void tegra_hdmi_set_format(struct hda_codec *codec,
|
||||
hda_nid_t cvt_nid,
|
||||
unsigned int format)
|
||||
{
|
||||
unsigned int value;
|
||||
unsigned int nid = NVIDIA_AFG_NID;
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
|
||||
/*
|
||||
* Tegra HDA codec design from TEGRA234 chip onwards support DP MST.
|
||||
* This resulted in moving scratch registers from audio function
|
||||
* group to converter widget context. So CVT NID should be used for
|
||||
* scratch register read/write for DP MST supported Tegra HDA codec.
|
||||
*/
|
||||
if (codec->dp_mst)
|
||||
nid = cvt_nid;
|
||||
|
||||
/* bits [31:30] contain the trigger and valid bits */
|
||||
value = snd_hda_codec_read(codec, NVIDIA_AFG_NID, 0,
|
||||
value = snd_hda_codec_read(codec, nid, 0,
|
||||
NVIDIA_GET_SCRATCH0, 0);
|
||||
value = (value >> 24) & 0xff;
|
||||
|
||||
/* bits [15:0] are used to store the HDA format */
|
||||
snd_hda_codec_write(codec, NVIDIA_AFG_NID, 0,
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
NVIDIA_SET_SCRATCH0_BYTE0,
|
||||
(format >> 0) & 0xff);
|
||||
snd_hda_codec_write(codec, NVIDIA_AFG_NID, 0,
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
NVIDIA_SET_SCRATCH0_BYTE1,
|
||||
(format >> 8) & 0xff);
|
||||
|
||||
/* bits [16:24] are unused */
|
||||
snd_hda_codec_write(codec, NVIDIA_AFG_NID, 0,
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
NVIDIA_SET_SCRATCH0_BYTE2, 0);
|
||||
|
||||
/*
|
||||
|
@ -3771,15 +3865,28 @@ static void tegra_hdmi_set_format(struct hda_codec *codec, unsigned int format)
|
|||
else
|
||||
value |= NVIDIA_SCRATCH_VALID;
|
||||
|
||||
/*
|
||||
* Whenever the trigger bit is toggled, an interrupt is raised in the
|
||||
* HDMI codec. The HDMI driver will use that as trigger to update its
|
||||
* configuration.
|
||||
*/
|
||||
value ^= NVIDIA_SCRATCH_TRIGGER;
|
||||
if (spec->hdmi_intr_trig_ctrl) {
|
||||
/*
|
||||
* For Tegra HDA Codec design from TEGRA234 onwards, the
|
||||
* Interrupt to hdmi driver is triggered by writing
|
||||
* non-zero values to verb 0xF80 instead of 31st bit of
|
||||
* scratch register.
|
||||
*/
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
NVIDIA_SET_SCRATCH0_BYTE3, value);
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
NVIDIA_SET_HOST_INTR, 0x1);
|
||||
} else {
|
||||
/*
|
||||
* Whenever the 31st trigger bit is toggled, an interrupt is raised
|
||||
* in the HDMI codec. The HDMI driver will use that as trigger
|
||||
* to update its configuration.
|
||||
*/
|
||||
value ^= NVIDIA_SCRATCH_TRIGGER;
|
||||
|
||||
snd_hda_codec_write(codec, NVIDIA_AFG_NID, 0,
|
||||
NVIDIA_SET_SCRATCH0_BYTE3, value);
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
NVIDIA_SET_SCRATCH0_BYTE3, value);
|
||||
}
|
||||
}
|
||||
|
||||
static int tegra_hdmi_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
|
@ -3796,7 +3903,7 @@ static int tegra_hdmi_pcm_prepare(struct hda_pcm_stream *hinfo,
|
|||
return err;
|
||||
|
||||
/* notify the HDMI codec of the format change */
|
||||
tegra_hdmi_set_format(codec, format);
|
||||
tegra_hdmi_set_format(codec, hinfo->nid, format);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3806,7 +3913,7 @@ static int tegra_hdmi_pcm_cleanup(struct hda_pcm_stream *hinfo,
|
|||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
/* invalidate the format in the HDMI codec */
|
||||
tegra_hdmi_set_format(codec, 0);
|
||||
tegra_hdmi_set_format(codec, hinfo->nid, 0);
|
||||
|
||||
return generic_hdmi_playback_pcm_cleanup(hinfo, codec, substream);
|
||||
}
|
||||
|
@ -3851,17 +3958,29 @@ static int tegra_hdmi_build_pcms(struct hda_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int patch_tegra_hdmi(struct hda_codec *codec)
|
||||
static int tegra_hdmi_init(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec;
|
||||
int err;
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
int i, err;
|
||||
|
||||
err = patch_generic_hdmi(codec);
|
||||
if (err)
|
||||
err = hdmi_parse_codec(codec);
|
||||
if (err < 0) {
|
||||
generic_spec_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 0; i < spec->num_cvts; i++)
|
||||
snd_hda_codec_write(codec, spec->cvt_nids[i], 0,
|
||||
AC_VERB_SET_DIGI_CONVERT_1,
|
||||
AC_DIG1_ENABLE);
|
||||
|
||||
generic_hdmi_init_per_pins(codec);
|
||||
|
||||
codec->patch_ops.build_pcms = tegra_hdmi_build_pcms;
|
||||
spec = codec->spec;
|
||||
spec->chmap.ops.chmap_cea_alloc_validate_get_type =
|
||||
nvhdmi_chmap_cea_alloc_validate_get_type;
|
||||
spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate;
|
||||
|
||||
spec->chmap.ops.chmap_cea_alloc_validate_get_type =
|
||||
nvhdmi_chmap_cea_alloc_validate_get_type;
|
||||
spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate;
|
||||
|
@ -3869,6 +3988,36 @@ static int patch_tegra_hdmi(struct hda_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int patch_tegra_hdmi(struct hda_codec *codec)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = alloc_generic_hdmi(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return tegra_hdmi_init(codec);
|
||||
}
|
||||
|
||||
static int patch_tegra234_hdmi(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec;
|
||||
int err;
|
||||
|
||||
err = alloc_generic_hdmi(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
codec->dp_mst = true;
|
||||
codec->mst_no_extra_pcms = true;
|
||||
spec = codec->spec;
|
||||
spec->dyn_pin_out = true;
|
||||
spec->dyn_pcm_assign = true;
|
||||
spec->hdmi_intr_trig_ctrl = true;
|
||||
|
||||
return tegra_hdmi_init(codec);
|
||||
}
|
||||
|
||||
/*
|
||||
* ATI/AMD-specific implementations
|
||||
*/
|
||||
|
@ -4322,6 +4471,7 @@ HDA_CODEC_ENTRY(0x10de002d, "Tegra186 HDMI/DP0", patch_tegra_hdmi),
|
|||
HDA_CODEC_ENTRY(0x10de002e, "Tegra186 HDMI/DP1", patch_tegra_hdmi),
|
||||
HDA_CODEC_ENTRY(0x10de002f, "Tegra194 HDMI/DP2", patch_tegra_hdmi),
|
||||
HDA_CODEC_ENTRY(0x10de0030, "Tegra194 HDMI/DP3", patch_tegra_hdmi),
|
||||
HDA_CODEC_ENTRY(0x10de0031, "Tegra234 HDMI/DP", patch_tegra234_hdmi),
|
||||
HDA_CODEC_ENTRY(0x10de0040, "GPU 40 HDMI/DP", patch_nvhdmi),
|
||||
HDA_CODEC_ENTRY(0x10de0041, "GPU 41 HDMI/DP", patch_nvhdmi),
|
||||
HDA_CODEC_ENTRY(0x10de0042, "GPU 42 HDMI/DP", patch_nvhdmi),
|
||||
|
@ -4390,10 +4540,11 @@ HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi),
|
|||
HDA_CODEC_ENTRY(0x80862814, "DG1 HDMI", patch_i915_tgl_hdmi),
|
||||
HDA_CODEC_ENTRY(0x80862815, "Alderlake HDMI", patch_i915_tgl_hdmi),
|
||||
HDA_CODEC_ENTRY(0x80862816, "Rocketlake HDMI", patch_i915_tgl_hdmi),
|
||||
HDA_CODEC_ENTRY(0x80862819, "DG2 HDMI", patch_i915_tgl_hdmi),
|
||||
HDA_CODEC_ENTRY(0x80862818, "Raptorlake HDMI", patch_i915_tgl_hdmi),
|
||||
HDA_CODEC_ENTRY(0x80862819, "DG2 HDMI", patch_i915_adlp_hdmi),
|
||||
HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi),
|
||||
HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI", patch_i915_icl_hdmi),
|
||||
HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_tgl_hdmi),
|
||||
HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_adlp_hdmi),
|
||||
HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
|
||||
HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi),
|
||||
HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),
|
||||
|
|
|
@ -6662,6 +6662,16 @@ static void cs35l41_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup
|
|||
cs35l41_generic_fixup(cdc, action, "i2c", "CSC3551", 2);
|
||||
}
|
||||
|
||||
static void cs35l41_fixup_spi_two(struct hda_codec *codec, const struct hda_fixup *fix, int action)
|
||||
{
|
||||
cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 2);
|
||||
}
|
||||
|
||||
static void cs35l41_fixup_spi_four(struct hda_codec *codec, const struct hda_fixup *fix, int action)
|
||||
{
|
||||
cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 4);
|
||||
}
|
||||
|
||||
static void alc287_legion_16achg6_playback_hook(struct hda_pcm_stream *hinfo, struct hda_codec *cdc,
|
||||
struct snd_pcm_substream *sub, int action)
|
||||
{
|
||||
|
@ -6948,6 +6958,7 @@ enum {
|
|||
ALC236_FIXUP_HP_MUTE_LED,
|
||||
ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF,
|
||||
ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
|
||||
ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
|
||||
ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
|
||||
ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS,
|
||||
ALC269VC_FIXUP_ACER_HEADSET_MIC,
|
||||
|
@ -6999,6 +7010,9 @@ enum {
|
|||
ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE,
|
||||
ALC287_FIXUP_LEGION_16ACHG6,
|
||||
ALC287_FIXUP_CS35L41_I2C_2,
|
||||
ALC245_FIXUP_CS35L41_SPI_2,
|
||||
ALC245_FIXUP_CS35L41_SPI_4,
|
||||
ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED,
|
||||
ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
|
||||
};
|
||||
|
||||
|
@ -8273,6 +8287,14 @@ static const struct hda_fixup alc269_fixups[] = {
|
|||
{ }
|
||||
},
|
||||
},
|
||||
[ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = {
|
||||
.type = HDA_FIXUP_VERBS,
|
||||
.v.verbs = (const struct hda_verb[]) {
|
||||
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x08},
|
||||
{ 0x20, AC_VERB_SET_PROC_COEF, 0x2fcf},
|
||||
{ }
|
||||
},
|
||||
},
|
||||
[ALC295_FIXUP_ASUS_MIC_NO_PRESENCE] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
|
@ -8750,6 +8772,20 @@ static const struct hda_fixup alc269_fixups[] = {
|
|||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = cs35l41_fixup_i2c_two,
|
||||
},
|
||||
[ALC245_FIXUP_CS35L41_SPI_2] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = cs35l41_fixup_spi_two,
|
||||
},
|
||||
[ALC245_FIXUP_CS35L41_SPI_4] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = cs35l41_fixup_spi_four,
|
||||
},
|
||||
[ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = cs35l41_fixup_spi_four,
|
||||
.chained = true,
|
||||
.chain_id = ALC285_FIXUP_HP_GPIO_LED,
|
||||
},
|
||||
[ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED] = {
|
||||
.type = HDA_FIXUP_VERBS,
|
||||
.v.verbs = (const struct hda_verb[]) {
|
||||
|
@ -8977,7 +9013,25 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
|
||||
SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x89c3, "HP", ALC285_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8972, "HP EliteBook 840 G9", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8973, "HP EliteBook 860 G9", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8974, "HP EliteBook 840 Aero G9", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8975, "HP EliteBook x360 840 Aero G9", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8981, "HP Elite Dragonfly G3", ALC245_FIXUP_CS35L41_SPI_4),
|
||||
SND_PCI_QUIRK(0x103c, 0x898e, "HP EliteBook 835 G9", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x898f, "HP EliteBook 835 G9", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8991, "HP EliteBook 845 G9", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8992, "HP EliteBook 845 G9", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8994, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8995, "HP EliteBook 855 G9", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x89a4, "HP ProBook 440 G9", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x89a6, "HP ProBook 450 G9", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x89ac, "HP EliteBook 640 G9", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x89ae, "HP EliteBook 650 G9", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
|
||||
|
@ -9020,6 +9074,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x16b2, "ASUS GU603", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
|
||||
SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
|
||||
|
@ -9053,6 +9108,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
|
||||
SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
|
||||
SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
|
||||
SND_PCI_QUIRK(0x144d, 0xc832, "Samsung Galaxy Book Flex Alpha (NP730QCJ)", ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
|
||||
SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
|
||||
|
@ -9103,6 +9159,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x1558, 0x8561, "Clevo NH[57][0-9][ER][ACDH]Q", ALC269_FIXUP_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1558, 0x8562, "Clevo NH[57][0-9]RZ[Q]", ALC269_FIXUP_DMIC),
|
||||
SND_PCI_QUIRK(0x1558, 0x8668, "Clevo NP50B[BE]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1558, 0x866d, "Clevo NP5[05]PN[HJK]", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1558, 0x867d, "Clevo NP7[01]PN[HJK]", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1558, 0x8680, "Clevo NJ50LU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1558, 0x8686, "Clevo NH50[CZ]U", ALC256_FIXUP_MIC_NO_PRESENCE_AND_RESUME),
|
||||
SND_PCI_QUIRK(0x1558, 0x8a20, "Clevo NH55DCQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
|
||||
|
@ -9397,6 +9455,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
|
|||
{.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
|
||||
{.id = ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, .name = "alc256-medion-headset"},
|
||||
{.id = ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, .name = "alc298-samsung-headphone"},
|
||||
{.id = ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, .name = "alc256-samsung-headphone"},
|
||||
{.id = ALC255_FIXUP_XIAOMI_HEADSET_MIC, .name = "alc255-xiaomi-headset"},
|
||||
{.id = ALC274_FIXUP_HP_MIC, .name = "alc274-hp-mic-detect"},
|
||||
{.id = ALC245_FIXUP_HP_X360_AMP, .name = "alc245-hp-x360-amp"},
|
||||
|
@ -11067,6 +11126,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
|
||||
SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2),
|
||||
SND_PCI_QUIRK(0x103c, 0x885f, "HP 288 Pro G8", ALC671_FIXUP_HP_HEADSET_MIC2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
|
||||
SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
|
||||
SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue