mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-29 10:01:25 +00:00
sound updates for 5.13
No surprises in this development cycle, and most of works are about the fixes and the improvements of the existing code, while a new LED control layer and a few new drivers have been introduced. Here are some highlights: Core: - A common mute-LED framework was introduced; used by HD-audio for now, more adaption will follow later. The former "Mic Mute-LED Mode" mixer control has been replaced with the corresponding sysfs now. - User-control management was changed to count consumed bytes instead of capping by number of elements; this will allow more controls in the normal usage pattern while avoiding the possible memory exhaustion DoS ASoC: - Continued refactoring and cleanups in ASoC core and generic card drivers - Wide range of small cppcheck and warning fixes - New drivers for Freescale i.MX DMA over rpmsg, Mediatek MT6358 accessory detection, and Realtek RT1019, RT1316, RT711 and RT715 USB-audio: - Continued improvements and fixes of the implicit feedback mode, including better support for Pioneer and Roland/BOSS devices HD-audio: - Default back to non-buffer preallocation on x86 - Cirrus codec improvements, more quirks for Realtek codecs Others: - New virtio sound driver - FireWire Bebob updates Note that this PR includes a couple of changes in reset and SPI drivers, too, and some merge conflicts might happen. -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmCMJaAOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE/T6A//Ti0SAWYnAr5l/7ccuwS4zljHcuHngwvIxRPY BokU1ZUlagi+Ro2HLUq13G8T4AlUAQ8r2ecz7EJQHHl9tkrIg7Cc0+fiBPHju1Yu 0F3Vjc78/JsJHvAR2DPll2rwhsdD3usSQXFo181k38J098X02iNcrzsj3kW5Bpzb DBvXzOBIAg/PPfPa4edSYsSurqYeZTkhshedTohlwOCnVbW9NN5b5T9yoXP+t5na rvK1Vhu0He8nVMBPDrzjKgE5rjm7Kn0FNXZ6CMDekU9sRVzm/PbgAqqmRnn6bUKa GDpcQzlaiDrw8a7/uTVgUZy85F9kMXMMnfYpBy4bBXOt6RWOplXY1yMxy1RXV+op 3qC9k5R+IsjSWFQZ2z5bIHtGBNCG0698z9fQcvpsWTv+R68rUyfj+jeO/G9zzvpi qpQTloBfI28NoP+iGis7wtrlQ15ut47YMCQS8QiOEvLmd5/3xKXRut4Ac/VmvDpS q7fLivL8MZ/SMoXY74q/kByMBkXNpryQCAN+xAslaJ5P0aefNYJJdBt/sJlsDd9J Ya2VIxHoP+Sb1MG6OLq1Y8c53Di9lwY80pOtF3plcz/ZWgzipirf6BhFj0OttiKP a6+VewXA7zZcWEdw+Ik4dWP2dybWL+CuNl7Bwug8SyG9iWqg8Ph7FgoCTWAi93Fx KKUJxsc= =YT3U -----END PGP SIGNATURE----- Merge tag 'sound-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound updates from Takashi Iwai: "No surprises in this development cycle, and most of work is about the fixes and the improvements of the existing code, while a new LED control layer and a few new drivers have been introduced. Here are some highlights: Core: - A common mute-LED framework was introduced. It is used by HD-audio for now, more adaption will follow later. The former "Mic Mute-LED Mode" mixer control has been replaced with the corresponding sysfs now. - User-control management was changed to count consumed bytes instead of capping by number of elements; this will allow more controls in the normal usage pattern while avoiding the possible memory exhaustion DoS ASoC: - Continued refactoring and cleanups in ASoC core and generic card drivers - Wide range of small cppcheck and warning fixes - New drivers for Freescale i.MX DMA over rpmsg, Mediatek MT6358 accessory detection, and Realtek RT1019, RT1316, RT711 and RT715 USB-audio: - Continued improvements and fixes of the implicit feedback mode, including better support for Pioneer and Roland/BOSS devices HD-audio: - Default back to non-buffer preallocation on x86 - Cirrus codec improvements, more quirks for Realtek codecs Others: - New virtio sound driver - FireWire Bebob updates" * tag 'sound-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (587 commits) ALSA: hda/conexant: Re-order CX5066 quirk table entries ALSA: hda/realtek: Remove redundant entry for ALC861 Haier/Uniwill devices ALSA: hda/realtek: Re-order ALC662 quirk table entries ALSA: hda/realtek: Re-order remaining ALC269 quirk table entries ALSA: hda/realtek: Re-order ALC269 Lenovo quirk table entries ALSA: hda/realtek: Re-order ALC269 Sony quirk table entries ALSA: hda/realtek: Re-order ALC269 ASUS quirk table entries ALSA: hda/realtek: Re-order ALC269 Dell quirk table entries ALSA: hda/realtek: Re-order ALC269 Acer quirk table entries ALSA: hda/realtek: Re-order ALC269 HP quirk table entries ALSA: hda/realtek: Re-order ALC882 Clevo quirk table entries ALSA: hda/realtek: Re-order ALC882 Sony quirk table entries ALSA: hda/realtek: Re-order ALC882 Acer quirk table entries ALSA: usb-audio: Remove redundant assignment to len ALSA: hda/realtek: Add quirk for Intel Clevo PCx0Dx ALSA: virtio: fix kernel-doc ALSA: hda/cirrus: Use CS8409 filter to fix abnormal sounds on Bullseye ALSA: hda/cirrus: Set Initial DMIC volume for Bullseye to -26 dB ALSA: sb: Fix two use after free in snd_sb_qsound_build ALSA: emu8000: Fix a use after free in snd_emu8000_create_mixer ...
This commit is contained in:
commit
b71428d7ab
420 changed files with 23480 additions and 4048 deletions
|
@ -4,7 +4,7 @@ This device supports I2C mode only.
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
|
|
||||||
- compatible : "asahi-kasei,ak5558"
|
- compatible : "asahi-kasei,ak5558" or "asahi-kasei,ak5552".
|
||||||
- reg : The I2C address of the device.
|
- reg : The I2C address of the device.
|
||||||
|
|
||||||
Optional properties:
|
Optional properties:
|
||||||
|
|
|
@ -11,71 +11,59 @@ maintainers:
|
||||||
|
|
||||||
select: false
|
select: false
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: /schemas/graph.yaml#/$defs/port-base
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
port:
|
prefix:
|
||||||
description: single OF-Graph subnode
|
description: "device name prefix"
|
||||||
type: object
|
$ref: /schemas/types.yaml#/definitions/string
|
||||||
|
convert-rate:
|
||||||
|
description: CPU to Codec rate convert.
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
convert-channels:
|
||||||
|
description: CPU to Codec rate channels.
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
patternProperties:
|
||||||
|
"^endpoint(@[0-9a-f]+)?":
|
||||||
|
$ref: /schemas/graph.yaml#/$defs/endpoint-base
|
||||||
properties:
|
properties:
|
||||||
reg:
|
mclk-fs:
|
||||||
maxItems: 1
|
description: |
|
||||||
prefix:
|
Multiplication factor between stream rate and codec mclk.
|
||||||
description: "device name prefix"
|
When defined, mclk-fs property defined in dai-link sub nodes are
|
||||||
$ref: /schemas/types.yaml#/definitions/string
|
ignored.
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
|
frame-inversion:
|
||||||
|
description: dai-link uses frame clock inversion
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
bitclock-inversion:
|
||||||
|
description: dai-link uses bit clock inversion
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
frame-master:
|
||||||
|
description: Indicates dai-link frame master.
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
bitclock-master:
|
||||||
|
description: Indicates dai-link bit clock master
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
dai-format:
|
||||||
|
description: audio format.
|
||||||
|
items:
|
||||||
|
enum:
|
||||||
|
- i2s
|
||||||
|
- right_j
|
||||||
|
- left_j
|
||||||
|
- dsp_a
|
||||||
|
- dsp_b
|
||||||
|
- ac97
|
||||||
|
- pdm
|
||||||
|
- msb
|
||||||
|
- lsb
|
||||||
convert-rate:
|
convert-rate:
|
||||||
description: CPU to Codec rate convert.
|
description: CPU to Codec rate convert.
|
||||||
$ref: /schemas/types.yaml#/definitions/uint32
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
convert-channels:
|
convert-channels:
|
||||||
description: CPU to Codec rate channels.
|
description: CPU to Codec rate channels.
|
||||||
$ref: /schemas/types.yaml#/definitions/uint32
|
$ref: /schemas/types.yaml#/definitions/uint32
|
||||||
patternProperties:
|
|
||||||
"^endpoint(@[0-9a-f]+)?":
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
remote-endpoint:
|
|
||||||
maxItems: 1
|
|
||||||
mclk-fs:
|
|
||||||
description: |
|
|
||||||
Multiplication factor between stream rate and codec mclk.
|
|
||||||
When defined, mclk-fs property defined in dai-link sub nodes are
|
|
||||||
ignored.
|
|
||||||
$ref: /schemas/types.yaml#/definitions/uint32
|
|
||||||
frame-inversion:
|
|
||||||
description: dai-link uses frame clock inversion
|
|
||||||
$ref: /schemas/types.yaml#/definitions/flag
|
|
||||||
bitclock-inversion:
|
|
||||||
description: dai-link uses bit clock inversion
|
|
||||||
$ref: /schemas/types.yaml#/definitions/flag
|
|
||||||
frame-master:
|
|
||||||
description: Indicates dai-link frame master.
|
|
||||||
$ref: /schemas/types.yaml#/definitions/phandle
|
|
||||||
bitclock-master:
|
|
||||||
description: Indicates dai-link bit clock master
|
|
||||||
$ref: /schemas/types.yaml#/definitions/phandle
|
|
||||||
dai-format:
|
|
||||||
description: audio format.
|
|
||||||
items:
|
|
||||||
enum:
|
|
||||||
- i2s
|
|
||||||
- right_j
|
|
||||||
- left_j
|
|
||||||
- dsp_a
|
|
||||||
- dsp_b
|
|
||||||
- ac97
|
|
||||||
- pdm
|
|
||||||
- msb
|
|
||||||
- lsb
|
|
||||||
convert-rate:
|
|
||||||
description: CPU to Codec rate convert.
|
|
||||||
$ref: /schemas/types.yaml#/definitions/uint32
|
|
||||||
convert-channels:
|
|
||||||
description: CPU to Codec rate channels.
|
|
||||||
$ref: /schemas/types.yaml#/definitions/uint32
|
|
||||||
|
|
||||||
ports:
|
|
||||||
description: multi OF-Graph subnode
|
|
||||||
type: object
|
|
||||||
patternProperties:
|
|
||||||
"^port(@[0-9a-f]+)?":
|
|
||||||
$ref: "#/properties/port"
|
|
||||||
|
|
||||||
additionalProperties: true
|
additionalProperties: true
|
||||||
|
|
108
Documentation/devicetree/bindings/sound/fsl,rpmsg.yaml
Normal file
108
Documentation/devicetree/bindings/sound/fsl,rpmsg.yaml
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/sound/fsl,rpmsg.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: NXP Audio RPMSG CPU DAI Controller
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Shengjiu Wang <shengjiu.wang@nxp.com>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
fsl_rpmsg is a virtual audio device. Mapping to real hardware devices
|
||||||
|
are SAI, DMA controlled by Cortex M core. What we see from Linux
|
||||||
|
side is a device which provides audio service by rpmsg channel.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- fsl,imx7ulp-rpmsg-audio
|
||||||
|
- fsl,imx8mn-rpmsg-audio
|
||||||
|
- fsl,imx8mm-rpmsg-audio
|
||||||
|
- fsl,imx8mp-rpmsg-audio
|
||||||
|
|
||||||
|
model:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/string
|
||||||
|
description: User specified audio sound card name
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
items:
|
||||||
|
- description: Peripheral clock for register access
|
||||||
|
- description: Master clock
|
||||||
|
- description: DMA clock for DMA register access
|
||||||
|
- description: Parent clock for multiple of 8kHz sample rates
|
||||||
|
- description: Parent clock for multiple of 11kHz sample rates
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
items:
|
||||||
|
- const: ipg
|
||||||
|
- const: mclk
|
||||||
|
- const: dma
|
||||||
|
- const: pll8k
|
||||||
|
- const: pll11k
|
||||||
|
|
||||||
|
power-domains:
|
||||||
|
description:
|
||||||
|
List of phandle and PM domain specifier as documented in
|
||||||
|
Documentation/devicetree/bindings/power/power_domain.txt
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
memory-region:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description:
|
||||||
|
phandle to a node describing reserved memory (System RAM memory)
|
||||||
|
The M core can't access all the DDR memory space on some platform,
|
||||||
|
So reserved a specific memory for dma buffer which M core can
|
||||||
|
access.
|
||||||
|
(see bindings/reserved-memory/reserved-memory.txt)
|
||||||
|
|
||||||
|
audio-codec:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description: The phandle to a node of audio codec
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
fsl,enable-lpa:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
description: enable low power audio path.
|
||||||
|
|
||||||
|
fsl,rpmsg-out:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
description: |
|
||||||
|
This is a boolean property. If present, the transmitting function
|
||||||
|
will be enabled.
|
||||||
|
|
||||||
|
fsl,rpmsg-in:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
description: |
|
||||||
|
This is a boolean property. If present, the receiving function
|
||||||
|
will be enabled.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- model
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/clock/imx8mn-clock.h>
|
||||||
|
|
||||||
|
rpmsg_audio: rpmsg_audio {
|
||||||
|
compatible = "fsl,imx8mn-rpmsg-audio";
|
||||||
|
model = "wm8524-audio";
|
||||||
|
fsl,enable-lpa;
|
||||||
|
fsl,rpmsg-out;
|
||||||
|
clocks = <&clk IMX8MN_CLK_SAI3_IPG>,
|
||||||
|
<&clk IMX8MN_CLK_SAI3_ROOT>,
|
||||||
|
<&clk IMX8MN_CLK_SDMA3_ROOT>,
|
||||||
|
<&clk IMX8MN_AUDIO_PLL1_OUT>,
|
||||||
|
<&clk IMX8MN_AUDIO_PLL2_OUT>;
|
||||||
|
clock-names = "ipg", "mclk", "dma", "pll8k", "pll11k";
|
||||||
|
};
|
|
@ -42,6 +42,8 @@ The compatible list for this generic sound card currently:
|
||||||
|
|
||||||
"fsl,imx-audio-si476x"
|
"fsl,imx-audio-si476x"
|
||||||
|
|
||||||
|
"fsl,imx-audio-wm8958"
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
|
|
||||||
- compatible : Contains one of entries in the compatible list.
|
- compatible : Contains one of entries in the compatible list.
|
||||||
|
|
|
@ -81,6 +81,6 @@ examples:
|
||||||
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
clock-names = "osc", "apb_clk";
|
clock-names = "osc", "apb_clk";
|
||||||
clocks = <&scmi_clk KEEM_BAY_PSS_AUX_I2S3>, <&scmi_clk KEEM_BAY_PSS_I2S3>;
|
clocks = <&scmi_clk KEEM_BAY_PSS_AUX_I2S3>, <&scmi_clk KEEM_BAY_PSS_I2S3>;
|
||||||
dmas = <&axi_dma0 29 &axi_dma0 33>;
|
dmas = <&axi_dma0 29>, <&axi_dma0 33>;
|
||||||
dma-names = "tx", "rx";
|
dma-names = "tx", "rx";
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,9 +9,6 @@ title: Marvel SSPA Digital Audio Interface Bindings
|
||||||
maintainers:
|
maintainers:
|
||||||
- Lubomir Rintel <lkundrak@v3.sk>
|
- Lubomir Rintel <lkundrak@v3.sk>
|
||||||
|
|
||||||
allOf:
|
|
||||||
- $ref: audio-graph-port.yaml#
|
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^audio-controller(@.*)?$"
|
pattern: "^audio-controller(@.*)?$"
|
||||||
|
@ -54,7 +51,8 @@ properties:
|
||||||
- const: rx
|
- const: rx
|
||||||
|
|
||||||
port:
|
port:
|
||||||
type: object
|
$ref: audio-graph-port.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
endpoint:
|
endpoint:
|
||||||
|
|
108
Documentation/devicetree/bindings/sound/mchp,i2s-mcc.yaml
Normal file
108
Documentation/devicetree/bindings/sound/mchp,i2s-mcc.yaml
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/sound/mchp,i2s-mcc.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Microchip I2S Multi-Channel Controller
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
|
||||||
|
|
||||||
|
description:
|
||||||
|
The I2SMCC complies with the Inter-IC Sound (I2S) bus specification and
|
||||||
|
supports a Time Division Multiplexed (TDM) interface with external
|
||||||
|
multi-channel audio codecs. It consists of a receiver, a transmitter and a
|
||||||
|
common clock generator that can be enabled separately to provide Adapter,
|
||||||
|
Client or Controller modes with receiver and/or transmitter active.
|
||||||
|
On later I2SMCC versions (starting with Microchip's SAMA7G5) I2S
|
||||||
|
multi-channel is supported by using multiple data pins, output and
|
||||||
|
input, without TDM.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
"#sound-dai-cells":
|
||||||
|
const: 0
|
||||||
|
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- microchip,sam9x60-i2smcc
|
||||||
|
- microchip,sama7g5-i2smcc
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
interrupts:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
items:
|
||||||
|
- description: Peripheral Bus Clock
|
||||||
|
- description: Generic Clock (Optional). Should be set mostly when Master
|
||||||
|
Mode is required.
|
||||||
|
minItems: 1
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
items:
|
||||||
|
- const: pclk
|
||||||
|
- const: gclk
|
||||||
|
minItems: 1
|
||||||
|
|
||||||
|
dmas:
|
||||||
|
items:
|
||||||
|
- description: TX DMA Channel
|
||||||
|
- description: RX DMA Channel
|
||||||
|
|
||||||
|
dma-names:
|
||||||
|
items:
|
||||||
|
- const: tx
|
||||||
|
- const: rx
|
||||||
|
|
||||||
|
microchip,tdm-data-pair:
|
||||||
|
description:
|
||||||
|
Represents the DIN/DOUT pair pins that are used to receive/send
|
||||||
|
TDM data. It is optional and it is only needed if the controller
|
||||||
|
uses the TDM mode.
|
||||||
|
$ref: /schemas/types.yaml#/definitions/uint8
|
||||||
|
enum: [0, 1, 2, 3]
|
||||||
|
default: 0
|
||||||
|
|
||||||
|
if:
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: microchip,sam9x60-i2smcc
|
||||||
|
then:
|
||||||
|
properties:
|
||||||
|
microchip,tdm-data-pair: false
|
||||||
|
|
||||||
|
required:
|
||||||
|
- "#sound-dai-cells"
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- interrupts
|
||||||
|
- clocks
|
||||||
|
- clock-names
|
||||||
|
- dmas
|
||||||
|
- dma-names
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/dma/at91.h>
|
||||||
|
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||||
|
|
||||||
|
i2s@f001c000 {
|
||||||
|
#sound-dai-cells = <0>;
|
||||||
|
compatible = "microchip,sam9x60-i2smcc";
|
||||||
|
reg = <0xf001c000 0x100>;
|
||||||
|
interrupts = <34 IRQ_TYPE_LEVEL_HIGH 7>;
|
||||||
|
dmas = <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
|
||||||
|
AT91_XDMAC_DT_PERID(36))>,
|
||||||
|
<&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
|
||||||
|
AT91_XDMAC_DT_PERID(37))>;
|
||||||
|
dma-names = "tx", "rx";
|
||||||
|
clocks = <&i2s_clk>, <&i2s_gclk>;
|
||||||
|
clock-names = "pclk", "gclk";
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&pinctrl_i2s_default>;
|
||||||
|
};
|
|
@ -1,43 +0,0 @@
|
||||||
* Microchip I2S Multi-Channel Controller
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible: Should be "microchip,sam9x60-i2smcc".
|
|
||||||
- reg: Should be the physical base address of the controller and the
|
|
||||||
length of memory mapped region.
|
|
||||||
- interrupts: Should contain the interrupt for the controller.
|
|
||||||
- dmas: Should be one per channel name listed in the dma-names property,
|
|
||||||
as described in atmel-dma.txt and dma.txt files.
|
|
||||||
- dma-names: Identifier string for each DMA request line in the dmas property.
|
|
||||||
Two dmas have to be defined, "tx" and "rx".
|
|
||||||
- clocks: Must contain an entry for each entry in clock-names.
|
|
||||||
Please refer to clock-bindings.txt.
|
|
||||||
- clock-names: Should be one of each entry matching the clocks phandles list:
|
|
||||||
- "pclk" (peripheral clock) Required.
|
|
||||||
- "gclk" (generated clock) Optional (1).
|
|
||||||
|
|
||||||
Optional properties:
|
|
||||||
- pinctrl-0: Should specify pin control groups used for this controller.
|
|
||||||
- princtrl-names: Should contain only one value - "default".
|
|
||||||
|
|
||||||
|
|
||||||
(1) : Only the peripheral clock is required. The generated clock is optional
|
|
||||||
and should be set mostly when Master Mode is required.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
i2s@f001c000 {
|
|
||||||
compatible = "microchip,sam9x60-i2smcc";
|
|
||||||
reg = <0xf001c000 0x100>;
|
|
||||||
interrupts = <34 IRQ_TYPE_LEVEL_HIGH 7>;
|
|
||||||
dmas = <&dma0
|
|
||||||
(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
|
|
||||||
AT91_XDMAC_DT_PERID(36))>,
|
|
||||||
<&dma0
|
|
||||||
(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
|
|
||||||
AT91_XDMAC_DT_PERID(37))>;
|
|
||||||
dma-names = "tx", "rx";
|
|
||||||
clocks = <&i2s_clk>, <&i2s_gclk>;
|
|
||||||
clock-names = "pclk", "gclk";
|
|
||||||
pinctrl-names = "default";
|
|
||||||
pinctrl-0 = <&pinctrl_i2s_default>;
|
|
||||||
};
|
|
|
@ -4,6 +4,7 @@ Required properties:
|
||||||
- compatible : "mediatek,mt8183_mt6358_ts3a227_max98357" for MAX98357A codec
|
- compatible : "mediatek,mt8183_mt6358_ts3a227_max98357" for MAX98357A codec
|
||||||
"mediatek,mt8183_mt6358_ts3a227_max98357b" for MAX98357B codec
|
"mediatek,mt8183_mt6358_ts3a227_max98357b" for MAX98357B codec
|
||||||
"mediatek,mt8183_mt6358_ts3a227_rt1015" for RT1015 codec
|
"mediatek,mt8183_mt6358_ts3a227_rt1015" for RT1015 codec
|
||||||
|
"mediatek,mt8183_mt6358_ts3a227_rt1015p" for RT1015P codec
|
||||||
- mediatek,platform: the phandle of MT8183 ASoC platform
|
- mediatek,platform: the phandle of MT8183 ASoC platform
|
||||||
|
|
||||||
Optional properties:
|
Optional properties:
|
||||||
|
|
|
@ -17,9 +17,6 @@ maintainers:
|
||||||
- Jon Hunter <jonathanh@nvidia.com>
|
- Jon Hunter <jonathanh@nvidia.com>
|
||||||
- Sameer Pujar <spujar@nvidia.com>
|
- Sameer Pujar <spujar@nvidia.com>
|
||||||
|
|
||||||
allOf:
|
|
||||||
- $ref: audio-graph-port.yaml#
|
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^dspk@[0-9a-f]*$"
|
pattern: "^dspk@[0-9a-f]*$"
|
||||||
|
@ -59,14 +56,18 @@ properties:
|
||||||
available instances on a Tegra SoC.
|
available instances on a Tegra SoC.
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
type: object
|
$ref: /schemas/graph.yaml#/properties/ports
|
||||||
properties:
|
properties:
|
||||||
port@0:
|
port@0:
|
||||||
|
$ref: audio-graph-port.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
description: |
|
description: |
|
||||||
DSPK ACIF (Audio Client Interface) port connected to the
|
DSPK ACIF (Audio Client Interface) port connected to the
|
||||||
corresponding AHUB (Audio Hub) ACIF port.
|
corresponding AHUB (Audio Hub) ACIF port.
|
||||||
|
|
||||||
port@1:
|
port@1:
|
||||||
|
$ref: audio-graph-port.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
description: |
|
description: |
|
||||||
DSPK DAP (Digital Audio Port) interface which can be connected
|
DSPK DAP (Digital Audio Port) interface which can be connected
|
||||||
to external audio codec for playback.
|
to external audio codec for playback.
|
||||||
|
@ -80,7 +81,7 @@ required:
|
||||||
- assigned-clock-parents
|
- assigned-clock-parents
|
||||||
- sound-name-prefix
|
- sound-name-prefix
|
||||||
|
|
||||||
unevaluatedProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
|
|
|
@ -17,9 +17,6 @@ maintainers:
|
||||||
- Jon Hunter <jonathanh@nvidia.com>
|
- Jon Hunter <jonathanh@nvidia.com>
|
||||||
- Sameer Pujar <spujar@nvidia.com>
|
- Sameer Pujar <spujar@nvidia.com>
|
||||||
|
|
||||||
allOf:
|
|
||||||
- $ref: audio-graph-port.yaml#
|
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^admaif@[0-9a-f]*$"
|
pattern: "^admaif@[0-9a-f]*$"
|
||||||
|
@ -41,6 +38,7 @@ properties:
|
||||||
dma-names: true
|
dma-names: true
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
|
$ref: /schemas/graph.yaml#/properties/ports
|
||||||
description: |
|
description: |
|
||||||
Contains list of ACIF (Audio CIF) port nodes for ADMAIF channels.
|
Contains list of ACIF (Audio CIF) port nodes for ADMAIF channels.
|
||||||
The number of port nodes depends on the number of ADMAIF channels
|
The number of port nodes depends on the number of ADMAIF channels
|
||||||
|
@ -48,6 +46,11 @@ properties:
|
||||||
in AHUB (Audio Hub). Each port is capable of data transfers in
|
in AHUB (Audio Hub). Each port is capable of data transfers in
|
||||||
both directions.
|
both directions.
|
||||||
|
|
||||||
|
patternProperties:
|
||||||
|
'^port@[0-9]':
|
||||||
|
$ref: audio-graph-port.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
if:
|
if:
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
|
@ -92,7 +95,7 @@ required:
|
||||||
- dmas
|
- dmas
|
||||||
- dma-names
|
- dma-names
|
||||||
|
|
||||||
unevaluatedProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
|
|
|
@ -17,9 +17,6 @@ maintainers:
|
||||||
- Jon Hunter <jonathanh@nvidia.com>
|
- Jon Hunter <jonathanh@nvidia.com>
|
||||||
- Sameer Pujar <spujar@nvidia.com>
|
- Sameer Pujar <spujar@nvidia.com>
|
||||||
|
|
||||||
allOf:
|
|
||||||
- $ref: audio-graph-port.yaml#
|
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^ahub@[0-9a-f]*$"
|
pattern: "^ahub@[0-9a-f]*$"
|
||||||
|
@ -60,12 +57,34 @@ properties:
|
||||||
ranges: true
|
ranges: true
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
|
$ref: /schemas/graph.yaml#/properties/ports
|
||||||
description: |
|
description: |
|
||||||
Contains list of ACIF (Audio CIF) port nodes for AHUB (Audio Hub).
|
Contains list of ACIF (Audio CIF) port nodes for AHUB (Audio Hub).
|
||||||
These are connected to ACIF interfaces of AHUB clients. Thus the
|
These are connected to ACIF interfaces of AHUB clients. Thus the
|
||||||
number of port nodes depend on the number of clients that AHUB may
|
number of port nodes depend on the number of clients that AHUB may
|
||||||
have depending on the SoC revision.
|
have depending on the SoC revision.
|
||||||
|
|
||||||
|
patternProperties:
|
||||||
|
'^port@[0-9]':
|
||||||
|
$ref: audio-graph-port.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
|
patternProperties:
|
||||||
|
'^i2s@[0-9a-f]+$':
|
||||||
|
type: object
|
||||||
|
|
||||||
|
'^dmic@[0-9a-f]+$':
|
||||||
|
type: object
|
||||||
|
$ref: nvidia,tegra210-dmic.yaml#
|
||||||
|
|
||||||
|
'^admaif@[0-9a-f]+$':
|
||||||
|
type: object
|
||||||
|
$ref: nvidia,tegra210-admaif.yaml#
|
||||||
|
|
||||||
|
'^dspk@[0-9a-f]+$':
|
||||||
|
type: object
|
||||||
|
$ref: nvidia,tegra186-dspk.yaml#
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- reg
|
- reg
|
||||||
|
@ -77,7 +96,7 @@ required:
|
||||||
- "#size-cells"
|
- "#size-cells"
|
||||||
- ranges
|
- ranges
|
||||||
|
|
||||||
unevaluatedProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
|
|
|
@ -16,9 +16,6 @@ maintainers:
|
||||||
- Jon Hunter <jonathanh@nvidia.com>
|
- Jon Hunter <jonathanh@nvidia.com>
|
||||||
- Sameer Pujar <spujar@nvidia.com>
|
- Sameer Pujar <spujar@nvidia.com>
|
||||||
|
|
||||||
allOf:
|
|
||||||
- $ref: audio-graph-port.yaml#
|
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^dmic@[0-9a-f]*$"
|
pattern: "^dmic@[0-9a-f]*$"
|
||||||
|
@ -60,14 +57,18 @@ properties:
|
||||||
on the maximum available instances on a Tegra SoC.
|
on the maximum available instances on a Tegra SoC.
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
type: object
|
$ref: /schemas/graph.yaml#/properties/ports
|
||||||
properties:
|
properties:
|
||||||
port@0:
|
port@0:
|
||||||
|
$ref: audio-graph-port.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
description: |
|
description: |
|
||||||
DMIC ACIF (Audio Client Interface) port connected to the
|
DMIC ACIF (Audio Client Interface) port connected to the
|
||||||
corresponding AHUB (Audio Hub) ACIF port.
|
corresponding AHUB (Audio Hub) ACIF port.
|
||||||
|
|
||||||
port@1:
|
port@1:
|
||||||
|
$ref: audio-graph-port.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
description: |
|
description: |
|
||||||
DMIC DAP (Digital Audio Port) interface which can be connected
|
DMIC DAP (Digital Audio Port) interface which can be connected
|
||||||
to external audio codec for capture.
|
to external audio codec for capture.
|
||||||
|
@ -80,7 +81,7 @@ required:
|
||||||
- assigned-clocks
|
- assigned-clocks
|
||||||
- assigned-clock-parents
|
- assigned-clock-parents
|
||||||
|
|
||||||
unevaluatedProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
|
|
|
@ -16,9 +16,6 @@ maintainers:
|
||||||
- Jon Hunter <jonathanh@nvidia.com>
|
- Jon Hunter <jonathanh@nvidia.com>
|
||||||
- Sameer Pujar <spujar@nvidia.com>
|
- Sameer Pujar <spujar@nvidia.com>
|
||||||
|
|
||||||
allOf:
|
|
||||||
- $ref: audio-graph-port.yaml#
|
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
$nodename:
|
$nodename:
|
||||||
pattern: "^i2s@[0-9a-f]*$"
|
pattern: "^i2s@[0-9a-f]*$"
|
||||||
|
@ -78,14 +75,18 @@ properties:
|
||||||
on the maximum available instances on a Tegra SoC.
|
on the maximum available instances on a Tegra SoC.
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
type: object
|
$ref: /schemas/graph.yaml#/properties/ports
|
||||||
properties:
|
properties:
|
||||||
port@0:
|
port@0:
|
||||||
|
$ref: audio-graph-port.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
description: |
|
description: |
|
||||||
I2S ACIF (Audio Client Interface) port connected to the
|
I2S ACIF (Audio Client Interface) port connected to the
|
||||||
corresponding AHUB (Audio Hub) ACIF port.
|
corresponding AHUB (Audio Hub) ACIF port.
|
||||||
|
|
||||||
port@1:
|
port@1:
|
||||||
|
$ref: audio-graph-port.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
description: |
|
description: |
|
||||||
I2S DAP (Digital Audio Port) interface which can be connected
|
I2S DAP (Digital Audio Port) interface which can be connected
|
||||||
to external audio codec for playback or capture.
|
to external audio codec for playback or capture.
|
||||||
|
@ -98,7 +99,7 @@ required:
|
||||||
- assigned-clocks
|
- assigned-clocks
|
||||||
- assigned-clock-parents
|
- assigned-clock-parents
|
||||||
|
|
||||||
unevaluatedProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
|
|
|
@ -110,7 +110,9 @@ properties:
|
||||||
- pattern: '^dvc\.[0-1]$'
|
- pattern: '^dvc\.[0-1]$'
|
||||||
- pattern: '^clk_(a|b|c|i)$'
|
- pattern: '^clk_(a|b|c|i)$'
|
||||||
|
|
||||||
port: true
|
port:
|
||||||
|
$ref: audio-graph-port.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
# use patternProperties to avoid naming "xxx,yyy" issue
|
# use patternProperties to avoid naming "xxx,yyy" issue
|
||||||
patternProperties:
|
patternProperties:
|
||||||
|
@ -256,7 +258,6 @@ required:
|
||||||
|
|
||||||
allOf:
|
allOf:
|
||||||
- $ref: audio-graph.yaml#
|
- $ref: audio-graph.yaml#
|
||||||
- $ref: audio-graph-port.yaml#
|
|
||||||
- if:
|
- if:
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
|
|
35
Documentation/devicetree/bindings/sound/rt1019.yaml
Normal file
35
Documentation/devicetree/bindings/sound/rt1019.yaml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/sound/rt1019.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: RT1019 Mono Class-D Audio Amplifier
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- jack.yu@realtek.com
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: realtek,rt1019
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
description: I2C address of the device.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
i2c {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
rt1019: codec@28 {
|
||||||
|
compatible = "realtek,rt1019";
|
||||||
|
reg = <0x28>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -44,7 +44,7 @@ Optional properties:
|
||||||
- realtek,dmic-delay-ms : Set the delay time (ms) for the requirement of
|
- realtek,dmic-delay-ms : Set the delay time (ms) for the requirement of
|
||||||
the particular DMIC.
|
the particular DMIC.
|
||||||
|
|
||||||
- realtek,dmic-clk-driving-high : Set the high drving of the DMIC clock out.
|
- realtek,dmic-clk-driving-high : Set the high driving of the DMIC clock out.
|
||||||
|
|
||||||
Pins on the device (for linking into audio routes) for RT5682:
|
Pins on the device (for linking into audio routes) for RT5682:
|
||||||
|
|
||||||
|
|
|
@ -46,11 +46,9 @@ properties:
|
||||||
|
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"^port@[0-9]$":
|
"^port@[0-9]$":
|
||||||
type: object
|
description: FIXME, Need to define what each port is.
|
||||||
properties:
|
$ref: audio-graph-port.yaml#
|
||||||
endpoint: true
|
unevaluatedProperties: false
|
||||||
required:
|
|
||||||
- endpoint
|
|
||||||
|
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,9 @@ properties:
|
||||||
|
|
||||||
patternProperties:
|
patternProperties:
|
||||||
"^port@[0-9]$":
|
"^port@[0-9]$":
|
||||||
type: object
|
description: FIXME, Need to define what each port is.
|
||||||
properties:
|
$ref: audio-graph-port.yaml#
|
||||||
endpoint: true
|
unevaluatedProperties: false
|
||||||
required:
|
|
||||||
- endpoint
|
|
||||||
|
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Texas Instruments - tlv320aic3x Codec module
|
Texas Instruments - tlv320aic3x Codec module
|
||||||
|
|
||||||
The tlv320aic3x serial control bus communicates through I2C protocols
|
The tlv320aic3x serial control bus communicates through both I2C and SPI bus protocols
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ CODEC input pins for other compatible codecs:
|
||||||
|
|
||||||
The pins can be used in referring sound node's audio-routing property.
|
The pins can be used in referring sound node's audio-routing property.
|
||||||
|
|
||||||
Example:
|
I2C example:
|
||||||
|
|
||||||
#include <dt-bindings/gpio/gpio.h>
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
|
|
||||||
|
@ -78,3 +78,20 @@ tlv320aic3x: tlv320aic3x@1b {
|
||||||
DRVDD-supply = <®ulator>;
|
DRVDD-supply = <®ulator>;
|
||||||
DVDD-supply = <®ulator>;
|
DVDD-supply = <®ulator>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SPI example:
|
||||||
|
|
||||||
|
spi0: spi@f0000000 {
|
||||||
|
tlv320aic3x: codec@0 {
|
||||||
|
compatible = "ti,tlv320aic3x";
|
||||||
|
reg = <0>; /* CS number */
|
||||||
|
#sound-dai-cells = <0>;
|
||||||
|
spi-max-frequency = <1000000>;
|
||||||
|
|
||||||
|
AVDD-supply = <®ulator>;
|
||||||
|
IOVDD-supply = <®ulator>;
|
||||||
|
DRVDD-supply = <®ulator>;
|
||||||
|
DVDD-supply = <®ulator>;
|
||||||
|
ai3x-ocmv = <0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -19335,6 +19335,15 @@ W: https://virtio-mem.gitlab.io/
|
||||||
F: drivers/virtio/virtio_mem.c
|
F: drivers/virtio/virtio_mem.c
|
||||||
F: include/uapi/linux/virtio_mem.h
|
F: include/uapi/linux/virtio_mem.h
|
||||||
|
|
||||||
|
VIRTIO SOUND DRIVER
|
||||||
|
M: Anton Yakovlev <anton.yakovlev@opensynergy.com>
|
||||||
|
M: "Michael S. Tsirkin" <mst@redhat.com>
|
||||||
|
L: virtualization@lists.linux-foundation.org
|
||||||
|
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||||
|
S: Maintained
|
||||||
|
F: include/uapi/linux/virtio_snd.h
|
||||||
|
F: sound/virtio/*
|
||||||
|
|
||||||
VIRTUAL BOX GUEST DEVICE DRIVER
|
VIRTUAL BOX GUEST DEVICE DRIVER
|
||||||
M: Hans de Goede <hdegoede@redhat.com>
|
M: Hans de Goede <hdegoede@redhat.com>
|
||||||
M: Arnd Bergmann <arnd@arndb.de>
|
M: Arnd Bergmann <arnd@arndb.de>
|
||||||
|
|
|
@ -166,6 +166,7 @@ static int __init dmi_checksum(const u8 *buf, u8 len)
|
||||||
static const char *dmi_ident[DMI_STRING_MAX];
|
static const char *dmi_ident[DMI_STRING_MAX];
|
||||||
static LIST_HEAD(dmi_devices);
|
static LIST_HEAD(dmi_devices);
|
||||||
int dmi_available;
|
int dmi_available;
|
||||||
|
EXPORT_SYMBOL_GPL(dmi_available);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save a DMI string
|
* Save a DMI string
|
||||||
|
|
|
@ -358,6 +358,30 @@ int reset_control_reset(struct reset_control *rstc)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(reset_control_reset);
|
EXPORT_SYMBOL_GPL(reset_control_reset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset_control_bulk_reset - reset the controlled devices in order
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset controls set
|
||||||
|
*
|
||||||
|
* Issue a reset on all provided reset controls, in order.
|
||||||
|
*
|
||||||
|
* See also: reset_control_reset()
|
||||||
|
*/
|
||||||
|
int reset_control_bulk_reset(int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_rstcs; i++) {
|
||||||
|
ret = reset_control_reset(rstcs[i].rstc);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(reset_control_bulk_reset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reset_control_rearm - allow shared reset line to be re-triggered"
|
* reset_control_rearm - allow shared reset line to be re-triggered"
|
||||||
* @rstc: reset controller
|
* @rstc: reset controller
|
||||||
|
@ -461,6 +485,36 @@ int reset_control_assert(struct reset_control *rstc)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(reset_control_assert);
|
EXPORT_SYMBOL_GPL(reset_control_assert);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset_control_bulk_assert - asserts the reset lines in order
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset controls set
|
||||||
|
*
|
||||||
|
* Assert the reset lines for all provided reset controls, in order.
|
||||||
|
* If an assertion fails, already asserted resets are deasserted again.
|
||||||
|
*
|
||||||
|
* See also: reset_control_assert()
|
||||||
|
*/
|
||||||
|
int reset_control_bulk_assert(int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_rstcs; i++) {
|
||||||
|
ret = reset_control_assert(rstcs[i].rstc);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
while (i--)
|
||||||
|
reset_control_deassert(rstcs[i].rstc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(reset_control_bulk_assert);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reset_control_deassert - deasserts the reset line
|
* reset_control_deassert - deasserts the reset line
|
||||||
* @rstc: reset controller
|
* @rstc: reset controller
|
||||||
|
@ -511,6 +565,36 @@ int reset_control_deassert(struct reset_control *rstc)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(reset_control_deassert);
|
EXPORT_SYMBOL_GPL(reset_control_deassert);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset_control_bulk_deassert - deasserts the reset lines in reverse order
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset controls set
|
||||||
|
*
|
||||||
|
* Deassert the reset lines for all provided reset controls, in reverse order.
|
||||||
|
* If a deassertion fails, already deasserted resets are asserted again.
|
||||||
|
*
|
||||||
|
* See also: reset_control_deassert()
|
||||||
|
*/
|
||||||
|
int reset_control_bulk_deassert(int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
for (i = num_rstcs - 1; i >= 0; i--) {
|
||||||
|
ret = reset_control_deassert(rstcs[i].rstc);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
while (i < num_rstcs)
|
||||||
|
reset_control_assert(rstcs[i++].rstc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(reset_control_bulk_deassert);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reset_control_status - returns a negative errno if not supported, a
|
* reset_control_status - returns a negative errno if not supported, a
|
||||||
* positive value if the reset line is asserted, or zero if the reset
|
* positive value if the reset line is asserted, or zero if the reset
|
||||||
|
@ -588,6 +672,36 @@ int reset_control_acquire(struct reset_control *rstc)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(reset_control_acquire);
|
EXPORT_SYMBOL_GPL(reset_control_acquire);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset_control_bulk_acquire - acquires reset controls for exclusive use
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset controls set
|
||||||
|
*
|
||||||
|
* This is used to explicitly acquire reset controls requested with
|
||||||
|
* reset_control_bulk_get_exclusive_release() for temporary exclusive use.
|
||||||
|
*
|
||||||
|
* See also: reset_control_acquire(), reset_control_bulk_release()
|
||||||
|
*/
|
||||||
|
int reset_control_bulk_acquire(int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_rstcs; i++) {
|
||||||
|
ret = reset_control_acquire(rstcs[i].rstc);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
while (i--)
|
||||||
|
reset_control_release(rstcs[i].rstc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(reset_control_bulk_acquire);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reset_control_release() - releases exclusive access to a reset control
|
* reset_control_release() - releases exclusive access to a reset control
|
||||||
* @rstc: reset control
|
* @rstc: reset control
|
||||||
|
@ -610,6 +724,26 @@ void reset_control_release(struct reset_control *rstc)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(reset_control_release);
|
EXPORT_SYMBOL_GPL(reset_control_release);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset_control_bulk_release() - releases exclusive access to reset controls
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset controls set
|
||||||
|
*
|
||||||
|
* Releases exclusive access right to reset controls previously obtained by a
|
||||||
|
* call to reset_control_bulk_acquire().
|
||||||
|
*
|
||||||
|
* See also: reset_control_release(), reset_control_bulk_acquire()
|
||||||
|
*/
|
||||||
|
void reset_control_bulk_release(int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_rstcs; i++)
|
||||||
|
reset_control_release(rstcs[i].rstc);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(reset_control_bulk_release);
|
||||||
|
|
||||||
static struct reset_control *__reset_control_get_internal(
|
static struct reset_control *__reset_control_get_internal(
|
||||||
struct reset_controller_dev *rcdev,
|
struct reset_controller_dev *rcdev,
|
||||||
unsigned int index, bool shared, bool acquired)
|
unsigned int index, bool shared, bool acquired)
|
||||||
|
@ -814,6 +948,32 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__reset_control_get);
|
EXPORT_SYMBOL_GPL(__reset_control_get);
|
||||||
|
|
||||||
|
int __reset_control_bulk_get(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs,
|
||||||
|
bool shared, bool optional, bool acquired)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_rstcs; i++) {
|
||||||
|
rstcs[i].rstc = __reset_control_get(dev, rstcs[i].id, 0,
|
||||||
|
shared, optional, acquired);
|
||||||
|
if (IS_ERR(rstcs[i].rstc)) {
|
||||||
|
ret = PTR_ERR(rstcs[i].rstc);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
mutex_lock(&reset_list_mutex);
|
||||||
|
while (i--)
|
||||||
|
__reset_control_put_internal(rstcs[i].rstc);
|
||||||
|
mutex_unlock(&reset_list_mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(__reset_control_bulk_get);
|
||||||
|
|
||||||
static void reset_control_array_put(struct reset_control_array *resets)
|
static void reset_control_array_put(struct reset_control_array *resets)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -845,6 +1005,23 @@ void reset_control_put(struct reset_control *rstc)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(reset_control_put);
|
EXPORT_SYMBOL_GPL(reset_control_put);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset_control_bulk_put - free the reset controllers
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset controls set
|
||||||
|
*/
|
||||||
|
void reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
mutex_lock(&reset_list_mutex);
|
||||||
|
while (num_rstcs--) {
|
||||||
|
if (IS_ERR_OR_NULL(rstcs[num_rstcs].rstc))
|
||||||
|
continue;
|
||||||
|
__reset_control_put_internal(rstcs[num_rstcs].rstc);
|
||||||
|
}
|
||||||
|
mutex_unlock(&reset_list_mutex);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(reset_control_bulk_put);
|
||||||
|
|
||||||
static void devm_reset_control_release(struct device *dev, void *res)
|
static void devm_reset_control_release(struct device *dev, void *res)
|
||||||
{
|
{
|
||||||
reset_control_put(*(struct reset_control **)res);
|
reset_control_put(*(struct reset_control **)res);
|
||||||
|
@ -874,6 +1051,44 @@ struct reset_control *__devm_reset_control_get(struct device *dev,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__devm_reset_control_get);
|
EXPORT_SYMBOL_GPL(__devm_reset_control_get);
|
||||||
|
|
||||||
|
struct reset_control_bulk_devres {
|
||||||
|
int num_rstcs;
|
||||||
|
struct reset_control_bulk_data *rstcs;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void devm_reset_control_bulk_release(struct device *dev, void *res)
|
||||||
|
{
|
||||||
|
struct reset_control_bulk_devres *devres = res;
|
||||||
|
|
||||||
|
reset_control_bulk_put(devres->num_rstcs, devres->rstcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs,
|
||||||
|
bool shared, bool optional, bool acquired)
|
||||||
|
{
|
||||||
|
struct reset_control_bulk_devres *ptr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ptr = devres_alloc(devm_reset_control_bulk_release, sizeof(*ptr),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!ptr)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = __reset_control_bulk_get(dev, num_rstcs, rstcs, shared, optional, acquired);
|
||||||
|
if (ret < 0) {
|
||||||
|
devres_free(ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr->num_rstcs = num_rstcs;
|
||||||
|
ptr->rstcs = rstcs;
|
||||||
|
devres_add(dev, ptr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(__devm_reset_control_bulk_get);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __device_reset - find reset controller associated with the device
|
* __device_reset - find reset controller associated with the device
|
||||||
* and perform reset
|
* and perform reset
|
||||||
|
|
|
@ -1553,13 +1553,12 @@ static int spi_imx_slave_abort(struct spi_master *master)
|
||||||
static int spi_imx_probe(struct platform_device *pdev)
|
static int spi_imx_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
const struct of_device_id *of_id =
|
|
||||||
of_match_device(spi_imx_dt_ids, &pdev->dev);
|
|
||||||
struct spi_master *master;
|
struct spi_master *master;
|
||||||
struct spi_imx_data *spi_imx;
|
struct spi_imx_data *spi_imx;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
int ret, irq, spi_drctl;
|
int ret, irq, spi_drctl;
|
||||||
const struct spi_imx_devtype_data *devtype_data = of_id->data;
|
const struct spi_imx_devtype_data *devtype_data =
|
||||||
|
of_device_get_match_data(&pdev->dev);
|
||||||
bool slave_mode;
|
bool slave_mode;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
#ifndef __PLATFORM_DATA_ASOC_MX27VIS_H
|
|
||||||
#define __PLATFORM_DATA_ASOC_MX27VIS_H
|
|
||||||
|
|
||||||
struct snd_mx27vis_platform_data {
|
|
||||||
int amp_gain0_gpio;
|
|
||||||
int amp_gain1_gpio;
|
|
||||||
int amp_mutel_gpio;
|
|
||||||
int amp_muter_gpio;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* __PLATFORM_DATA_ASOC_MX27VIS_H */
|
|
|
@ -10,6 +10,21 @@ struct device;
|
||||||
struct device_node;
|
struct device_node;
|
||||||
struct reset_control;
|
struct reset_control;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct reset_control_bulk_data - Data used for bulk reset control operations.
|
||||||
|
*
|
||||||
|
* @id: reset control consumer ID
|
||||||
|
* @rstc: struct reset_control * to store the associated reset control
|
||||||
|
*
|
||||||
|
* The reset APIs provide a series of reset_control_bulk_*() API calls as
|
||||||
|
* a convenience to consumers which require multiple reset controls.
|
||||||
|
* This structure is used to manage data for these calls.
|
||||||
|
*/
|
||||||
|
struct reset_control_bulk_data {
|
||||||
|
const char *id;
|
||||||
|
struct reset_control *rstc;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_RESET_CONTROLLER
|
#ifdef CONFIG_RESET_CONTROLLER
|
||||||
|
|
||||||
int reset_control_reset(struct reset_control *rstc);
|
int reset_control_reset(struct reset_control *rstc);
|
||||||
|
@ -20,6 +35,12 @@ int reset_control_status(struct reset_control *rstc);
|
||||||
int reset_control_acquire(struct reset_control *rstc);
|
int reset_control_acquire(struct reset_control *rstc);
|
||||||
void reset_control_release(struct reset_control *rstc);
|
void reset_control_release(struct reset_control *rstc);
|
||||||
|
|
||||||
|
int reset_control_bulk_reset(int num_rstcs, struct reset_control_bulk_data *rstcs);
|
||||||
|
int reset_control_bulk_assert(int num_rstcs, struct reset_control_bulk_data *rstcs);
|
||||||
|
int reset_control_bulk_deassert(int num_rstcs, struct reset_control_bulk_data *rstcs);
|
||||||
|
int reset_control_bulk_acquire(int num_rstcs, struct reset_control_bulk_data *rstcs);
|
||||||
|
void reset_control_bulk_release(int num_rstcs, struct reset_control_bulk_data *rstcs);
|
||||||
|
|
||||||
struct reset_control *__of_reset_control_get(struct device_node *node,
|
struct reset_control *__of_reset_control_get(struct device_node *node,
|
||||||
const char *id, int index, bool shared,
|
const char *id, int index, bool shared,
|
||||||
bool optional, bool acquired);
|
bool optional, bool acquired);
|
||||||
|
@ -27,10 +48,18 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id,
|
||||||
int index, bool shared,
|
int index, bool shared,
|
||||||
bool optional, bool acquired);
|
bool optional, bool acquired);
|
||||||
void reset_control_put(struct reset_control *rstc);
|
void reset_control_put(struct reset_control *rstc);
|
||||||
|
int __reset_control_bulk_get(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs,
|
||||||
|
bool shared, bool optional, bool acquired);
|
||||||
|
void reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs);
|
||||||
|
|
||||||
int __device_reset(struct device *dev, bool optional);
|
int __device_reset(struct device *dev, bool optional);
|
||||||
struct reset_control *__devm_reset_control_get(struct device *dev,
|
struct reset_control *__devm_reset_control_get(struct device *dev,
|
||||||
const char *id, int index, bool shared,
|
const char *id, int index, bool shared,
|
||||||
bool optional, bool acquired);
|
bool optional, bool acquired);
|
||||||
|
int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs,
|
||||||
|
bool shared, bool optional, bool acquired);
|
||||||
|
|
||||||
struct reset_control *devm_reset_control_array_get(struct device *dev,
|
struct reset_control *devm_reset_control_array_get(struct device *dev,
|
||||||
bool shared, bool optional);
|
bool shared, bool optional);
|
||||||
|
@ -96,6 +125,48 @@ static inline struct reset_control *__reset_control_get(
|
||||||
return optional ? NULL : ERR_PTR(-ENOTSUPP);
|
return optional ? NULL : ERR_PTR(-ENOTSUPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
reset_control_bulk_reset(int num_rstcs, struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
reset_control_bulk_assert(int num_rstcs, struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
reset_control_bulk_deassert(int num_rstcs, struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
reset_control_bulk_acquire(int num_rstcs, struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
reset_control_bulk_release(int num_rstcs, struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__reset_control_bulk_get(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs,
|
||||||
|
bool shared, bool optional, bool acquired)
|
||||||
|
{
|
||||||
|
return optional ? 0 : -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct reset_control *__devm_reset_control_get(
|
static inline struct reset_control *__devm_reset_control_get(
|
||||||
struct device *dev, const char *id,
|
struct device *dev, const char *id,
|
||||||
int index, bool shared, bool optional,
|
int index, bool shared, bool optional,
|
||||||
|
@ -104,6 +175,14 @@ static inline struct reset_control *__devm_reset_control_get(
|
||||||
return optional ? NULL : ERR_PTR(-ENOTSUPP);
|
return optional ? NULL : ERR_PTR(-ENOTSUPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs,
|
||||||
|
bool shared, bool optional, bool acquired)
|
||||||
|
{
|
||||||
|
return optional ? 0 : -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct reset_control *
|
static inline struct reset_control *
|
||||||
devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
|
devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
|
||||||
{
|
{
|
||||||
|
@ -155,6 +234,23 @@ __must_check reset_control_get_exclusive(struct device *dev, const char *id)
|
||||||
return __reset_control_get(dev, id, 0, false, false, true);
|
return __reset_control_get(dev, id, 0, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset_control_bulk_get_exclusive - Lookup and obtain exclusive references to
|
||||||
|
* multiple reset controllers.
|
||||||
|
* @dev: device to be reset by the controller
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset line names set
|
||||||
|
*
|
||||||
|
* Fills the rstcs array with pointers to exclusive reset controls and
|
||||||
|
* returns 0, or an IS_ERR() condition containing errno.
|
||||||
|
*/
|
||||||
|
static inline int __must_check
|
||||||
|
reset_control_bulk_get_exclusive(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reset_control_get_exclusive_released - Lookup and obtain a temoprarily
|
* reset_control_get_exclusive_released - Lookup and obtain a temoprarily
|
||||||
* exclusive reference to a reset
|
* exclusive reference to a reset
|
||||||
|
@ -176,6 +272,48 @@ __must_check reset_control_get_exclusive_released(struct device *dev,
|
||||||
return __reset_control_get(dev, id, 0, false, false, false);
|
return __reset_control_get(dev, id, 0, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset_control_bulk_get_exclusive_released - Lookup and obtain temporarily
|
||||||
|
* exclusive references to multiple reset
|
||||||
|
* controllers.
|
||||||
|
* @dev: device to be reset by the controller
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset line names set
|
||||||
|
*
|
||||||
|
* Fills the rstcs array with pointers to exclusive reset controls and
|
||||||
|
* returns 0, or an IS_ERR() condition containing errno.
|
||||||
|
* reset-controls returned by this function must be acquired via
|
||||||
|
* reset_control_bulk_acquire() before they can be used and should be released
|
||||||
|
* via reset_control_bulk_release() afterwards.
|
||||||
|
*/
|
||||||
|
static inline int __must_check
|
||||||
|
reset_control_bulk_get_exclusive_released(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset_control_bulk_get_optional_exclusive_released - Lookup and obtain optional
|
||||||
|
* temporarily exclusive references to multiple
|
||||||
|
* reset controllers.
|
||||||
|
* @dev: device to be reset by the controller
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset line names set
|
||||||
|
*
|
||||||
|
* Optional variant of reset_control_bulk_get_exclusive_released(). If the
|
||||||
|
* requested reset is not specified in the device tree, this function returns 0
|
||||||
|
* instead of an error and missing rtsc is set to NULL.
|
||||||
|
*
|
||||||
|
* See reset_control_bulk_get_exclusive_released() for more information.
|
||||||
|
*/
|
||||||
|
static inline int __must_check
|
||||||
|
reset_control_bulk_get_optional_exclusive_released(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reset_control_get_shared - Lookup and obtain a shared reference to a
|
* reset_control_get_shared - Lookup and obtain a shared reference to a
|
||||||
* reset controller.
|
* reset controller.
|
||||||
|
@ -204,6 +342,23 @@ static inline struct reset_control *reset_control_get_shared(
|
||||||
return __reset_control_get(dev, id, 0, true, false, false);
|
return __reset_control_get(dev, id, 0, true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset_control_bulk_get_shared - Lookup and obtain shared references to
|
||||||
|
* multiple reset controllers.
|
||||||
|
* @dev: device to be reset by the controller
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset line names set
|
||||||
|
*
|
||||||
|
* Fills the rstcs array with pointers to shared reset controls and
|
||||||
|
* returns 0, or an IS_ERR() condition containing errno.
|
||||||
|
*/
|
||||||
|
static inline int __must_check
|
||||||
|
reset_control_bulk_get_shared(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return __reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reset_control_get_optional_exclusive - optional reset_control_get_exclusive()
|
* reset_control_get_optional_exclusive - optional reset_control_get_exclusive()
|
||||||
* @dev: device to be reset by the controller
|
* @dev: device to be reset by the controller
|
||||||
|
@ -221,6 +376,26 @@ static inline struct reset_control *reset_control_get_optional_exclusive(
|
||||||
return __reset_control_get(dev, id, 0, false, true, true);
|
return __reset_control_get(dev, id, 0, false, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset_control_bulk_get_optional_exclusive - optional
|
||||||
|
* reset_control_bulk_get_exclusive()
|
||||||
|
* @dev: device to be reset by the controller
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset line names set
|
||||||
|
*
|
||||||
|
* Optional variant of reset_control_bulk_get_exclusive(). If any of the
|
||||||
|
* requested resets are not specified in the device tree, this function sets
|
||||||
|
* them to NULL instead of returning an error.
|
||||||
|
*
|
||||||
|
* See reset_control_bulk_get_exclusive() for more information.
|
||||||
|
*/
|
||||||
|
static inline int __must_check
|
||||||
|
reset_control_bulk_get_optional_exclusive(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reset_control_get_optional_shared - optional reset_control_get_shared()
|
* reset_control_get_optional_shared - optional reset_control_get_shared()
|
||||||
* @dev: device to be reset by the controller
|
* @dev: device to be reset by the controller
|
||||||
|
@ -238,6 +413,26 @@ static inline struct reset_control *reset_control_get_optional_shared(
|
||||||
return __reset_control_get(dev, id, 0, true, true, false);
|
return __reset_control_get(dev, id, 0, true, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset_control_bulk_get_optional_shared - optional
|
||||||
|
* reset_control_bulk_get_shared()
|
||||||
|
* @dev: device to be reset by the controller
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset line names set
|
||||||
|
*
|
||||||
|
* Optional variant of reset_control_bulk_get_shared(). If the requested resets
|
||||||
|
* are not specified in the device tree, this function sets them to NULL
|
||||||
|
* instead of returning an error.
|
||||||
|
*
|
||||||
|
* See reset_control_bulk_get_shared() for more information.
|
||||||
|
*/
|
||||||
|
static inline int __must_check
|
||||||
|
reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return __reset_control_bulk_get(dev, num_rstcs, rstcs, true, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* of_reset_control_get_exclusive - Lookup and obtain an exclusive reference
|
* of_reset_control_get_exclusive - Lookup and obtain an exclusive reference
|
||||||
* to a reset controller.
|
* to a reset controller.
|
||||||
|
@ -343,6 +538,26 @@ __must_check devm_reset_control_get_exclusive(struct device *dev,
|
||||||
return __devm_reset_control_get(dev, id, 0, false, false, true);
|
return __devm_reset_control_get(dev, id, 0, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* devm_reset_control_bulk_get_exclusive - resource managed
|
||||||
|
* reset_control_bulk_get_exclusive()
|
||||||
|
* @dev: device to be reset by the controller
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset line names set
|
||||||
|
*
|
||||||
|
* Managed reset_control_bulk_get_exclusive(). For reset controllers returned
|
||||||
|
* from this function, reset_control_put() is called automatically on driver
|
||||||
|
* detach.
|
||||||
|
*
|
||||||
|
* See reset_control_bulk_get_exclusive() for more information.
|
||||||
|
*/
|
||||||
|
static inline int __must_check
|
||||||
|
devm_reset_control_bulk_get_exclusive(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* devm_reset_control_get_exclusive_released - resource managed
|
* devm_reset_control_get_exclusive_released - resource managed
|
||||||
* reset_control_get_exclusive_released()
|
* reset_control_get_exclusive_released()
|
||||||
|
@ -362,6 +577,26 @@ __must_check devm_reset_control_get_exclusive_released(struct device *dev,
|
||||||
return __devm_reset_control_get(dev, id, 0, false, false, false);
|
return __devm_reset_control_get(dev, id, 0, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* devm_reset_control_bulk_get_exclusive_released - resource managed
|
||||||
|
* reset_control_bulk_get_exclusive_released()
|
||||||
|
* @dev: device to be reset by the controller
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset line names set
|
||||||
|
*
|
||||||
|
* Managed reset_control_bulk_get_exclusive_released(). For reset controllers
|
||||||
|
* returned from this function, reset_control_put() is called automatically on
|
||||||
|
* driver detach.
|
||||||
|
*
|
||||||
|
* See reset_control_bulk_get_exclusive_released() for more information.
|
||||||
|
*/
|
||||||
|
static inline int __must_check
|
||||||
|
devm_reset_control_bulk_get_exclusive_released(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* devm_reset_control_get_optional_exclusive_released - resource managed
|
* devm_reset_control_get_optional_exclusive_released - resource managed
|
||||||
* reset_control_get_optional_exclusive_released()
|
* reset_control_get_optional_exclusive_released()
|
||||||
|
@ -381,6 +616,26 @@ __must_check devm_reset_control_get_optional_exclusive_released(struct device *d
|
||||||
return __devm_reset_control_get(dev, id, 0, false, true, false);
|
return __devm_reset_control_get(dev, id, 0, false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* devm_reset_control_bulk_get_optional_exclusive_released - resource managed
|
||||||
|
* reset_control_bulk_optional_get_exclusive_released()
|
||||||
|
* @dev: device to be reset by the controller
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset line names set
|
||||||
|
*
|
||||||
|
* Managed reset_control_bulk_optional_get_exclusive_released(). For reset
|
||||||
|
* controllers returned from this function, reset_control_put() is called
|
||||||
|
* automatically on driver detach.
|
||||||
|
*
|
||||||
|
* See reset_control_bulk_optional_get_exclusive_released() for more information.
|
||||||
|
*/
|
||||||
|
static inline int __must_check
|
||||||
|
devm_reset_control_bulk_get_optional_exclusive_released(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* devm_reset_control_get_shared - resource managed reset_control_get_shared()
|
* devm_reset_control_get_shared - resource managed reset_control_get_shared()
|
||||||
* @dev: device to be reset by the controller
|
* @dev: device to be reset by the controller
|
||||||
|
@ -396,6 +651,26 @@ static inline struct reset_control *devm_reset_control_get_shared(
|
||||||
return __devm_reset_control_get(dev, id, 0, true, false, false);
|
return __devm_reset_control_get(dev, id, 0, true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* devm_reset_control_bulk_get_shared - resource managed
|
||||||
|
* reset_control_bulk_get_shared()
|
||||||
|
* @dev: device to be reset by the controller
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset line names set
|
||||||
|
*
|
||||||
|
* Managed reset_control_bulk_get_shared(). For reset controllers returned
|
||||||
|
* from this function, reset_control_put() is called automatically on driver
|
||||||
|
* detach.
|
||||||
|
*
|
||||||
|
* See reset_control_bulk_get_shared() for more information.
|
||||||
|
*/
|
||||||
|
static inline int __must_check
|
||||||
|
devm_reset_control_bulk_get_shared(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* devm_reset_control_get_optional_exclusive - resource managed
|
* devm_reset_control_get_optional_exclusive - resource managed
|
||||||
* reset_control_get_optional_exclusive()
|
* reset_control_get_optional_exclusive()
|
||||||
|
@ -414,6 +689,26 @@ static inline struct reset_control *devm_reset_control_get_optional_exclusive(
|
||||||
return __devm_reset_control_get(dev, id, 0, false, true, true);
|
return __devm_reset_control_get(dev, id, 0, false, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* devm_reset_control_bulk_get_optional_exclusive - resource managed
|
||||||
|
* reset_control_bulk_get_optional_exclusive()
|
||||||
|
* @dev: device to be reset by the controller
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset line names set
|
||||||
|
*
|
||||||
|
* Managed reset_control_bulk_get_optional_exclusive(). For reset controllers
|
||||||
|
* returned from this function, reset_control_put() is called automatically on
|
||||||
|
* driver detach.
|
||||||
|
*
|
||||||
|
* See reset_control_bulk_get_optional_exclusive() for more information.
|
||||||
|
*/
|
||||||
|
static inline int __must_check
|
||||||
|
devm_reset_control_bulk_get_optional_exclusive(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* devm_reset_control_get_optional_shared - resource managed
|
* devm_reset_control_get_optional_shared - resource managed
|
||||||
* reset_control_get_optional_shared()
|
* reset_control_get_optional_shared()
|
||||||
|
@ -432,6 +727,26 @@ static inline struct reset_control *devm_reset_control_get_optional_shared(
|
||||||
return __devm_reset_control_get(dev, id, 0, true, true, false);
|
return __devm_reset_control_get(dev, id, 0, true, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* devm_reset_control_bulk_get_optional_shared - resource managed
|
||||||
|
* reset_control_bulk_get_optional_shared()
|
||||||
|
* @dev: device to be reset by the controller
|
||||||
|
* @num_rstcs: number of entries in rstcs array
|
||||||
|
* @rstcs: array of struct reset_control_bulk_data with reset line names set
|
||||||
|
*
|
||||||
|
* Managed reset_control_bulk_get_optional_shared(). For reset controllers
|
||||||
|
* returned from this function, reset_control_put() is called automatically on
|
||||||
|
* driver detach.
|
||||||
|
*
|
||||||
|
* See reset_control_bulk_get_optional_shared() for more information.
|
||||||
|
*/
|
||||||
|
static inline int __must_check
|
||||||
|
devm_reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs,
|
||||||
|
struct reset_control_bulk_data *rstcs)
|
||||||
|
{
|
||||||
|
return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* devm_reset_control_get_exclusive_by_index - resource managed
|
* devm_reset_control_get_exclusive_by_index - resource managed
|
||||||
* reset_control_get_exclusive()
|
* reset_control_get_exclusive()
|
||||||
|
|
|
@ -24,7 +24,7 @@ typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol,
|
||||||
|
|
||||||
/* internal flag for skipping validations */
|
/* internal flag for skipping validations */
|
||||||
#ifdef CONFIG_SND_CTL_VALIDATION
|
#ifdef CONFIG_SND_CTL_VALIDATION
|
||||||
#define SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK (1 << 27)
|
#define SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK (1 << 24)
|
||||||
#define snd_ctl_skip_validation(info) \
|
#define snd_ctl_skip_validation(info) \
|
||||||
((info)->access & SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK)
|
((info)->access & SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK)
|
||||||
#else
|
#else
|
||||||
|
@ -32,6 +32,12 @@ typedef int (snd_kcontrol_tlv_rw_t)(struct snd_kcontrol *kcontrol,
|
||||||
#define snd_ctl_skip_validation(info) true
|
#define snd_ctl_skip_validation(info) true
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* kernel only - LED bits */
|
||||||
|
#define SNDRV_CTL_ELEM_ACCESS_LED_SHIFT 25
|
||||||
|
#define SNDRV_CTL_ELEM_ACCESS_LED_MASK (7<<25) /* kernel three bits - LED group */
|
||||||
|
#define SNDRV_CTL_ELEM_ACCESS_SPK_LED (1<<25) /* kernel speaker (output) LED flag */
|
||||||
|
#define SNDRV_CTL_ELEM_ACCESS_MIC_LED (2<<25) /* kernel microphone (input) LED flag */
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SNDRV_CTL_TLV_OP_READ = 0,
|
SNDRV_CTL_TLV_OP_READ = 0,
|
||||||
SNDRV_CTL_TLV_OP_WRITE = 1,
|
SNDRV_CTL_TLV_OP_WRITE = 1,
|
||||||
|
@ -108,6 +114,14 @@ struct snd_ctl_file {
|
||||||
struct list_head events; /* waiting events for read */
|
struct list_head events; /* waiting events for read */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct snd_ctl_layer_ops {
|
||||||
|
struct snd_ctl_layer_ops *next;
|
||||||
|
const char *module_name;
|
||||||
|
void (*lregister)(struct snd_card *card);
|
||||||
|
void (*ldisconnect)(struct snd_card *card);
|
||||||
|
void (*lnotify)(struct snd_card *card, unsigned int mask, struct snd_kcontrol *kctl, unsigned int ioff);
|
||||||
|
};
|
||||||
|
|
||||||
#define snd_ctl_file(n) list_entry(n, struct snd_ctl_file, list)
|
#define snd_ctl_file(n) list_entry(n, struct snd_ctl_file, list)
|
||||||
|
|
||||||
typedef int (*snd_kctl_ioctl_func_t) (struct snd_card * card,
|
typedef int (*snd_kctl_ioctl_func_t) (struct snd_card * card,
|
||||||
|
@ -115,6 +129,7 @@ typedef int (*snd_kctl_ioctl_func_t) (struct snd_card * card,
|
||||||
unsigned int cmd, unsigned long arg);
|
unsigned int cmd, unsigned long arg);
|
||||||
|
|
||||||
void snd_ctl_notify(struct snd_card * card, unsigned int mask, struct snd_ctl_elem_id * id);
|
void snd_ctl_notify(struct snd_card * card, unsigned int mask, struct snd_ctl_elem_id * id);
|
||||||
|
void snd_ctl_notify_one(struct snd_card * card, unsigned int mask, struct snd_kcontrol * kctl, unsigned int ioff);
|
||||||
|
|
||||||
struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new * kcontrolnew, void * private_data);
|
struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new * kcontrolnew, void * private_data);
|
||||||
void snd_ctl_free_one(struct snd_kcontrol * kcontrol);
|
void snd_ctl_free_one(struct snd_kcontrol * kcontrol);
|
||||||
|
@ -123,8 +138,7 @@ int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
|
||||||
int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace);
|
int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace);
|
||||||
int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
|
int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
|
||||||
int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
|
int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
|
||||||
int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
|
int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, int active);
|
||||||
int active);
|
|
||||||
struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);
|
struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);
|
||||||
struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);
|
struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);
|
||||||
|
|
||||||
|
@ -140,6 +154,10 @@ int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn);
|
||||||
#define snd_ctl_unregister_ioctl_compat(fcn)
|
#define snd_ctl_unregister_ioctl_compat(fcn)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int snd_ctl_request_layer(const char *module_name);
|
||||||
|
void snd_ctl_register_layer(struct snd_ctl_layer_ops *lops);
|
||||||
|
void snd_ctl_disconnect_layer(struct snd_ctl_layer_ops *lops);
|
||||||
|
|
||||||
int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type);
|
int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type);
|
||||||
|
|
||||||
static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
|
static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
|
||||||
|
@ -253,6 +271,17 @@ int snd_ctl_apply_vmaster_followers(struct snd_kcontrol *kctl,
|
||||||
void *arg),
|
void *arg),
|
||||||
void *arg);
|
void *arg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control LED trigger layer
|
||||||
|
*/
|
||||||
|
#define SND_CTL_LAYER_MODULE_LED "snd-ctl-led"
|
||||||
|
|
||||||
|
#if IS_MODULE(CONFIG_SND_CTL_LED)
|
||||||
|
static inline int snd_ctl_led_request(void) { return snd_ctl_request_layer(SND_CTL_LAYER_MODULE_LED); }
|
||||||
|
#else
|
||||||
|
static inline int snd_ctl_led_request(void) { return 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper functions for jack-detection controls
|
* Helper functions for jack-detection controls
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -100,7 +100,7 @@ struct snd_card {
|
||||||
struct rw_semaphore controls_rwsem; /* controls list lock */
|
struct rw_semaphore controls_rwsem; /* controls list lock */
|
||||||
rwlock_t ctl_files_rwlock; /* ctl_files list lock */
|
rwlock_t ctl_files_rwlock; /* ctl_files list lock */
|
||||||
int controls_count; /* count of all controls */
|
int controls_count; /* count of all controls */
|
||||||
int user_ctl_count; /* count of all user controls */
|
size_t user_ctl_alloc_size; // current memory allocation by user controls.
|
||||||
struct list_head controls; /* all controls for this card */
|
struct list_head controls; /* all controls for this card */
|
||||||
struct list_head ctl_files; /* active control files */
|
struct list_head ctl_files; /* active control files */
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,6 @@
|
||||||
|
|
||||||
#include <sound/simple_card_utils.h>
|
#include <sound/simple_card_utils.h>
|
||||||
|
|
||||||
int audio_graph_card_probe(struct snd_soc_card *card);
|
|
||||||
|
|
||||||
int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev);
|
int audio_graph_parse_of(struct asoc_simple_priv *priv, struct device *dev);
|
||||||
|
|
||||||
int audio_graph_remove(struct platform_device *pdev);
|
|
||||||
|
|
||||||
#endif /* __GRAPH_CARD_H */
|
#endif /* __GRAPH_CARD_H */
|
||||||
|
|
|
@ -140,8 +140,12 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
|
||||||
#define BDL_SIZE 4096
|
#define BDL_SIZE 4096
|
||||||
#define AZX_MAX_BDL_ENTRIES (BDL_SIZE / 16)
|
#define AZX_MAX_BDL_ENTRIES (BDL_SIZE / 16)
|
||||||
#define AZX_MAX_FRAG 32
|
#define AZX_MAX_FRAG 32
|
||||||
/* max buffer size - no h/w limit, you can increase as you like */
|
/*
|
||||||
#define AZX_MAX_BUF_SIZE (1024*1024*1024)
|
* max buffer size - artificial 4MB limit per stream to avoid big allocations
|
||||||
|
* In theory it can be really big, but as it is per stream on systems with many streams memory could
|
||||||
|
* be quickly saturated if userspace requests maximum buffer size for each of them.
|
||||||
|
*/
|
||||||
|
#define AZX_MAX_BUF_SIZE (4*1024*1024)
|
||||||
|
|
||||||
/* RIRB int mask: overrun[2], response[0] */
|
/* RIRB int mask: overrun[2], response[0] */
|
||||||
#define RIRB_INT_RESPONSE 0x01
|
#define RIRB_INT_RESPONSE 0x01
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
||||||
/*
|
|
||||||
* linux/sound/rt5645.h -- Platform data for RT5645
|
|
||||||
*
|
|
||||||
* Copyright 2013 Realtek Microelectronics
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LINUX_SND_RT5645_H
|
|
||||||
#define __LINUX_SND_RT5645_H
|
|
||||||
|
|
||||||
struct rt5645_platform_data {
|
|
||||||
/* IN2 can optionally be differential */
|
|
||||||
bool in2_diff;
|
|
||||||
|
|
||||||
unsigned int dmic1_data_pin;
|
|
||||||
/* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */
|
|
||||||
unsigned int dmic2_data_pin;
|
|
||||||
/* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */
|
|
||||||
|
|
||||||
unsigned int jd_mode;
|
|
||||||
/* Use level triggered irq */
|
|
||||||
bool level_trigger_irq;
|
|
||||||
/* Invert JD1_1 status polarity */
|
|
||||||
bool inv_jd1_1;
|
|
||||||
/* Invert HP detect status polarity */
|
|
||||||
bool inv_hp_pol;
|
|
||||||
|
|
||||||
/* Value to asign to snd_soc_card.long_name */
|
|
||||||
const char *long_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -38,22 +38,31 @@ struct asoc_simple_jack {
|
||||||
struct snd_soc_jack_gpio gpio;
|
struct snd_soc_jack_gpio gpio;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct prop_nums {
|
||||||
|
int cpus;
|
||||||
|
int codecs;
|
||||||
|
int platforms;
|
||||||
|
};
|
||||||
|
|
||||||
struct asoc_simple_priv {
|
struct asoc_simple_priv {
|
||||||
struct snd_soc_card snd_card;
|
struct snd_soc_card snd_card;
|
||||||
struct simple_dai_props {
|
struct simple_dai_props {
|
||||||
struct asoc_simple_dai *cpu_dai;
|
struct asoc_simple_dai *cpu_dai;
|
||||||
struct asoc_simple_dai *codec_dai;
|
struct asoc_simple_dai *codec_dai;
|
||||||
struct snd_soc_dai_link_component cpus; /* single cpu */
|
struct snd_soc_dai_link_component *cpus;
|
||||||
struct snd_soc_dai_link_component codecs; /* single codec */
|
struct snd_soc_dai_link_component *codecs;
|
||||||
struct snd_soc_dai_link_component platforms;
|
struct snd_soc_dai_link_component *platforms;
|
||||||
struct asoc_simple_data adata;
|
struct asoc_simple_data adata;
|
||||||
struct snd_soc_codec_conf *codec_conf;
|
struct snd_soc_codec_conf *codec_conf;
|
||||||
|
struct prop_nums num;
|
||||||
unsigned int mclk_fs;
|
unsigned int mclk_fs;
|
||||||
} *dai_props;
|
} *dai_props;
|
||||||
struct asoc_simple_jack hp_jack;
|
struct asoc_simple_jack hp_jack;
|
||||||
struct asoc_simple_jack mic_jack;
|
struct asoc_simple_jack mic_jack;
|
||||||
struct snd_soc_dai_link *dai_link;
|
struct snd_soc_dai_link *dai_link;
|
||||||
struct asoc_simple_dai *dais;
|
struct asoc_simple_dai *dais;
|
||||||
|
struct snd_soc_dai_link_component *dlcs;
|
||||||
|
struct snd_soc_dai_link_component dummy;
|
||||||
struct snd_soc_codec_conf *codec_conf;
|
struct snd_soc_codec_conf *codec_conf;
|
||||||
struct gpio_desc *pa_gpio;
|
struct gpio_desc *pa_gpio;
|
||||||
const struct snd_soc_ops *ops;
|
const struct snd_soc_ops *ops;
|
||||||
|
@ -65,11 +74,53 @@ struct asoc_simple_priv {
|
||||||
#define simple_priv_to_dev(priv) (simple_priv_to_card(priv)->dev)
|
#define simple_priv_to_dev(priv) (simple_priv_to_card(priv)->dev)
|
||||||
#define simple_priv_to_link(priv, i) (simple_priv_to_card(priv)->dai_link + (i))
|
#define simple_priv_to_link(priv, i) (simple_priv_to_card(priv)->dai_link + (i))
|
||||||
|
|
||||||
|
#define simple_props_to_dlc_cpu(props, i) ((props)->cpus + i)
|
||||||
|
#define simple_props_to_dlc_codec(props, i) ((props)->codecs + i)
|
||||||
|
#define simple_props_to_dlc_platform(props, i) ((props)->platforms + i)
|
||||||
|
|
||||||
|
#define simple_props_to_dai_cpu(props, i) ((props)->cpu_dai + i)
|
||||||
|
#define simple_props_to_dai_codec(props, i) ((props)->codec_dai + i)
|
||||||
|
#define simple_props_to_codec_conf(props, i) ((props)->codec_conf + i)
|
||||||
|
|
||||||
|
#define for_each_prop_dlc_cpus(props, i, cpu) \
|
||||||
|
for ((i) = 0; \
|
||||||
|
((i) < (props)->num.cpus) && \
|
||||||
|
((cpu) = simple_props_to_dlc_cpu(props, i)); \
|
||||||
|
(i)++)
|
||||||
|
#define for_each_prop_dlc_codecs(props, i, codec) \
|
||||||
|
for ((i) = 0; \
|
||||||
|
((i) < (props)->num.codecs) && \
|
||||||
|
((codec) = simple_props_to_dlc_codec(props, i)); \
|
||||||
|
(i)++)
|
||||||
|
#define for_each_prop_dlc_platforms(props, i, platform) \
|
||||||
|
for ((i) = 0; \
|
||||||
|
((i) < (props)->num.platforms) && \
|
||||||
|
((platform) = simple_props_to_dlc_platform(props, i)); \
|
||||||
|
(i)++)
|
||||||
|
#define for_each_prop_codec_conf(props, i, conf) \
|
||||||
|
for ((i) = 0; \
|
||||||
|
((i) < (props)->num.codecs) && \
|
||||||
|
(props)->codec_conf && \
|
||||||
|
((conf) = simple_props_to_codec_conf(props, i)); \
|
||||||
|
(i)++)
|
||||||
|
|
||||||
|
#define for_each_prop_dai_cpu(props, i, cpu) \
|
||||||
|
for ((i) = 0; \
|
||||||
|
((i) < (props)->num.cpus) && \
|
||||||
|
((cpu) = simple_props_to_dai_cpu(props, i)); \
|
||||||
|
(i)++)
|
||||||
|
#define for_each_prop_dai_codec(props, i, codec) \
|
||||||
|
for ((i) = 0; \
|
||||||
|
((i) < (props)->num.codecs) && \
|
||||||
|
((codec) = simple_props_to_dai_codec(props, i)); \
|
||||||
|
(i)++)
|
||||||
|
|
||||||
|
#define SNDRV_MAX_LINKS 128
|
||||||
|
|
||||||
struct link_info {
|
struct link_info {
|
||||||
int dais; /* number of dai */
|
|
||||||
int link; /* number of link */
|
int link; /* number of link */
|
||||||
int conf; /* number of codec_conf */
|
|
||||||
int cpu; /* turn for CPU / Codec */
|
int cpu; /* turn for CPU / Codec */
|
||||||
|
struct prop_nums num[SNDRV_MAX_LINKS];
|
||||||
};
|
};
|
||||||
|
|
||||||
int asoc_simple_parse_daifmt(struct device *dev,
|
int asoc_simple_parse_daifmt(struct device *dev,
|
||||||
|
@ -84,10 +135,6 @@ int asoc_simple_set_dailink_name(struct device *dev,
|
||||||
int asoc_simple_parse_card_name(struct snd_soc_card *card,
|
int asoc_simple_parse_card_name(struct snd_soc_card *card,
|
||||||
char *prefix);
|
char *prefix);
|
||||||
|
|
||||||
#define asoc_simple_parse_clk_cpu(dev, node, dai_link, simple_dai) \
|
|
||||||
asoc_simple_parse_clk(dev, node, simple_dai, dai_link->cpus)
|
|
||||||
#define asoc_simple_parse_clk_codec(dev, node, dai_link, simple_dai) \
|
|
||||||
asoc_simple_parse_clk(dev, node, simple_dai, dai_link->codecs)
|
|
||||||
int asoc_simple_parse_clk(struct device *dev,
|
int asoc_simple_parse_clk(struct device *dev,
|
||||||
struct device_node *node,
|
struct device_node *node,
|
||||||
struct asoc_simple_dai *simple_dai,
|
struct asoc_simple_dai *simple_dai,
|
||||||
|
@ -100,29 +147,22 @@ int asoc_simple_dai_init(struct snd_soc_pcm_runtime *rtd);
|
||||||
int asoc_simple_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
int asoc_simple_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
||||||
struct snd_pcm_hw_params *params);
|
struct snd_pcm_hw_params *params);
|
||||||
|
|
||||||
#define asoc_simple_parse_cpu(node, dai_link, is_single_link) \
|
|
||||||
asoc_simple_parse_dai(node, dai_link->cpus, is_single_link)
|
|
||||||
#define asoc_simple_parse_codec(node, dai_link) \
|
|
||||||
asoc_simple_parse_dai(node, dai_link->codecs, NULL)
|
|
||||||
#define asoc_simple_parse_platform(node, dai_link) \
|
|
||||||
asoc_simple_parse_dai(node, dai_link->platforms, NULL)
|
|
||||||
|
|
||||||
#define asoc_simple_parse_tdm(np, dai) \
|
#define asoc_simple_parse_tdm(np, dai) \
|
||||||
snd_soc_of_parse_tdm_slot(np, &(dai)->tx_slot_mask, \
|
snd_soc_of_parse_tdm_slot(np, &(dai)->tx_slot_mask, \
|
||||||
&(dai)->rx_slot_mask, \
|
&(dai)->rx_slot_mask, \
|
||||||
&(dai)->slots, \
|
&(dai)->slots, \
|
||||||
&(dai)->slot_width);
|
&(dai)->slot_width);
|
||||||
|
|
||||||
void asoc_simple_canonicalize_platform(struct snd_soc_dai_link *dai_link);
|
void asoc_simple_canonicalize_platform(struct snd_soc_dai_link_component *platforms,
|
||||||
void asoc_simple_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
|
struct snd_soc_dai_link_component *cpus);
|
||||||
int is_single_links);
|
void asoc_simple_canonicalize_cpu(struct snd_soc_dai_link_component *cpus,
|
||||||
|
int is_single_links);
|
||||||
|
|
||||||
int asoc_simple_clean_reference(struct snd_soc_card *card);
|
int asoc_simple_clean_reference(struct snd_soc_card *card);
|
||||||
|
|
||||||
void asoc_simple_convert_fixup(struct asoc_simple_data *data,
|
void asoc_simple_convert_fixup(struct asoc_simple_data *data,
|
||||||
struct snd_pcm_hw_params *params);
|
struct snd_pcm_hw_params *params);
|
||||||
void asoc_simple_parse_convert(struct device *dev,
|
void asoc_simple_parse_convert(struct device_node *np, char *prefix,
|
||||||
struct device_node *np, char *prefix,
|
|
||||||
struct asoc_simple_data *data);
|
struct asoc_simple_data *data);
|
||||||
|
|
||||||
int asoc_simple_parse_routing(struct snd_soc_card *card,
|
int asoc_simple_parse_routing(struct snd_soc_card *card,
|
||||||
|
@ -137,6 +177,9 @@ int asoc_simple_init_jack(struct snd_soc_card *card,
|
||||||
int is_hp, char *prefix, char *pin);
|
int is_hp, char *prefix, char *pin);
|
||||||
int asoc_simple_init_priv(struct asoc_simple_priv *priv,
|
int asoc_simple_init_priv(struct asoc_simple_priv *priv,
|
||||||
struct link_info *li);
|
struct link_info *li);
|
||||||
|
int asoc_simple_remove(struct platform_device *pdev);
|
||||||
|
|
||||||
|
int asoc_graph_card_probe(struct snd_soc_card *card);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
|
static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
|
||||||
|
@ -152,12 +195,6 @@ static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
|
||||||
if (dai->name)
|
if (dai->name)
|
||||||
dev_dbg(dev, "%s dai name = %s\n",
|
dev_dbg(dev, "%s dai name = %s\n",
|
||||||
name, dai->name);
|
name, dai->name);
|
||||||
if (dai->sysclk)
|
|
||||||
dev_dbg(dev, "%s sysclk = %d\n",
|
|
||||||
name, dai->sysclk);
|
|
||||||
|
|
||||||
dev_dbg(dev, "%s direction = %s\n",
|
|
||||||
name, dai->clk_direction ? "OUT" : "IN");
|
|
||||||
|
|
||||||
if (dai->slots)
|
if (dai->slots)
|
||||||
dev_dbg(dev, "%s slots = %d\n", name, dai->slots);
|
dev_dbg(dev, "%s slots = %d\n", name, dai->slots);
|
||||||
|
@ -169,6 +206,12 @@ static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
|
||||||
dev_dbg(dev, "%s rx slot mask = %d\n", name, dai->rx_slot_mask);
|
dev_dbg(dev, "%s rx slot mask = %d\n", name, dai->rx_slot_mask);
|
||||||
if (dai->clk)
|
if (dai->clk)
|
||||||
dev_dbg(dev, "%s clk %luHz\n", name, clk_get_rate(dai->clk));
|
dev_dbg(dev, "%s clk %luHz\n", name, clk_get_rate(dai->clk));
|
||||||
|
if (dai->sysclk)
|
||||||
|
dev_dbg(dev, "%s sysclk = %dHz\n",
|
||||||
|
name, dai->sysclk);
|
||||||
|
if (dai->clk || dai->sysclk)
|
||||||
|
dev_dbg(dev, "%s direction = %s\n",
|
||||||
|
name, dai->clk_direction ? "OUT" : "IN");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void asoc_simple_debug_info(struct asoc_simple_priv *priv)
|
static inline void asoc_simple_debug_info(struct asoc_simple_priv *priv)
|
||||||
|
@ -184,29 +227,32 @@ static inline void asoc_simple_debug_info(struct asoc_simple_priv *priv)
|
||||||
for (i = 0; i < card->num_links; i++) {
|
for (i = 0; i < card->num_links; i++) {
|
||||||
struct simple_dai_props *props = simple_priv_to_props(priv, i);
|
struct simple_dai_props *props = simple_priv_to_props(priv, i);
|
||||||
struct snd_soc_dai_link *link = simple_priv_to_link(priv, i);
|
struct snd_soc_dai_link *link = simple_priv_to_link(priv, i);
|
||||||
|
struct asoc_simple_dai *dai;
|
||||||
|
struct snd_soc_codec_conf *cnf;
|
||||||
|
int j;
|
||||||
|
|
||||||
dev_dbg(dev, "DAI%d\n", i);
|
dev_dbg(dev, "DAI%d\n", i);
|
||||||
|
|
||||||
asoc_simple_debug_dai(priv, "cpu", props->cpu_dai);
|
dev_dbg(dev, "cpu num = %d\n", link->num_cpus);
|
||||||
asoc_simple_debug_dai(priv, "codec", props->codec_dai);
|
for_each_prop_dai_cpu(props, j, dai)
|
||||||
|
asoc_simple_debug_dai(priv, "cpu", dai);
|
||||||
|
dev_dbg(dev, "codec num = %d\n", link->num_codecs);
|
||||||
|
for_each_prop_dai_codec(props, j, dai)
|
||||||
|
asoc_simple_debug_dai(priv, "codec", dai);
|
||||||
|
|
||||||
if (link->name)
|
if (link->name)
|
||||||
dev_dbg(dev, "dai name = %s\n", link->name);
|
dev_dbg(dev, "dai name = %s\n", link->name);
|
||||||
|
if (link->dai_fmt)
|
||||||
dev_dbg(dev, "dai format = %04x\n", link->dai_fmt);
|
dev_dbg(dev, "dai format = %04x\n", link->dai_fmt);
|
||||||
|
|
||||||
if (props->adata.convert_rate)
|
if (props->adata.convert_rate)
|
||||||
dev_dbg(dev, "convert_rate = %d\n",
|
dev_dbg(dev, "convert_rate = %d\n", props->adata.convert_rate);
|
||||||
props->adata.convert_rate);
|
|
||||||
if (props->adata.convert_channels)
|
if (props->adata.convert_channels)
|
||||||
dev_dbg(dev, "convert_channels = %d\n",
|
dev_dbg(dev, "convert_channels = %d\n", props->adata.convert_channels);
|
||||||
props->adata.convert_channels);
|
for_each_prop_codec_conf(props, j, cnf)
|
||||||
if (props->codec_conf && props->codec_conf->name_prefix)
|
if (cnf->name_prefix)
|
||||||
dev_dbg(dev, "name prefix = %s\n",
|
dev_dbg(dev, "name prefix = %s\n", cnf->name_prefix);
|
||||||
props->codec_conf->name_prefix);
|
|
||||||
if (props->mclk_fs)
|
if (props->mclk_fs)
|
||||||
dev_dbg(dev, "mclk-fs = %d\n",
|
dev_dbg(dev, "mclk-fs = %d\n", props->mclk_fs);
|
||||||
props->mclk_fs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -63,6 +63,8 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
|
||||||
* @common_hdmi_codec_drv: use commom HDAudio HDMI codec driver
|
* @common_hdmi_codec_drv: use commom HDAudio HDMI codec driver
|
||||||
* @link_mask: links enabled on the board
|
* @link_mask: links enabled on the board
|
||||||
* @links: array of link _ADR descriptors, null terminated
|
* @links: array of link _ADR descriptors, null terminated
|
||||||
|
* @num_dai_drivers: number of elements in @dai_drivers
|
||||||
|
* @dai_drivers: pointer to dai_drivers, used e.g. in nocodec mode
|
||||||
*/
|
*/
|
||||||
struct snd_soc_acpi_mach_params {
|
struct snd_soc_acpi_mach_params {
|
||||||
u32 acpi_ipc_irq_index;
|
u32 acpi_ipc_irq_index;
|
||||||
|
@ -72,6 +74,8 @@ struct snd_soc_acpi_mach_params {
|
||||||
bool common_hdmi_codec_drv;
|
bool common_hdmi_codec_drv;
|
||||||
u32 link_mask;
|
u32 link_mask;
|
||||||
const struct snd_soc_acpi_link_adr *links;
|
const struct snd_soc_acpi_link_adr *links;
|
||||||
|
u32 num_dai_drivers;
|
||||||
|
struct snd_soc_dai_driver *dai_drivers;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -101,7 +101,7 @@ struct snd_soc_component_driver {
|
||||||
|
|
||||||
/* DT */
|
/* DT */
|
||||||
int (*of_xlate_dai_name)(struct snd_soc_component *component,
|
int (*of_xlate_dai_name)(struct snd_soc_component *component,
|
||||||
struct of_phandle_args *args,
|
const struct of_phandle_args *args,
|
||||||
const char **dai_name);
|
const char **dai_name);
|
||||||
int (*of_xlate_dai_id)(struct snd_soc_component *comment,
|
int (*of_xlate_dai_id)(struct snd_soc_component *comment,
|
||||||
struct device_node *endpoint);
|
struct device_node *endpoint);
|
||||||
|
@ -146,6 +146,8 @@ struct snd_soc_component_driver {
|
||||||
int (*mmap)(struct snd_soc_component *component,
|
int (*mmap)(struct snd_soc_component *component,
|
||||||
struct snd_pcm_substream *substream,
|
struct snd_pcm_substream *substream,
|
||||||
struct vm_area_struct *vma);
|
struct vm_area_struct *vma);
|
||||||
|
int (*ack)(struct snd_soc_component *component,
|
||||||
|
struct snd_pcm_substream *substream);
|
||||||
|
|
||||||
const struct snd_compress_ops *compress_ops;
|
const struct snd_compress_ops *compress_ops;
|
||||||
|
|
||||||
|
@ -336,6 +338,7 @@ static inline int snd_soc_component_cache_sync(
|
||||||
void snd_soc_component_set_aux(struct snd_soc_component *component,
|
void snd_soc_component_set_aux(struct snd_soc_component *component,
|
||||||
struct snd_soc_aux_dev *aux);
|
struct snd_soc_aux_dev *aux);
|
||||||
int snd_soc_component_init(struct snd_soc_component *component);
|
int snd_soc_component_init(struct snd_soc_component *component);
|
||||||
|
int snd_soc_component_is_dummy(struct snd_soc_component *component);
|
||||||
|
|
||||||
/* component IO */
|
/* component IO */
|
||||||
unsigned int snd_soc_component_read(struct snd_soc_component *component,
|
unsigned int snd_soc_component_read(struct snd_soc_component *component,
|
||||||
|
@ -450,7 +453,7 @@ void snd_soc_component_remove(struct snd_soc_component *component);
|
||||||
int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
|
int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
|
||||||
struct device_node *ep);
|
struct device_node *ep);
|
||||||
int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
|
int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
|
||||||
struct of_phandle_args *args,
|
const struct of_phandle_args *args,
|
||||||
const char **dai_name);
|
const char **dai_name);
|
||||||
int snd_soc_component_compr_open(struct snd_compr_stream *cstream);
|
int snd_soc_component_compr_open(struct snd_compr_stream *cstream);
|
||||||
void snd_soc_component_compr_free(struct snd_compr_stream *cstream,
|
void snd_soc_component_compr_free(struct snd_compr_stream *cstream,
|
||||||
|
@ -498,5 +501,6 @@ int snd_soc_pcm_component_pm_runtime_get(struct snd_soc_pcm_runtime *rtd,
|
||||||
void *stream);
|
void *stream);
|
||||||
void snd_soc_pcm_component_pm_runtime_put(struct snd_soc_pcm_runtime *rtd,
|
void snd_soc_pcm_component_pm_runtime_put(struct snd_soc_pcm_runtime *rtd,
|
||||||
void *stream, int rollback);
|
void *stream, int rollback);
|
||||||
|
int snd_soc_pcm_component_ack(struct snd_pcm_substream *substream);
|
||||||
|
|
||||||
#endif /* __SOC_COMPONENT_H */
|
#endif /* __SOC_COMPONENT_H */
|
||||||
|
|
|
@ -149,14 +149,20 @@ void dpcm_path_put(struct snd_soc_dapm_widget_list **list);
|
||||||
int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
|
int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
|
||||||
int stream, struct snd_soc_dapm_widget_list **list, int new);
|
int stream, struct snd_soc_dapm_widget_list **list, int new);
|
||||||
int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream);
|
int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream);
|
||||||
int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream);
|
void dpcm_be_dai_stop(struct snd_soc_pcm_runtime *fe, int stream,
|
||||||
|
int do_hw_free, struct snd_soc_dpcm *last);
|
||||||
void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream);
|
void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream);
|
||||||
void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream);
|
void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream);
|
||||||
int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream);
|
void dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream);
|
||||||
int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int tream);
|
int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int tream);
|
||||||
int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd);
|
int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd);
|
||||||
int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream);
|
int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream);
|
||||||
int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
|
int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
|
||||||
int event);
|
int event);
|
||||||
|
|
||||||
|
#define dpcm_be_dai_startup_rollback(fe, stream, last) \
|
||||||
|
dpcm_be_dai_stop(fe, stream, 0, last)
|
||||||
|
#define dpcm_be_dai_startup_unwind(fe, stream) dpcm_be_dai_stop(fe, stream, 0, NULL)
|
||||||
|
#define dpcm_be_dai_shutdown(fe, stream) dpcm_be_dai_stop(fe, stream, 1, NULL)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -716,20 +716,38 @@ struct snd_soc_dai_link {
|
||||||
struct snd_soc_dobj dobj; /* For topology */
|
struct snd_soc_dobj dobj; /* For topology */
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline struct snd_soc_dai_link_component*
|
||||||
|
asoc_link_to_cpu(struct snd_soc_dai_link *link, int n) {
|
||||||
|
return &(link)->cpus[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct snd_soc_dai_link_component*
|
||||||
|
asoc_link_to_codec(struct snd_soc_dai_link *link, int n) {
|
||||||
|
return &(link)->codecs[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct snd_soc_dai_link_component*
|
||||||
|
asoc_link_to_platform(struct snd_soc_dai_link *link, int n) {
|
||||||
|
return &(link)->platforms[n];
|
||||||
|
}
|
||||||
|
|
||||||
#define for_each_link_codecs(link, i, codec) \
|
#define for_each_link_codecs(link, i, codec) \
|
||||||
for ((i) = 0; \
|
for ((i) = 0; \
|
||||||
((i) < link->num_codecs) && ((codec) = &link->codecs[i]); \
|
((i) < link->num_codecs) && \
|
||||||
|
((codec) = asoc_link_to_codec(link, i)); \
|
||||||
(i)++)
|
(i)++)
|
||||||
|
|
||||||
#define for_each_link_platforms(link, i, platform) \
|
#define for_each_link_platforms(link, i, platform) \
|
||||||
for ((i) = 0; \
|
for ((i) = 0; \
|
||||||
((i) < link->num_platforms) && \
|
((i) < link->num_platforms) && \
|
||||||
((platform) = &link->platforms[i]); \
|
((platform) = asoc_link_to_platform(link, i)); \
|
||||||
(i)++)
|
(i)++)
|
||||||
|
|
||||||
#define for_each_link_cpus(link, i, cpu) \
|
#define for_each_link_cpus(link, i, cpu) \
|
||||||
for ((i) = 0; \
|
for ((i) = 0; \
|
||||||
((i) < link->num_cpus) && ((cpu) = &link->cpus[i]); \
|
((i) < link->num_cpus) && \
|
||||||
|
((cpu) = asoc_link_to_cpu(link, i)); \
|
||||||
(i)++)
|
(i)++)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1219,7 +1237,7 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
|
||||||
struct device_node **bitclkmaster,
|
struct device_node **bitclkmaster,
|
||||||
struct device_node **framemaster);
|
struct device_node **framemaster);
|
||||||
int snd_soc_get_dai_id(struct device_node *ep);
|
int snd_soc_get_dai_id(struct device_node *ep);
|
||||||
int snd_soc_get_dai_name(struct of_phandle_args *args,
|
int snd_soc_get_dai_name(const struct of_phandle_args *args,
|
||||||
const char **dai_name);
|
const char **dai_name);
|
||||||
int snd_soc_of_get_dai_name(struct device_node *of_node,
|
int snd_soc_of_get_dai_name(struct device_node *of_node,
|
||||||
const char **dai_name);
|
const char **dai_name);
|
||||||
|
@ -1262,13 +1280,17 @@ int snd_soc_fixup_dai_links_platform_name(struct snd_soc_card *card,
|
||||||
|
|
||||||
/* set platform name for each dailink */
|
/* set platform name for each dailink */
|
||||||
for_each_card_prelinks(card, i, dai_link) {
|
for_each_card_prelinks(card, i, dai_link) {
|
||||||
name = devm_kstrdup(card->dev, platform_name, GFP_KERNEL);
|
/* only single platform is supported for now */
|
||||||
if (!name)
|
if (dai_link->num_platforms != 1)
|
||||||
return -ENOMEM;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!dai_link->platforms)
|
if (!dai_link->platforms)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
name = devm_kstrdup(card->dev, platform_name, GFP_KERNEL);
|
||||||
|
if (!name)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
/* only single platform is supported for now */
|
/* only single platform is supported for now */
|
||||||
dai_link->platforms->name = name;
|
dai_link->platforms->name = name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,8 +100,6 @@ struct sof_dev_desc {
|
||||||
const struct snd_sof_dsp_ops *ops;
|
const struct snd_sof_dsp_ops *ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
int sof_nocodec_setup(struct device *dev, const struct snd_sof_dsp_ops *ops,
|
int sof_dai_get_mclk(struct snd_soc_pcm_runtime *rtd);
|
||||||
int (*pcm_dai_link_fixup)(struct snd_soc_pcm_runtime *rtd,
|
|
||||||
struct snd_pcm_hw_params *params));
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#define VIRTIO_ID_PSTORE 22 /* virtio pstore device */
|
#define VIRTIO_ID_PSTORE 22 /* virtio pstore device */
|
||||||
#define VIRTIO_ID_IOMMU 23 /* virtio IOMMU */
|
#define VIRTIO_ID_IOMMU 23 /* virtio IOMMU */
|
||||||
#define VIRTIO_ID_MEM 24 /* virtio mem */
|
#define VIRTIO_ID_MEM 24 /* virtio mem */
|
||||||
|
#define VIRTIO_ID_SOUND 25 /* virtio sound */
|
||||||
#define VIRTIO_ID_FS 26 /* virtio filesystem */
|
#define VIRTIO_ID_FS 26 /* virtio filesystem */
|
||||||
#define VIRTIO_ID_PMEM 27 /* virtio pmem */
|
#define VIRTIO_ID_PMEM 27 /* virtio pmem */
|
||||||
#define VIRTIO_ID_BT 28 /* virtio bluetooth */
|
#define VIRTIO_ID_BT 28 /* virtio bluetooth */
|
||||||
|
|
334
include/uapi/linux/virtio_snd.h
Normal file
334
include/uapi/linux/virtio_snd.h
Normal file
|
@ -0,0 +1,334 @@
|
||||||
|
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 OpenSynergy GmbH
|
||||||
|
*/
|
||||||
|
#ifndef VIRTIO_SND_IF_H
|
||||||
|
#define VIRTIO_SND_IF_H
|
||||||
|
|
||||||
|
#include <linux/virtio_types.h>
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* CONFIGURATION SPACE
|
||||||
|
*/
|
||||||
|
struct virtio_snd_config {
|
||||||
|
/* # of available physical jacks */
|
||||||
|
__le32 jacks;
|
||||||
|
/* # of available PCM streams */
|
||||||
|
__le32 streams;
|
||||||
|
/* # of available channel maps */
|
||||||
|
__le32 chmaps;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/* device virtqueue indexes */
|
||||||
|
VIRTIO_SND_VQ_CONTROL = 0,
|
||||||
|
VIRTIO_SND_VQ_EVENT,
|
||||||
|
VIRTIO_SND_VQ_TX,
|
||||||
|
VIRTIO_SND_VQ_RX,
|
||||||
|
/* # of device virtqueues */
|
||||||
|
VIRTIO_SND_VQ_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* COMMON DEFINITIONS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* supported dataflow directions */
|
||||||
|
enum {
|
||||||
|
VIRTIO_SND_D_OUTPUT = 0,
|
||||||
|
VIRTIO_SND_D_INPUT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/* jack control request types */
|
||||||
|
VIRTIO_SND_R_JACK_INFO = 1,
|
||||||
|
VIRTIO_SND_R_JACK_REMAP,
|
||||||
|
|
||||||
|
/* PCM control request types */
|
||||||
|
VIRTIO_SND_R_PCM_INFO = 0x0100,
|
||||||
|
VIRTIO_SND_R_PCM_SET_PARAMS,
|
||||||
|
VIRTIO_SND_R_PCM_PREPARE,
|
||||||
|
VIRTIO_SND_R_PCM_RELEASE,
|
||||||
|
VIRTIO_SND_R_PCM_START,
|
||||||
|
VIRTIO_SND_R_PCM_STOP,
|
||||||
|
|
||||||
|
/* channel map control request types */
|
||||||
|
VIRTIO_SND_R_CHMAP_INFO = 0x0200,
|
||||||
|
|
||||||
|
/* jack event types */
|
||||||
|
VIRTIO_SND_EVT_JACK_CONNECTED = 0x1000,
|
||||||
|
VIRTIO_SND_EVT_JACK_DISCONNECTED,
|
||||||
|
|
||||||
|
/* PCM event types */
|
||||||
|
VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED = 0x1100,
|
||||||
|
VIRTIO_SND_EVT_PCM_XRUN,
|
||||||
|
|
||||||
|
/* common status codes */
|
||||||
|
VIRTIO_SND_S_OK = 0x8000,
|
||||||
|
VIRTIO_SND_S_BAD_MSG,
|
||||||
|
VIRTIO_SND_S_NOT_SUPP,
|
||||||
|
VIRTIO_SND_S_IO_ERR
|
||||||
|
};
|
||||||
|
|
||||||
|
/* common header */
|
||||||
|
struct virtio_snd_hdr {
|
||||||
|
__le32 code;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* event notification */
|
||||||
|
struct virtio_snd_event {
|
||||||
|
/* VIRTIO_SND_EVT_XXX */
|
||||||
|
struct virtio_snd_hdr hdr;
|
||||||
|
/* optional event data */
|
||||||
|
__le32 data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* common control request to query an item information */
|
||||||
|
struct virtio_snd_query_info {
|
||||||
|
/* VIRTIO_SND_R_XXX_INFO */
|
||||||
|
struct virtio_snd_hdr hdr;
|
||||||
|
/* item start identifier */
|
||||||
|
__le32 start_id;
|
||||||
|
/* item count to query */
|
||||||
|
__le32 count;
|
||||||
|
/* item information size in bytes */
|
||||||
|
__le32 size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* common item information header */
|
||||||
|
struct virtio_snd_info {
|
||||||
|
/* function group node id (High Definition Audio Specification 7.1.2) */
|
||||||
|
__le32 hda_fn_nid;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* JACK CONTROL MESSAGES
|
||||||
|
*/
|
||||||
|
struct virtio_snd_jack_hdr {
|
||||||
|
/* VIRTIO_SND_R_JACK_XXX */
|
||||||
|
struct virtio_snd_hdr hdr;
|
||||||
|
/* 0 ... virtio_snd_config::jacks - 1 */
|
||||||
|
__le32 jack_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* supported jack features */
|
||||||
|
enum {
|
||||||
|
VIRTIO_SND_JACK_F_REMAP = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
struct virtio_snd_jack_info {
|
||||||
|
/* common header */
|
||||||
|
struct virtio_snd_info hdr;
|
||||||
|
/* supported feature bit map (1 << VIRTIO_SND_JACK_F_XXX) */
|
||||||
|
__le32 features;
|
||||||
|
/* pin configuration (High Definition Audio Specification 7.3.3.31) */
|
||||||
|
__le32 hda_reg_defconf;
|
||||||
|
/* pin capabilities (High Definition Audio Specification 7.3.4.9) */
|
||||||
|
__le32 hda_reg_caps;
|
||||||
|
/* current jack connection status (0: disconnected, 1: connected) */
|
||||||
|
__u8 connected;
|
||||||
|
|
||||||
|
__u8 padding[7];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* jack remapping control request */
|
||||||
|
struct virtio_snd_jack_remap {
|
||||||
|
/* .code = VIRTIO_SND_R_JACK_REMAP */
|
||||||
|
struct virtio_snd_jack_hdr hdr;
|
||||||
|
/* selected association number */
|
||||||
|
__le32 association;
|
||||||
|
/* selected sequence number */
|
||||||
|
__le32 sequence;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* PCM CONTROL MESSAGES
|
||||||
|
*/
|
||||||
|
struct virtio_snd_pcm_hdr {
|
||||||
|
/* VIRTIO_SND_R_PCM_XXX */
|
||||||
|
struct virtio_snd_hdr hdr;
|
||||||
|
/* 0 ... virtio_snd_config::streams - 1 */
|
||||||
|
__le32 stream_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* supported PCM stream features */
|
||||||
|
enum {
|
||||||
|
VIRTIO_SND_PCM_F_SHMEM_HOST = 0,
|
||||||
|
VIRTIO_SND_PCM_F_SHMEM_GUEST,
|
||||||
|
VIRTIO_SND_PCM_F_MSG_POLLING,
|
||||||
|
VIRTIO_SND_PCM_F_EVT_SHMEM_PERIODS,
|
||||||
|
VIRTIO_SND_PCM_F_EVT_XRUNS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* supported PCM sample formats */
|
||||||
|
enum {
|
||||||
|
/* analog formats (width / physical width) */
|
||||||
|
VIRTIO_SND_PCM_FMT_IMA_ADPCM = 0, /* 4 / 4 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_MU_LAW, /* 8 / 8 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_A_LAW, /* 8 / 8 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_S8, /* 8 / 8 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_U8, /* 8 / 8 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_S16, /* 16 / 16 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_U16, /* 16 / 16 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_S18_3, /* 18 / 24 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_U18_3, /* 18 / 24 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_S20_3, /* 20 / 24 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_U20_3, /* 20 / 24 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_S24_3, /* 24 / 24 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_U24_3, /* 24 / 24 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_S20, /* 20 / 32 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_U20, /* 20 / 32 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_S24, /* 24 / 32 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_U24, /* 24 / 32 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_S32, /* 32 / 32 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_U32, /* 32 / 32 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_FLOAT, /* 32 / 32 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_FLOAT64, /* 64 / 64 bits */
|
||||||
|
/* digital formats (width / physical width) */
|
||||||
|
VIRTIO_SND_PCM_FMT_DSD_U8, /* 8 / 8 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_DSD_U16, /* 16 / 16 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_DSD_U32, /* 32 / 32 bits */
|
||||||
|
VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME /* 32 / 32 bits */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* supported PCM frame rates */
|
||||||
|
enum {
|
||||||
|
VIRTIO_SND_PCM_RATE_5512 = 0,
|
||||||
|
VIRTIO_SND_PCM_RATE_8000,
|
||||||
|
VIRTIO_SND_PCM_RATE_11025,
|
||||||
|
VIRTIO_SND_PCM_RATE_16000,
|
||||||
|
VIRTIO_SND_PCM_RATE_22050,
|
||||||
|
VIRTIO_SND_PCM_RATE_32000,
|
||||||
|
VIRTIO_SND_PCM_RATE_44100,
|
||||||
|
VIRTIO_SND_PCM_RATE_48000,
|
||||||
|
VIRTIO_SND_PCM_RATE_64000,
|
||||||
|
VIRTIO_SND_PCM_RATE_88200,
|
||||||
|
VIRTIO_SND_PCM_RATE_96000,
|
||||||
|
VIRTIO_SND_PCM_RATE_176400,
|
||||||
|
VIRTIO_SND_PCM_RATE_192000,
|
||||||
|
VIRTIO_SND_PCM_RATE_384000
|
||||||
|
};
|
||||||
|
|
||||||
|
struct virtio_snd_pcm_info {
|
||||||
|
/* common header */
|
||||||
|
struct virtio_snd_info hdr;
|
||||||
|
/* supported feature bit map (1 << VIRTIO_SND_PCM_F_XXX) */
|
||||||
|
__le32 features;
|
||||||
|
/* supported sample format bit map (1 << VIRTIO_SND_PCM_FMT_XXX) */
|
||||||
|
__le64 formats;
|
||||||
|
/* supported frame rate bit map (1 << VIRTIO_SND_PCM_RATE_XXX) */
|
||||||
|
__le64 rates;
|
||||||
|
/* dataflow direction (VIRTIO_SND_D_XXX) */
|
||||||
|
__u8 direction;
|
||||||
|
/* minimum # of supported channels */
|
||||||
|
__u8 channels_min;
|
||||||
|
/* maximum # of supported channels */
|
||||||
|
__u8 channels_max;
|
||||||
|
|
||||||
|
__u8 padding[5];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* set PCM stream format */
|
||||||
|
struct virtio_snd_pcm_set_params {
|
||||||
|
/* .code = VIRTIO_SND_R_PCM_SET_PARAMS */
|
||||||
|
struct virtio_snd_pcm_hdr hdr;
|
||||||
|
/* size of the hardware buffer */
|
||||||
|
__le32 buffer_bytes;
|
||||||
|
/* size of the hardware period */
|
||||||
|
__le32 period_bytes;
|
||||||
|
/* selected feature bit map (1 << VIRTIO_SND_PCM_F_XXX) */
|
||||||
|
__le32 features;
|
||||||
|
/* selected # of channels */
|
||||||
|
__u8 channels;
|
||||||
|
/* selected sample format (VIRTIO_SND_PCM_FMT_XXX) */
|
||||||
|
__u8 format;
|
||||||
|
/* selected frame rate (VIRTIO_SND_PCM_RATE_XXX) */
|
||||||
|
__u8 rate;
|
||||||
|
|
||||||
|
__u8 padding;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* PCM I/O MESSAGES
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* I/O request header */
|
||||||
|
struct virtio_snd_pcm_xfer {
|
||||||
|
/* 0 ... virtio_snd_config::streams - 1 */
|
||||||
|
__le32 stream_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* I/O request status */
|
||||||
|
struct virtio_snd_pcm_status {
|
||||||
|
/* VIRTIO_SND_S_XXX */
|
||||||
|
__le32 status;
|
||||||
|
/* current device latency */
|
||||||
|
__le32 latency_bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* CHANNEL MAP CONTROL MESSAGES
|
||||||
|
*/
|
||||||
|
struct virtio_snd_chmap_hdr {
|
||||||
|
/* VIRTIO_SND_R_CHMAP_XXX */
|
||||||
|
struct virtio_snd_hdr hdr;
|
||||||
|
/* 0 ... virtio_snd_config::chmaps - 1 */
|
||||||
|
__le32 chmap_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* standard channel position definition */
|
||||||
|
enum {
|
||||||
|
VIRTIO_SND_CHMAP_NONE = 0, /* undefined */
|
||||||
|
VIRTIO_SND_CHMAP_NA, /* silent */
|
||||||
|
VIRTIO_SND_CHMAP_MONO, /* mono stream */
|
||||||
|
VIRTIO_SND_CHMAP_FL, /* front left */
|
||||||
|
VIRTIO_SND_CHMAP_FR, /* front right */
|
||||||
|
VIRTIO_SND_CHMAP_RL, /* rear left */
|
||||||
|
VIRTIO_SND_CHMAP_RR, /* rear right */
|
||||||
|
VIRTIO_SND_CHMAP_FC, /* front center */
|
||||||
|
VIRTIO_SND_CHMAP_LFE, /* low frequency (LFE) */
|
||||||
|
VIRTIO_SND_CHMAP_SL, /* side left */
|
||||||
|
VIRTIO_SND_CHMAP_SR, /* side right */
|
||||||
|
VIRTIO_SND_CHMAP_RC, /* rear center */
|
||||||
|
VIRTIO_SND_CHMAP_FLC, /* front left center */
|
||||||
|
VIRTIO_SND_CHMAP_FRC, /* front right center */
|
||||||
|
VIRTIO_SND_CHMAP_RLC, /* rear left center */
|
||||||
|
VIRTIO_SND_CHMAP_RRC, /* rear right center */
|
||||||
|
VIRTIO_SND_CHMAP_FLW, /* front left wide */
|
||||||
|
VIRTIO_SND_CHMAP_FRW, /* front right wide */
|
||||||
|
VIRTIO_SND_CHMAP_FLH, /* front left high */
|
||||||
|
VIRTIO_SND_CHMAP_FCH, /* front center high */
|
||||||
|
VIRTIO_SND_CHMAP_FRH, /* front right high */
|
||||||
|
VIRTIO_SND_CHMAP_TC, /* top center */
|
||||||
|
VIRTIO_SND_CHMAP_TFL, /* top front left */
|
||||||
|
VIRTIO_SND_CHMAP_TFR, /* top front right */
|
||||||
|
VIRTIO_SND_CHMAP_TFC, /* top front center */
|
||||||
|
VIRTIO_SND_CHMAP_TRL, /* top rear left */
|
||||||
|
VIRTIO_SND_CHMAP_TRR, /* top rear right */
|
||||||
|
VIRTIO_SND_CHMAP_TRC, /* top rear center */
|
||||||
|
VIRTIO_SND_CHMAP_TFLC, /* top front left center */
|
||||||
|
VIRTIO_SND_CHMAP_TFRC, /* top front right center */
|
||||||
|
VIRTIO_SND_CHMAP_TSL, /* top side left */
|
||||||
|
VIRTIO_SND_CHMAP_TSR, /* top side right */
|
||||||
|
VIRTIO_SND_CHMAP_LLFE, /* left LFE */
|
||||||
|
VIRTIO_SND_CHMAP_RLFE, /* right LFE */
|
||||||
|
VIRTIO_SND_CHMAP_BC, /* bottom center */
|
||||||
|
VIRTIO_SND_CHMAP_BLC, /* bottom left center */
|
||||||
|
VIRTIO_SND_CHMAP_BRC /* bottom right center */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* maximum possible number of channels */
|
||||||
|
#define VIRTIO_SND_CHMAP_MAX_SIZE 18
|
||||||
|
|
||||||
|
struct virtio_snd_chmap_info {
|
||||||
|
/* common header */
|
||||||
|
struct virtio_snd_info hdr;
|
||||||
|
/* dataflow direction (VIRTIO_SND_D_XXX) */
|
||||||
|
__u8 direction;
|
||||||
|
/* # of valid channel position values */
|
||||||
|
__u8 channels;
|
||||||
|
/* channel position values (VIRTIO_SND_CHMAP_XXX) */
|
||||||
|
__u8 positions[VIRTIO_SND_CHMAP_MAX_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* VIRTIO_SND_IF_H */
|
|
@ -99,6 +99,8 @@ source "sound/synth/Kconfig"
|
||||||
|
|
||||||
source "sound/xen/Kconfig"
|
source "sound/xen/Kconfig"
|
||||||
|
|
||||||
|
source "sound/virtio/Kconfig"
|
||||||
|
|
||||||
endif # SND
|
endif # SND
|
||||||
|
|
||||||
endif # !UML
|
endif # !UML
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
obj-$(CONFIG_SOUND) += soundcore.o
|
obj-$(CONFIG_SOUND) += soundcore.o
|
||||||
obj-$(CONFIG_DMASOUND) += oss/dmasound/
|
obj-$(CONFIG_DMASOUND) += oss/dmasound/
|
||||||
obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
|
obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
|
||||||
firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/ xen/
|
firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/ xen/ \
|
||||||
|
virtio/
|
||||||
obj-$(CONFIG_SND_AOA) += aoa/
|
obj-$(CONFIG_SND_AOA) += aoa/
|
||||||
|
|
||||||
# This one must be compilable even if sound is configured out
|
# This one must be compilable even if sound is configured out
|
||||||
|
|
|
@ -203,4 +203,10 @@ config SND_DMA_SGBUF
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on X86
|
depends on X86
|
||||||
|
|
||||||
|
config SND_CTL_LED
|
||||||
|
tristate
|
||||||
|
select NEW_LEDS if SND_CTL_LED
|
||||||
|
select LEDS_TRIGGERS if SND_CTL_LED
|
||||||
|
select LEDS_TRIGGER_AUDIO if SND_CTL_LED
|
||||||
|
|
||||||
source "sound/core/seq/Kconfig"
|
source "sound/core/seq/Kconfig"
|
||||||
|
|
|
@ -27,6 +27,7 @@ CFLAGS_pcm_native.o := -I$(src)
|
||||||
|
|
||||||
snd-pcm-dmaengine-objs := pcm_dmaengine.o
|
snd-pcm-dmaengine-objs := pcm_dmaengine.o
|
||||||
|
|
||||||
|
snd-ctl-led-objs := control_led.o
|
||||||
snd-rawmidi-objs := rawmidi.o
|
snd-rawmidi-objs := rawmidi.o
|
||||||
snd-timer-objs := timer.o
|
snd-timer-objs := timer.o
|
||||||
snd-hrtimer-objs := hrtimer.o
|
snd-hrtimer-objs := hrtimer.o
|
||||||
|
@ -37,6 +38,7 @@ snd-seq-device-objs := seq_device.o
|
||||||
snd-compress-objs := compress_offload.o
|
snd-compress-objs := compress_offload.o
|
||||||
|
|
||||||
obj-$(CONFIG_SND) += snd.o
|
obj-$(CONFIG_SND) += snd.o
|
||||||
|
obj-$(CONFIG_SND_CTL_LED) += snd-ctl-led.o
|
||||||
obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o
|
obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o
|
||||||
obj-$(CONFIG_SND_TIMER) += snd-timer.o
|
obj-$(CONFIG_SND_TIMER) += snd-timer.o
|
||||||
obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o
|
obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
|
@ -18,8 +19,11 @@
|
||||||
#include <sound/info.h>
|
#include <sound/info.h>
|
||||||
#include <sound/control.h>
|
#include <sound/control.h>
|
||||||
|
|
||||||
/* max number of user-defined controls */
|
// Max allocation size for user controls.
|
||||||
#define MAX_USER_CONTROLS 32
|
static int max_user_ctl_alloc_size = 8 * 1024 * 1024;
|
||||||
|
module_param_named(max_user_ctl_alloc_size, max_user_ctl_alloc_size, int, 0444);
|
||||||
|
MODULE_PARM_DESC(max_user_ctl_alloc_size, "Max allocation size for user controls");
|
||||||
|
|
||||||
#define MAX_CONTROL_COUNT 1028
|
#define MAX_CONTROL_COUNT 1028
|
||||||
|
|
||||||
struct snd_kctl_ioctl {
|
struct snd_kctl_ioctl {
|
||||||
|
@ -28,10 +32,12 @@ struct snd_kctl_ioctl {
|
||||||
};
|
};
|
||||||
|
|
||||||
static DECLARE_RWSEM(snd_ioctl_rwsem);
|
static DECLARE_RWSEM(snd_ioctl_rwsem);
|
||||||
|
static DECLARE_RWSEM(snd_ctl_layer_rwsem);
|
||||||
static LIST_HEAD(snd_control_ioctls);
|
static LIST_HEAD(snd_control_ioctls);
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
static LIST_HEAD(snd_control_compat_ioctls);
|
static LIST_HEAD(snd_control_compat_ioctls);
|
||||||
#endif
|
#endif
|
||||||
|
static struct snd_ctl_layer_ops *snd_ctl_layer;
|
||||||
|
|
||||||
static int snd_ctl_open(struct inode *inode, struct file *file)
|
static int snd_ctl_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
|
@ -181,6 +187,32 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(snd_ctl_notify);
|
EXPORT_SYMBOL(snd_ctl_notify);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_ctl_notify_one - Send notification to user-space for a control change
|
||||||
|
* @card: the card to send notification
|
||||||
|
* @mask: the event mask, SNDRV_CTL_EVENT_*
|
||||||
|
* @kctl: the pointer with the control instance
|
||||||
|
* @ioff: the additional offset to the control index
|
||||||
|
*
|
||||||
|
* This function calls snd_ctl_notify() and does additional jobs
|
||||||
|
* like LED state changes.
|
||||||
|
*/
|
||||||
|
void snd_ctl_notify_one(struct snd_card *card, unsigned int mask,
|
||||||
|
struct snd_kcontrol *kctl, unsigned int ioff)
|
||||||
|
{
|
||||||
|
struct snd_ctl_elem_id id = kctl->id;
|
||||||
|
struct snd_ctl_layer_ops *lops;
|
||||||
|
|
||||||
|
id.index += ioff;
|
||||||
|
id.numid += ioff;
|
||||||
|
snd_ctl_notify(card, mask, &id);
|
||||||
|
down_read(&snd_ctl_layer_rwsem);
|
||||||
|
for (lops = snd_ctl_layer; lops; lops = lops->next)
|
||||||
|
lops->lnotify(card, mask, kctl, ioff);
|
||||||
|
up_read(&snd_ctl_layer_rwsem);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(snd_ctl_notify_one);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_ctl_new - create a new control instance with some elements
|
* snd_ctl_new - create a new control instance with some elements
|
||||||
* @kctl: the pointer to store new control instance
|
* @kctl: the pointer to store new control instance
|
||||||
|
@ -250,6 +282,7 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
|
||||||
SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE |
|
SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE |
|
||||||
SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND |
|
SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND |
|
||||||
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK |
|
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK |
|
||||||
|
SNDRV_CTL_ELEM_ACCESS_LED_MASK |
|
||||||
SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK);
|
SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK);
|
||||||
|
|
||||||
err = snd_ctl_new(&kctl, count, access, NULL);
|
err = snd_ctl_new(&kctl, count, access, NULL);
|
||||||
|
@ -342,7 +375,6 @@ static int __snd_ctl_add_replace(struct snd_card *card,
|
||||||
{
|
{
|
||||||
struct snd_ctl_elem_id id;
|
struct snd_ctl_elem_id id;
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
unsigned int count;
|
|
||||||
struct snd_kcontrol *old;
|
struct snd_kcontrol *old;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -376,10 +408,8 @@ static int __snd_ctl_add_replace(struct snd_card *card,
|
||||||
kcontrol->id.numid = card->last_numid + 1;
|
kcontrol->id.numid = card->last_numid + 1;
|
||||||
card->last_numid += kcontrol->count;
|
card->last_numid += kcontrol->count;
|
||||||
|
|
||||||
id = kcontrol->id;
|
for (idx = 0; idx < kcontrol->count; idx++)
|
||||||
count = kcontrol->count;
|
snd_ctl_notify_one(card, SNDRV_CTL_EVENT_MASK_ADD, kcontrol, idx);
|
||||||
for (idx = 0; idx < count; idx++, id.index++, id.numid++)
|
|
||||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -462,16 +492,14 @@ EXPORT_SYMBOL(snd_ctl_replace);
|
||||||
*/
|
*/
|
||||||
int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
||||||
{
|
{
|
||||||
struct snd_ctl_elem_id id;
|
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
|
|
||||||
if (snd_BUG_ON(!card || !kcontrol))
|
if (snd_BUG_ON(!card || !kcontrol))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
list_del(&kcontrol->list);
|
list_del(&kcontrol->list);
|
||||||
card->controls_count -= kcontrol->count;
|
card->controls_count -= kcontrol->count;
|
||||||
id = kcontrol->id;
|
for (idx = 0; idx < kcontrol->count; idx++)
|
||||||
for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
|
snd_ctl_notify_one(card, SNDRV_CTL_EVENT_MASK_REMOVE, kcontrol, idx);
|
||||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_REMOVE, &id);
|
|
||||||
snd_ctl_free_one(kcontrol);
|
snd_ctl_free_one(kcontrol);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -537,9 +565,6 @@ static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
ret = snd_ctl_remove(card, kctl);
|
ret = snd_ctl_remove(card, kctl);
|
||||||
if (ret < 0)
|
|
||||||
goto error;
|
|
||||||
card->user_ctl_count--;
|
|
||||||
error:
|
error:
|
||||||
up_write(&card->controls_rwsem);
|
up_write(&card->controls_rwsem);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -584,11 +609,13 @@ int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id,
|
||||||
vd->access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
|
vd->access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
|
||||||
}
|
}
|
||||||
snd_ctl_build_ioff(id, kctl, index_offset);
|
snd_ctl_build_ioff(id, kctl, index_offset);
|
||||||
ret = 1;
|
downgrade_write(&card->controls_rwsem);
|
||||||
|
snd_ctl_notify_one(card, SNDRV_CTL_EVENT_MASK_INFO, kctl, index_offset);
|
||||||
|
up_read(&card->controls_rwsem);
|
||||||
|
return 1;
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
up_write(&card->controls_rwsem);
|
up_write(&card->controls_rwsem);
|
||||||
if (ret > 0)
|
|
||||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, id);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_ctl_activate_id);
|
EXPORT_SYMBOL_GPL(snd_ctl_activate_id);
|
||||||
|
@ -1022,7 +1049,8 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
/* drop internal access flags */
|
/* drop internal access flags */
|
||||||
info.access &= ~SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK;
|
info.access &= ~(SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK|
|
||||||
|
SNDRV_CTL_ELEM_ACCESS_LED_MASK);
|
||||||
if (copy_to_user(_info, &info, sizeof(info)))
|
if (copy_to_user(_info, &info, sizeof(info)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return result;
|
return result;
|
||||||
|
@ -1110,25 +1138,34 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
|
||||||
unsigned int index_offset;
|
unsigned int index_offset;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
down_write(&card->controls_rwsem);
|
||||||
kctl = snd_ctl_find_id(card, &control->id);
|
kctl = snd_ctl_find_id(card, &control->id);
|
||||||
if (kctl == NULL)
|
if (kctl == NULL) {
|
||||||
|
up_write(&card->controls_rwsem);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
index_offset = snd_ctl_get_ioff(kctl, &control->id);
|
index_offset = snd_ctl_get_ioff(kctl, &control->id);
|
||||||
vd = &kctl->vd[index_offset];
|
vd = &kctl->vd[index_offset];
|
||||||
if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || kctl->put == NULL ||
|
if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || kctl->put == NULL ||
|
||||||
(file && vd->owner && vd->owner != file)) {
|
(file && vd->owner && vd->owner != file)) {
|
||||||
|
up_write(&card->controls_rwsem);
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_ctl_build_ioff(&control->id, kctl, index_offset);
|
snd_ctl_build_ioff(&control->id, kctl, index_offset);
|
||||||
result = kctl->put(kctl, control);
|
result = kctl->put(kctl, control);
|
||||||
if (result < 0)
|
if (result < 0) {
|
||||||
|
up_write(&card->controls_rwsem);
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if (result > 0) {
|
if (result > 0) {
|
||||||
struct snd_ctl_elem_id id = control->id;
|
downgrade_write(&card->controls_rwsem);
|
||||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id);
|
snd_ctl_notify_one(card, SNDRV_CTL_EVENT_MASK_VALUE, kctl, index_offset);
|
||||||
|
up_read(&card->controls_rwsem);
|
||||||
|
} else {
|
||||||
|
up_write(&card->controls_rwsem);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1150,9 +1187,7 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
down_write(&card->controls_rwsem);
|
|
||||||
result = snd_ctl_elem_write(card, file, control);
|
result = snd_ctl_elem_write(card, file, control);
|
||||||
up_write(&card->controls_rwsem);
|
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -1231,6 +1266,12 @@ struct user_element {
|
||||||
void *priv_data; /* private data (like strings for enumerated type) */
|
void *priv_data; /* private data (like strings for enumerated type) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// check whether the addition (in bytes) of user ctl element may overflow the limit.
|
||||||
|
static bool check_user_elem_overflow(struct snd_card *card, ssize_t add)
|
||||||
|
{
|
||||||
|
return (ssize_t)card->user_ctl_alloc_size + add > max_user_ctl_alloc_size;
|
||||||
|
}
|
||||||
|
|
||||||
static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol,
|
static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_info *uinfo)
|
struct snd_ctl_elem_info *uinfo)
|
||||||
{
|
{
|
||||||
|
@ -1296,12 +1337,12 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* called in controls_rwsem write lock */
|
||||||
static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
|
static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
|
||||||
unsigned int size)
|
unsigned int size)
|
||||||
{
|
{
|
||||||
struct user_element *ue = kctl->private_data;
|
struct user_element *ue = kctl->private_data;
|
||||||
unsigned int *container;
|
unsigned int *container;
|
||||||
struct snd_ctl_elem_id id;
|
|
||||||
unsigned int mask = 0;
|
unsigned int mask = 0;
|
||||||
int i;
|
int i;
|
||||||
int change;
|
int change;
|
||||||
|
@ -1309,6 +1350,10 @@ static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
|
||||||
if (size > 1024 * 128) /* sane value */
|
if (size > 1024 * 128) /* sane value */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
// does the TLV size change cause overflow?
|
||||||
|
if (check_user_elem_overflow(ue->card, (ssize_t)(size - ue->tlv_data_size)))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
container = vmemdup_user(buf, size);
|
container = vmemdup_user(buf, size);
|
||||||
if (IS_ERR(container))
|
if (IS_ERR(container))
|
||||||
return PTR_ERR(container);
|
return PTR_ERR(container);
|
||||||
|
@ -1326,17 +1371,20 @@ static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
|
||||||
for (i = 0; i < kctl->count; ++i)
|
for (i = 0; i < kctl->count; ++i)
|
||||||
kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
|
kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
|
||||||
mask = SNDRV_CTL_EVENT_MASK_INFO;
|
mask = SNDRV_CTL_EVENT_MASK_INFO;
|
||||||
|
} else {
|
||||||
|
ue->card->user_ctl_alloc_size -= ue->tlv_data_size;
|
||||||
|
ue->tlv_data_size = 0;
|
||||||
|
kvfree(ue->tlv_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
kvfree(ue->tlv_data);
|
|
||||||
ue->tlv_data = container;
|
ue->tlv_data = container;
|
||||||
ue->tlv_data_size = size;
|
ue->tlv_data_size = size;
|
||||||
|
// decremented at private_free.
|
||||||
|
ue->card->user_ctl_alloc_size += size;
|
||||||
|
|
||||||
mask |= SNDRV_CTL_EVENT_MASK_TLV;
|
mask |= SNDRV_CTL_EVENT_MASK_TLV;
|
||||||
for (i = 0; i < kctl->count; ++i) {
|
for (i = 0; i < kctl->count; ++i)
|
||||||
snd_ctl_build_ioff(&id, kctl, i);
|
snd_ctl_notify_one(ue->card, mask, kctl, i);
|
||||||
snd_ctl_notify(ue->card, mask, &id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
@ -1367,6 +1415,7 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kctl, int op_flag,
|
||||||
return read_user_tlv(kctl, buf, size);
|
return read_user_tlv(kctl, buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* called in controls_rwsem write lock */
|
||||||
static int snd_ctl_elem_init_enum_names(struct user_element *ue)
|
static int snd_ctl_elem_init_enum_names(struct user_element *ue)
|
||||||
{
|
{
|
||||||
char *names, *p;
|
char *names, *p;
|
||||||
|
@ -1374,16 +1423,17 @@ static int snd_ctl_elem_init_enum_names(struct user_element *ue)
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
const uintptr_t user_ptrval = ue->info.value.enumerated.names_ptr;
|
const uintptr_t user_ptrval = ue->info.value.enumerated.names_ptr;
|
||||||
|
|
||||||
if (ue->info.value.enumerated.names_length > 64 * 1024)
|
buf_len = ue->info.value.enumerated.names_length;
|
||||||
|
if (buf_len > 64 * 1024)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
names = vmemdup_user((const void __user *)user_ptrval,
|
if (check_user_elem_overflow(ue->card, buf_len))
|
||||||
ue->info.value.enumerated.names_length);
|
return -ENOMEM;
|
||||||
|
names = vmemdup_user((const void __user *)user_ptrval, buf_len);
|
||||||
if (IS_ERR(names))
|
if (IS_ERR(names))
|
||||||
return PTR_ERR(names);
|
return PTR_ERR(names);
|
||||||
|
|
||||||
/* check that there are enough valid names */
|
/* check that there are enough valid names */
|
||||||
buf_len = ue->info.value.enumerated.names_length;
|
|
||||||
p = names;
|
p = names;
|
||||||
for (i = 0; i < ue->info.value.enumerated.items; ++i) {
|
for (i = 0; i < ue->info.value.enumerated.items; ++i) {
|
||||||
name_len = strnlen(p, buf_len);
|
name_len = strnlen(p, buf_len);
|
||||||
|
@ -1397,14 +1447,27 @@ static int snd_ctl_elem_init_enum_names(struct user_element *ue)
|
||||||
|
|
||||||
ue->priv_data = names;
|
ue->priv_data = names;
|
||||||
ue->info.value.enumerated.names_ptr = 0;
|
ue->info.value.enumerated.names_ptr = 0;
|
||||||
|
// increment the allocation size; decremented again at private_free.
|
||||||
|
ue->card->user_ctl_alloc_size += ue->info.value.enumerated.names_length;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t compute_user_elem_size(size_t size, unsigned int count)
|
||||||
|
{
|
||||||
|
return sizeof(struct user_element) + size * count;
|
||||||
|
}
|
||||||
|
|
||||||
static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol)
|
static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol)
|
||||||
{
|
{
|
||||||
struct user_element *ue = kcontrol->private_data;
|
struct user_element *ue = kcontrol->private_data;
|
||||||
|
|
||||||
|
// decrement the allocation size.
|
||||||
|
ue->card->user_ctl_alloc_size -= compute_user_elem_size(ue->elem_data_size, kcontrol->count);
|
||||||
|
ue->card->user_ctl_alloc_size -= ue->tlv_data_size;
|
||||||
|
if (ue->priv_data)
|
||||||
|
ue->card->user_ctl_alloc_size -= ue->info.value.enumerated.names_length;
|
||||||
|
|
||||||
kvfree(ue->tlv_data);
|
kvfree(ue->tlv_data);
|
||||||
kvfree(ue->priv_data);
|
kvfree(ue->priv_data);
|
||||||
kfree(ue);
|
kfree(ue);
|
||||||
|
@ -1418,6 +1481,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
unsigned int access;
|
unsigned int access;
|
||||||
long private_size;
|
long private_size;
|
||||||
|
size_t alloc_size;
|
||||||
struct user_element *ue;
|
struct user_element *ue;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
int err;
|
int err;
|
||||||
|
@ -1435,13 +1499,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The number of userspace controls are counted control by control,
|
|
||||||
* not element by element.
|
|
||||||
*/
|
|
||||||
if (card->user_ctl_count + 1 > MAX_USER_CONTROLS)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
/* Check the number of elements for this userspace control. */
|
/* Check the number of elements for this userspace control. */
|
||||||
count = info->owner;
|
count = info->owner;
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
|
@ -1472,6 +1529,13 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||||
if (info->count < 1)
|
if (info->count < 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
private_size = value_sizes[info->type] * info->count;
|
private_size = value_sizes[info->type] * info->count;
|
||||||
|
alloc_size = compute_user_elem_size(private_size, count);
|
||||||
|
|
||||||
|
down_write(&card->controls_rwsem);
|
||||||
|
if (check_user_elem_overflow(card, alloc_size)) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep memory object for this userspace control. After passing this
|
* Keep memory object for this userspace control. After passing this
|
||||||
|
@ -1481,18 +1545,21 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||||
*/
|
*/
|
||||||
err = snd_ctl_new(&kctl, count, access, file);
|
err = snd_ctl_new(&kctl, count, access, file);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
goto unlock;
|
||||||
memcpy(&kctl->id, &info->id, sizeof(kctl->id));
|
memcpy(&kctl->id, &info->id, sizeof(kctl->id));
|
||||||
kctl->private_data = kzalloc(sizeof(struct user_element) + private_size * count,
|
ue = kzalloc(alloc_size, GFP_KERNEL);
|
||||||
GFP_KERNEL);
|
if (!ue) {
|
||||||
if (kctl->private_data == NULL) {
|
|
||||||
kfree(kctl);
|
kfree(kctl);
|
||||||
return -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
kctl->private_data = ue;
|
||||||
kctl->private_free = snd_ctl_elem_user_free;
|
kctl->private_free = snd_ctl_elem_user_free;
|
||||||
|
|
||||||
|
// increment the allocated size; decremented again at private_free.
|
||||||
|
card->user_ctl_alloc_size += alloc_size;
|
||||||
|
|
||||||
/* Set private data for this userspace control. */
|
/* Set private data for this userspace control. */
|
||||||
ue = (struct user_element *)kctl->private_data;
|
|
||||||
ue->card = card;
|
ue->card = card;
|
||||||
ue->info = *info;
|
ue->info = *info;
|
||||||
ue->info.access = 0;
|
ue->info.access = 0;
|
||||||
|
@ -1502,7 +1569,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||||
err = snd_ctl_elem_init_enum_names(ue);
|
err = snd_ctl_elem_init_enum_names(ue);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
snd_ctl_free_one(kctl);
|
snd_ctl_free_one(kctl);
|
||||||
return err;
|
goto unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1519,7 +1586,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||||
kctl->tlv.c = snd_ctl_elem_user_tlv;
|
kctl->tlv.c = snd_ctl_elem_user_tlv;
|
||||||
|
|
||||||
/* This function manage to free the instance on failure. */
|
/* This function manage to free the instance on failure. */
|
||||||
down_write(&card->controls_rwsem);
|
|
||||||
err = __snd_ctl_add_replace(card, kctl, CTL_ADD_EXCLUSIVE);
|
err = __snd_ctl_add_replace(card, kctl, CTL_ADD_EXCLUSIVE);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
snd_ctl_free_one(kctl);
|
snd_ctl_free_one(kctl);
|
||||||
|
@ -1534,9 +1600,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||||
* applications because the field originally means PID of a process
|
* applications because the field originally means PID of a process
|
||||||
* which locks the element.
|
* which locks the element.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
card->user_ctl_count++;
|
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
up_write(&card->controls_rwsem);
|
up_write(&card->controls_rwsem);
|
||||||
return err;
|
return err;
|
||||||
|
@ -1975,6 +2038,88 @@ EXPORT_SYMBOL_GPL(snd_ctl_get_preferred_subdevice);
|
||||||
#define snd_ctl_ioctl_compat NULL
|
#define snd_ctl_ioctl_compat NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* control layers (audio LED etc.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_ctl_request_layer - request to use the layer
|
||||||
|
* @module_name: Name of the kernel module (NULL == build-in)
|
||||||
|
*
|
||||||
|
* Return an error code when the module cannot be loaded.
|
||||||
|
*/
|
||||||
|
int snd_ctl_request_layer(const char *module_name)
|
||||||
|
{
|
||||||
|
struct snd_ctl_layer_ops *lops;
|
||||||
|
|
||||||
|
if (module_name == NULL)
|
||||||
|
return 0;
|
||||||
|
down_read(&snd_ctl_layer_rwsem);
|
||||||
|
for (lops = snd_ctl_layer; lops; lops = lops->next)
|
||||||
|
if (strcmp(lops->module_name, module_name) == 0)
|
||||||
|
break;
|
||||||
|
up_read(&snd_ctl_layer_rwsem);
|
||||||
|
if (lops)
|
||||||
|
return 0;
|
||||||
|
return request_module(module_name);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_ctl_request_layer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_ctl_register_layer - register new control layer
|
||||||
|
* @lops: operation structure
|
||||||
|
*
|
||||||
|
* The new layer can track all control elements and do additional
|
||||||
|
* operations on top (like audio LED handling).
|
||||||
|
*/
|
||||||
|
void snd_ctl_register_layer(struct snd_ctl_layer_ops *lops)
|
||||||
|
{
|
||||||
|
struct snd_card *card;
|
||||||
|
int card_number;
|
||||||
|
|
||||||
|
down_write(&snd_ctl_layer_rwsem);
|
||||||
|
lops->next = snd_ctl_layer;
|
||||||
|
snd_ctl_layer = lops;
|
||||||
|
up_write(&snd_ctl_layer_rwsem);
|
||||||
|
for (card_number = 0; card_number < SNDRV_CARDS; card_number++) {
|
||||||
|
card = snd_card_ref(card_number);
|
||||||
|
if (card) {
|
||||||
|
down_read(&card->controls_rwsem);
|
||||||
|
lops->lregister(card);
|
||||||
|
up_read(&card->controls_rwsem);
|
||||||
|
snd_card_unref(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_ctl_register_layer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_ctl_disconnect_layer - disconnect control layer
|
||||||
|
* @lops: operation structure
|
||||||
|
*
|
||||||
|
* It is expected that the information about tracked cards
|
||||||
|
* is freed before this call (the disconnect callback is
|
||||||
|
* not called here).
|
||||||
|
*/
|
||||||
|
void snd_ctl_disconnect_layer(struct snd_ctl_layer_ops *lops)
|
||||||
|
{
|
||||||
|
struct snd_ctl_layer_ops *lops2, *prev_lops2;
|
||||||
|
|
||||||
|
down_write(&snd_ctl_layer_rwsem);
|
||||||
|
for (lops2 = snd_ctl_layer, prev_lops2 = NULL; lops2; lops2 = lops2->next) {
|
||||||
|
if (lops2 == lops) {
|
||||||
|
if (!prev_lops2)
|
||||||
|
snd_ctl_layer = lops->next;
|
||||||
|
else
|
||||||
|
prev_lops2->next = lops->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev_lops2 = lops2;
|
||||||
|
}
|
||||||
|
up_write(&snd_ctl_layer_rwsem);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_ctl_disconnect_layer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* INIT PART
|
* INIT PART
|
||||||
*/
|
*/
|
||||||
|
@ -1998,9 +2143,20 @@ static const struct file_operations snd_ctl_f_ops =
|
||||||
static int snd_ctl_dev_register(struct snd_device *device)
|
static int snd_ctl_dev_register(struct snd_device *device)
|
||||||
{
|
{
|
||||||
struct snd_card *card = device->device_data;
|
struct snd_card *card = device->device_data;
|
||||||
|
struct snd_ctl_layer_ops *lops;
|
||||||
|
int err;
|
||||||
|
|
||||||
return snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
|
err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
|
||||||
&snd_ctl_f_ops, card, &card->ctl_dev);
|
&snd_ctl_f_ops, card, &card->ctl_dev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
down_read(&card->controls_rwsem);
|
||||||
|
down_read(&snd_ctl_layer_rwsem);
|
||||||
|
for (lops = snd_ctl_layer; lops; lops = lops->next)
|
||||||
|
lops->lregister(card);
|
||||||
|
up_read(&snd_ctl_layer_rwsem);
|
||||||
|
up_read(&card->controls_rwsem);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2010,6 +2166,7 @@ static int snd_ctl_dev_disconnect(struct snd_device *device)
|
||||||
{
|
{
|
||||||
struct snd_card *card = device->device_data;
|
struct snd_card *card = device->device_data;
|
||||||
struct snd_ctl_file *ctl;
|
struct snd_ctl_file *ctl;
|
||||||
|
struct snd_ctl_layer_ops *lops;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
read_lock_irqsave(&card->ctl_files_rwlock, flags);
|
read_lock_irqsave(&card->ctl_files_rwlock, flags);
|
||||||
|
@ -2019,6 +2176,13 @@ static int snd_ctl_dev_disconnect(struct snd_device *device)
|
||||||
}
|
}
|
||||||
read_unlock_irqrestore(&card->ctl_files_rwlock, flags);
|
read_unlock_irqrestore(&card->ctl_files_rwlock, flags);
|
||||||
|
|
||||||
|
down_read(&card->controls_rwsem);
|
||||||
|
down_read(&snd_ctl_layer_rwsem);
|
||||||
|
for (lops = snd_ctl_layer; lops; lops = lops->next)
|
||||||
|
lops->ldisconnect(card);
|
||||||
|
up_read(&snd_ctl_layer_rwsem);
|
||||||
|
up_read(&card->controls_rwsem);
|
||||||
|
|
||||||
return snd_unregister_device(&card->ctl_dev);
|
return snd_unregister_device(&card->ctl_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
777
sound/core/control_led.c
Normal file
777
sound/core/control_led.c
Normal file
|
@ -0,0 +1,777 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/*
|
||||||
|
* LED state routines for driver control interface
|
||||||
|
* Copyright (c) 2021 by Jaroslav Kysela <perex@perex.cz>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/leds.h>
|
||||||
|
#include <sound/core.h>
|
||||||
|
#include <sound/control.h>
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
|
||||||
|
MODULE_DESCRIPTION("ALSA control interface to LED trigger code.");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
#define MAX_LED (((SNDRV_CTL_ELEM_ACCESS_MIC_LED - SNDRV_CTL_ELEM_ACCESS_SPK_LED) \
|
||||||
|
>> SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) + 1)
|
||||||
|
|
||||||
|
enum snd_ctl_led_mode {
|
||||||
|
MODE_FOLLOW_MUTE = 0,
|
||||||
|
MODE_FOLLOW_ROUTE,
|
||||||
|
MODE_OFF,
|
||||||
|
MODE_ON,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct snd_ctl_led_card {
|
||||||
|
struct device dev;
|
||||||
|
int number;
|
||||||
|
struct snd_ctl_led *led;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct snd_ctl_led {
|
||||||
|
struct device dev;
|
||||||
|
struct list_head controls;
|
||||||
|
const char *name;
|
||||||
|
unsigned int group;
|
||||||
|
enum led_audio trigger_type;
|
||||||
|
enum snd_ctl_led_mode mode;
|
||||||
|
struct snd_ctl_led_card *cards[SNDRV_CARDS];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct snd_ctl_led_ctl {
|
||||||
|
struct list_head list;
|
||||||
|
struct snd_card *card;
|
||||||
|
unsigned int access;
|
||||||
|
struct snd_kcontrol *kctl;
|
||||||
|
unsigned int index_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
static DEFINE_MUTEX(snd_ctl_led_mutex);
|
||||||
|
static bool snd_ctl_led_card_valid[SNDRV_CARDS];
|
||||||
|
static struct snd_ctl_led snd_ctl_leds[MAX_LED] = {
|
||||||
|
{
|
||||||
|
.name = "speaker",
|
||||||
|
.group = (SNDRV_CTL_ELEM_ACCESS_SPK_LED >> SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) - 1,
|
||||||
|
.trigger_type = LED_AUDIO_MUTE,
|
||||||
|
.mode = MODE_FOLLOW_MUTE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "mic",
|
||||||
|
.group = (SNDRV_CTL_ELEM_ACCESS_MIC_LED >> SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) - 1,
|
||||||
|
.trigger_type = LED_AUDIO_MICMUTE,
|
||||||
|
.mode = MODE_FOLLOW_MUTE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void snd_ctl_led_sysfs_add(struct snd_card *card);
|
||||||
|
static void snd_ctl_led_sysfs_remove(struct snd_card *card);
|
||||||
|
|
||||||
|
#define UPDATE_ROUTE(route, cb) \
|
||||||
|
do { \
|
||||||
|
int route2 = (cb); \
|
||||||
|
if (route2 >= 0) \
|
||||||
|
route = route < 0 ? route2 : (route | route2); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static inline unsigned int access_to_group(unsigned int access)
|
||||||
|
{
|
||||||
|
return ((access & SNDRV_CTL_ELEM_ACCESS_LED_MASK) >>
|
||||||
|
SNDRV_CTL_ELEM_ACCESS_LED_SHIFT) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned int group_to_access(unsigned int group)
|
||||||
|
{
|
||||||
|
return (group + 1) << SNDRV_CTL_ELEM_ACCESS_LED_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct snd_ctl_led *snd_ctl_led_get_by_access(unsigned int access)
|
||||||
|
{
|
||||||
|
unsigned int group = access_to_group(access);
|
||||||
|
if (group >= MAX_LED)
|
||||||
|
return NULL;
|
||||||
|
return &snd_ctl_leds[group];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A note for callers:
|
||||||
|
* The two static variables info and value are protected using snd_ctl_led_mutex.
|
||||||
|
*/
|
||||||
|
static int snd_ctl_led_get(struct snd_ctl_led_ctl *lctl)
|
||||||
|
{
|
||||||
|
static struct snd_ctl_elem_info info;
|
||||||
|
static struct snd_ctl_elem_value value;
|
||||||
|
struct snd_kcontrol *kctl = lctl->kctl;
|
||||||
|
unsigned int i;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
info.id = kctl->id;
|
||||||
|
info.id.index += lctl->index_offset;
|
||||||
|
info.id.numid += lctl->index_offset;
|
||||||
|
result = kctl->info(kctl, &info);
|
||||||
|
if (result < 0)
|
||||||
|
return -1;
|
||||||
|
memset(&value, 0, sizeof(value));
|
||||||
|
value.id = info.id;
|
||||||
|
result = kctl->get(kctl, &value);
|
||||||
|
if (result < 0)
|
||||||
|
return -1;
|
||||||
|
if (info.type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
|
||||||
|
info.type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
|
||||||
|
for (i = 0; i < info.count; i++)
|
||||||
|
if (value.value.integer.value[i] != info.value.integer.min)
|
||||||
|
return 1;
|
||||||
|
} else if (info.type == SNDRV_CTL_ELEM_TYPE_INTEGER64) {
|
||||||
|
for (i = 0; i < info.count; i++)
|
||||||
|
if (value.value.integer64.value[i] != info.value.integer64.min)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snd_ctl_led_set_state(struct snd_card *card, unsigned int access,
|
||||||
|
struct snd_kcontrol *kctl, unsigned int ioff)
|
||||||
|
{
|
||||||
|
struct snd_ctl_led *led;
|
||||||
|
struct snd_ctl_led_ctl *lctl;
|
||||||
|
int route;
|
||||||
|
bool found;
|
||||||
|
|
||||||
|
led = snd_ctl_led_get_by_access(access);
|
||||||
|
if (!led)
|
||||||
|
return;
|
||||||
|
route = -1;
|
||||||
|
found = false;
|
||||||
|
mutex_lock(&snd_ctl_led_mutex);
|
||||||
|
/* the card may not be registered (active) at this point */
|
||||||
|
if (card && !snd_ctl_led_card_valid[card->number]) {
|
||||||
|
mutex_unlock(&snd_ctl_led_mutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
list_for_each_entry(lctl, &led->controls, list) {
|
||||||
|
if (lctl->kctl == kctl && lctl->index_offset == ioff)
|
||||||
|
found = true;
|
||||||
|
UPDATE_ROUTE(route, snd_ctl_led_get(lctl));
|
||||||
|
}
|
||||||
|
if (!found && kctl && card) {
|
||||||
|
lctl = kzalloc(sizeof(*lctl), GFP_KERNEL);
|
||||||
|
if (lctl) {
|
||||||
|
lctl->card = card;
|
||||||
|
lctl->access = access;
|
||||||
|
lctl->kctl = kctl;
|
||||||
|
lctl->index_offset = ioff;
|
||||||
|
list_add(&lctl->list, &led->controls);
|
||||||
|
UPDATE_ROUTE(route, snd_ctl_led_get(lctl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&snd_ctl_led_mutex);
|
||||||
|
switch (led->mode) {
|
||||||
|
case MODE_OFF: route = 1; break;
|
||||||
|
case MODE_ON: route = 0; break;
|
||||||
|
case MODE_FOLLOW_ROUTE: if (route >= 0) route ^= 1; break;
|
||||||
|
case MODE_FOLLOW_MUTE: /* noop */ break;
|
||||||
|
}
|
||||||
|
if (route >= 0)
|
||||||
|
ledtrig_audio_set(led->trigger_type, route ? LED_OFF : LED_ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct snd_ctl_led_ctl *snd_ctl_led_find(struct snd_kcontrol *kctl, unsigned int ioff)
|
||||||
|
{
|
||||||
|
struct list_head *controls;
|
||||||
|
struct snd_ctl_led_ctl *lctl;
|
||||||
|
unsigned int group;
|
||||||
|
|
||||||
|
for (group = 0; group < MAX_LED; group++) {
|
||||||
|
controls = &snd_ctl_leds[group].controls;
|
||||||
|
list_for_each_entry(lctl, controls, list)
|
||||||
|
if (lctl->kctl == kctl && lctl->index_offset == ioff)
|
||||||
|
return lctl;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int snd_ctl_led_remove(struct snd_kcontrol *kctl, unsigned int ioff,
|
||||||
|
unsigned int access)
|
||||||
|
{
|
||||||
|
struct snd_ctl_led_ctl *lctl;
|
||||||
|
unsigned int ret = 0;
|
||||||
|
|
||||||
|
mutex_lock(&snd_ctl_led_mutex);
|
||||||
|
lctl = snd_ctl_led_find(kctl, ioff);
|
||||||
|
if (lctl && (access == 0 || access != lctl->access)) {
|
||||||
|
ret = lctl->access;
|
||||||
|
list_del(&lctl->list);
|
||||||
|
kfree(lctl);
|
||||||
|
}
|
||||||
|
mutex_unlock(&snd_ctl_led_mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snd_ctl_led_notify(struct snd_card *card, unsigned int mask,
|
||||||
|
struct snd_kcontrol *kctl, unsigned int ioff)
|
||||||
|
{
|
||||||
|
struct snd_kcontrol_volatile *vd;
|
||||||
|
unsigned int access, access2;
|
||||||
|
|
||||||
|
if (mask == SNDRV_CTL_EVENT_MASK_REMOVE) {
|
||||||
|
access = snd_ctl_led_remove(kctl, ioff, 0);
|
||||||
|
if (access)
|
||||||
|
snd_ctl_led_set_state(card, access, NULL, 0);
|
||||||
|
} else if (mask & SNDRV_CTL_EVENT_MASK_INFO) {
|
||||||
|
vd = &kctl->vd[ioff];
|
||||||
|
access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK;
|
||||||
|
access2 = snd_ctl_led_remove(kctl, ioff, access);
|
||||||
|
if (access2)
|
||||||
|
snd_ctl_led_set_state(card, access2, NULL, 0);
|
||||||
|
if (access)
|
||||||
|
snd_ctl_led_set_state(card, access, kctl, ioff);
|
||||||
|
} else if ((mask & (SNDRV_CTL_EVENT_MASK_ADD |
|
||||||
|
SNDRV_CTL_EVENT_MASK_VALUE)) != 0) {
|
||||||
|
vd = &kctl->vd[ioff];
|
||||||
|
access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK;
|
||||||
|
if (access)
|
||||||
|
snd_ctl_led_set_state(card, access, kctl, ioff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int snd_ctl_led_set_id(int card_number, struct snd_ctl_elem_id *id,
|
||||||
|
unsigned int group, bool set)
|
||||||
|
{
|
||||||
|
struct snd_card *card;
|
||||||
|
struct snd_kcontrol *kctl;
|
||||||
|
struct snd_kcontrol_volatile *vd;
|
||||||
|
unsigned int ioff, access, new_access;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
card = snd_card_ref(card_number);
|
||||||
|
if (card) {
|
||||||
|
down_write(&card->controls_rwsem);
|
||||||
|
kctl = snd_ctl_find_id(card, id);
|
||||||
|
if (kctl) {
|
||||||
|
ioff = snd_ctl_get_ioff(kctl, id);
|
||||||
|
vd = &kctl->vd[ioff];
|
||||||
|
access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK;
|
||||||
|
if (access != 0 && access != group_to_access(group)) {
|
||||||
|
err = -EXDEV;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
new_access = vd->access & ~SNDRV_CTL_ELEM_ACCESS_LED_MASK;
|
||||||
|
if (set)
|
||||||
|
new_access |= group_to_access(group);
|
||||||
|
if (new_access != vd->access) {
|
||||||
|
vd->access = new_access;
|
||||||
|
snd_ctl_led_notify(card, SNDRV_CTL_EVENT_MASK_INFO, kctl, ioff);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = -ENOENT;
|
||||||
|
}
|
||||||
|
unlock:
|
||||||
|
up_write(&card->controls_rwsem);
|
||||||
|
snd_card_unref(card);
|
||||||
|
} else {
|
||||||
|
err = -ENXIO;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snd_ctl_led_refresh(void)
|
||||||
|
{
|
||||||
|
unsigned int group;
|
||||||
|
|
||||||
|
for (group = 0; group < MAX_LED; group++)
|
||||||
|
snd_ctl_led_set_state(NULL, group_to_access(group), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snd_ctl_led_ctl_destroy(struct snd_ctl_led_ctl *lctl)
|
||||||
|
{
|
||||||
|
list_del(&lctl->list);
|
||||||
|
kfree(lctl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snd_ctl_led_clean(struct snd_card *card)
|
||||||
|
{
|
||||||
|
unsigned int group;
|
||||||
|
struct snd_ctl_led *led;
|
||||||
|
struct snd_ctl_led_ctl *lctl;
|
||||||
|
|
||||||
|
for (group = 0; group < MAX_LED; group++) {
|
||||||
|
led = &snd_ctl_leds[group];
|
||||||
|
repeat:
|
||||||
|
list_for_each_entry(lctl, &led->controls, list)
|
||||||
|
if (!card || lctl->card == card) {
|
||||||
|
snd_ctl_led_ctl_destroy(lctl);
|
||||||
|
goto repeat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int snd_ctl_led_reset(int card_number, unsigned int group)
|
||||||
|
{
|
||||||
|
struct snd_card *card;
|
||||||
|
struct snd_ctl_led *led;
|
||||||
|
struct snd_ctl_led_ctl *lctl;
|
||||||
|
struct snd_kcontrol_volatile *vd;
|
||||||
|
bool change = false;
|
||||||
|
|
||||||
|
card = snd_card_ref(card_number);
|
||||||
|
if (!card)
|
||||||
|
return -ENXIO;
|
||||||
|
|
||||||
|
mutex_lock(&snd_ctl_led_mutex);
|
||||||
|
if (!snd_ctl_led_card_valid[card_number]) {
|
||||||
|
mutex_unlock(&snd_ctl_led_mutex);
|
||||||
|
snd_card_unref(card);
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
led = &snd_ctl_leds[group];
|
||||||
|
repeat:
|
||||||
|
list_for_each_entry(lctl, &led->controls, list)
|
||||||
|
if (lctl->card == card) {
|
||||||
|
vd = &lctl->kctl->vd[lctl->index_offset];
|
||||||
|
vd->access &= ~group_to_access(group);
|
||||||
|
snd_ctl_led_ctl_destroy(lctl);
|
||||||
|
change = true;
|
||||||
|
goto repeat;
|
||||||
|
}
|
||||||
|
mutex_unlock(&snd_ctl_led_mutex);
|
||||||
|
if (change)
|
||||||
|
snd_ctl_led_set_state(NULL, group_to_access(group), NULL, 0);
|
||||||
|
snd_card_unref(card);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snd_ctl_led_register(struct snd_card *card)
|
||||||
|
{
|
||||||
|
struct snd_kcontrol *kctl;
|
||||||
|
unsigned int ioff;
|
||||||
|
|
||||||
|
if (snd_BUG_ON(card->number < 0 ||
|
||||||
|
card->number >= ARRAY_SIZE(snd_ctl_led_card_valid)))
|
||||||
|
return;
|
||||||
|
mutex_lock(&snd_ctl_led_mutex);
|
||||||
|
snd_ctl_led_card_valid[card->number] = true;
|
||||||
|
mutex_unlock(&snd_ctl_led_mutex);
|
||||||
|
/* the register callback is already called with held card->controls_rwsem */
|
||||||
|
list_for_each_entry(kctl, &card->controls, list)
|
||||||
|
for (ioff = 0; ioff < kctl->count; ioff++)
|
||||||
|
snd_ctl_led_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, kctl, ioff);
|
||||||
|
snd_ctl_led_refresh();
|
||||||
|
snd_ctl_led_sysfs_add(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snd_ctl_led_disconnect(struct snd_card *card)
|
||||||
|
{
|
||||||
|
snd_ctl_led_sysfs_remove(card);
|
||||||
|
mutex_lock(&snd_ctl_led_mutex);
|
||||||
|
snd_ctl_led_card_valid[card->number] = false;
|
||||||
|
snd_ctl_led_clean(card);
|
||||||
|
mutex_unlock(&snd_ctl_led_mutex);
|
||||||
|
snd_ctl_led_refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sysfs
|
||||||
|
*/
|
||||||
|
|
||||||
|
static ssize_t show_mode(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev);
|
||||||
|
const char *str;
|
||||||
|
|
||||||
|
switch (led->mode) {
|
||||||
|
case MODE_FOLLOW_MUTE: str = "follow-mute"; break;
|
||||||
|
case MODE_FOLLOW_ROUTE: str = "follow-route"; break;
|
||||||
|
case MODE_ON: str = "on"; break;
|
||||||
|
case MODE_OFF: str = "off"; break;
|
||||||
|
}
|
||||||
|
return sprintf(buf, "%s\n", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t store_mode(struct device *dev, struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev);
|
||||||
|
char _buf[16];
|
||||||
|
size_t l = min(count, sizeof(_buf) - 1);
|
||||||
|
enum snd_ctl_led_mode mode;
|
||||||
|
|
||||||
|
memcpy(_buf, buf, l);
|
||||||
|
_buf[l] = '\0';
|
||||||
|
if (strstr(_buf, "mute"))
|
||||||
|
mode = MODE_FOLLOW_MUTE;
|
||||||
|
else if (strstr(_buf, "route"))
|
||||||
|
mode = MODE_FOLLOW_ROUTE;
|
||||||
|
else if (strncmp(_buf, "off", 3) == 0 || strncmp(_buf, "0", 1) == 0)
|
||||||
|
mode = MODE_OFF;
|
||||||
|
else if (strncmp(_buf, "on", 2) == 0 || strncmp(_buf, "1", 1) == 0)
|
||||||
|
mode = MODE_ON;
|
||||||
|
else
|
||||||
|
return count;
|
||||||
|
|
||||||
|
mutex_lock(&snd_ctl_led_mutex);
|
||||||
|
led->mode = mode;
|
||||||
|
mutex_unlock(&snd_ctl_led_mutex);
|
||||||
|
|
||||||
|
snd_ctl_led_set_state(NULL, group_to_access(led->group), NULL, 0);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t show_brightness(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct snd_ctl_led *led = container_of(dev, struct snd_ctl_led, dev);
|
||||||
|
|
||||||
|
return sprintf(buf, "%u\n", ledtrig_audio_get(led->trigger_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(mode, 0644, show_mode, store_mode);
|
||||||
|
static DEVICE_ATTR(brightness, 0444, show_brightness, NULL);
|
||||||
|
|
||||||
|
static struct attribute *snd_ctl_led_dev_attrs[] = {
|
||||||
|
&dev_attr_mode.attr,
|
||||||
|
&dev_attr_brightness.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attribute_group snd_ctl_led_dev_attr_group = {
|
||||||
|
.attrs = snd_ctl_led_dev_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attribute_group *snd_ctl_led_dev_attr_groups[] = {
|
||||||
|
&snd_ctl_led_dev_attr_group,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *find_eos(char *s)
|
||||||
|
{
|
||||||
|
while (*s && *s != ',')
|
||||||
|
s++;
|
||||||
|
if (*s)
|
||||||
|
s++;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *parse_uint(char *s, unsigned int *val)
|
||||||
|
{
|
||||||
|
unsigned long long res;
|
||||||
|
if (kstrtoull(s, 10, &res))
|
||||||
|
res = 0;
|
||||||
|
*val = res;
|
||||||
|
return find_eos(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *parse_string(char *s, char *val, size_t val_size)
|
||||||
|
{
|
||||||
|
if (*s == '"' || *s == '\'') {
|
||||||
|
char c = *s;
|
||||||
|
s++;
|
||||||
|
while (*s && *s != c) {
|
||||||
|
if (val_size > 1) {
|
||||||
|
*val++ = *s;
|
||||||
|
val_size--;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (*s && *s != ',') {
|
||||||
|
if (val_size > 1) {
|
||||||
|
*val++ = *s;
|
||||||
|
val_size--;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*val = '\0';
|
||||||
|
if (*s)
|
||||||
|
s++;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *parse_iface(char *s, unsigned int *val)
|
||||||
|
{
|
||||||
|
if (!strncasecmp(s, "card", 4))
|
||||||
|
*val = SNDRV_CTL_ELEM_IFACE_CARD;
|
||||||
|
else if (!strncasecmp(s, "mixer", 5))
|
||||||
|
*val = SNDRV_CTL_ELEM_IFACE_MIXER;
|
||||||
|
return find_eos(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These types of input strings are accepted:
|
||||||
|
*
|
||||||
|
* unsigned integer - numid (equivaled to numid=UINT)
|
||||||
|
* string - basic mixer name (equivalent to iface=MIXER,name=STR)
|
||||||
|
* numid=UINT
|
||||||
|
* [iface=MIXER,][device=UINT,][subdevice=UINT,]name=STR[,index=UINT]
|
||||||
|
*/
|
||||||
|
static ssize_t set_led_id(struct snd_ctl_led_card *led_card, const char *buf, size_t count,
|
||||||
|
bool attach)
|
||||||
|
{
|
||||||
|
char buf2[256], *s, *os;
|
||||||
|
size_t len = max(sizeof(s) - 1, count);
|
||||||
|
struct snd_ctl_elem_id id;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
strncpy(buf2, buf, len);
|
||||||
|
buf2[len] = '\0';
|
||||||
|
memset(&id, 0, sizeof(id));
|
||||||
|
id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
|
||||||
|
s = buf2;
|
||||||
|
while (*s) {
|
||||||
|
os = s;
|
||||||
|
if (!strncasecmp(s, "numid=", 6)) {
|
||||||
|
s = parse_uint(s + 6, &id.numid);
|
||||||
|
} else if (!strncasecmp(s, "iface=", 6)) {
|
||||||
|
s = parse_iface(s + 6, &id.iface);
|
||||||
|
} else if (!strncasecmp(s, "device=", 7)) {
|
||||||
|
s = parse_uint(s + 7, &id.device);
|
||||||
|
} else if (!strncasecmp(s, "subdevice=", 10)) {
|
||||||
|
s = parse_uint(s + 10, &id.subdevice);
|
||||||
|
} else if (!strncasecmp(s, "name=", 5)) {
|
||||||
|
s = parse_string(s + 5, id.name, sizeof(id.name));
|
||||||
|
} else if (!strncasecmp(s, "index=", 6)) {
|
||||||
|
s = parse_uint(s + 6, &id.index);
|
||||||
|
} else if (s == buf2) {
|
||||||
|
while (*s) {
|
||||||
|
if (*s < '0' || *s > '9')
|
||||||
|
break;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
if (*s == '\0')
|
||||||
|
parse_uint(buf2, &id.numid);
|
||||||
|
else {
|
||||||
|
for (; *s >= ' '; s++);
|
||||||
|
*s = '\0';
|
||||||
|
strlcpy(id.name, buf2, sizeof(id.name));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*s == ',')
|
||||||
|
s++;
|
||||||
|
if (s == os)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = snd_ctl_led_set_id(led_card->number, &id, led_card->led->group, attach);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t parse_attach(struct device *dev, struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
|
||||||
|
return set_led_id(led_card, buf, count, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t parse_detach(struct device *dev, struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
|
||||||
|
return set_led_id(led_card, buf, count, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t ctl_reset(struct device *dev, struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (count > 0 && buf[0] == '1') {
|
||||||
|
err = snd_ctl_led_reset(led_card->number, led_card->led->group);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t ctl_list(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
|
||||||
|
struct snd_card *card;
|
||||||
|
struct snd_ctl_led_ctl *lctl;
|
||||||
|
char *buf2 = buf;
|
||||||
|
size_t l;
|
||||||
|
|
||||||
|
card = snd_card_ref(led_card->number);
|
||||||
|
if (!card)
|
||||||
|
return -ENXIO;
|
||||||
|
down_read(&card->controls_rwsem);
|
||||||
|
mutex_lock(&snd_ctl_led_mutex);
|
||||||
|
if (snd_ctl_led_card_valid[led_card->number]) {
|
||||||
|
list_for_each_entry(lctl, &led_card->led->controls, list)
|
||||||
|
if (lctl->card == card) {
|
||||||
|
if (buf2 - buf > PAGE_SIZE - 16)
|
||||||
|
break;
|
||||||
|
if (buf2 != buf)
|
||||||
|
*buf2++ = ' ';
|
||||||
|
l = scnprintf(buf2, 15, "%u",
|
||||||
|
lctl->kctl->id.numid +
|
||||||
|
lctl->index_offset);
|
||||||
|
buf2[l] = '\0';
|
||||||
|
buf2 += l + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&snd_ctl_led_mutex);
|
||||||
|
up_read(&card->controls_rwsem);
|
||||||
|
snd_card_unref(card);
|
||||||
|
return buf2 - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEVICE_ATTR(attach, 0200, NULL, parse_attach);
|
||||||
|
static DEVICE_ATTR(detach, 0200, NULL, parse_detach);
|
||||||
|
static DEVICE_ATTR(reset, 0200, NULL, ctl_reset);
|
||||||
|
static DEVICE_ATTR(list, 0444, ctl_list, NULL);
|
||||||
|
|
||||||
|
static struct attribute *snd_ctl_led_card_attrs[] = {
|
||||||
|
&dev_attr_attach.attr,
|
||||||
|
&dev_attr_detach.attr,
|
||||||
|
&dev_attr_reset.attr,
|
||||||
|
&dev_attr_list.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attribute_group snd_ctl_led_card_attr_group = {
|
||||||
|
.attrs = snd_ctl_led_card_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attribute_group *snd_ctl_led_card_attr_groups[] = {
|
||||||
|
&snd_ctl_led_card_attr_group,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct device snd_ctl_led_dev;
|
||||||
|
|
||||||
|
static void snd_ctl_led_sysfs_add(struct snd_card *card)
|
||||||
|
{
|
||||||
|
unsigned int group;
|
||||||
|
struct snd_ctl_led_card *led_card;
|
||||||
|
struct snd_ctl_led *led;
|
||||||
|
char link_name[32];
|
||||||
|
|
||||||
|
for (group = 0; group < MAX_LED; group++) {
|
||||||
|
led = &snd_ctl_leds[group];
|
||||||
|
led_card = kzalloc(sizeof(*led_card), GFP_KERNEL);
|
||||||
|
if (!led_card)
|
||||||
|
goto cerr2;
|
||||||
|
led_card->number = card->number;
|
||||||
|
led_card->led = led;
|
||||||
|
device_initialize(&led_card->dev);
|
||||||
|
if (dev_set_name(&led_card->dev, "card%d", card->number) < 0)
|
||||||
|
goto cerr;
|
||||||
|
led_card->dev.parent = &led->dev;
|
||||||
|
led_card->dev.groups = snd_ctl_led_card_attr_groups;
|
||||||
|
if (device_add(&led_card->dev))
|
||||||
|
goto cerr;
|
||||||
|
led->cards[card->number] = led_card;
|
||||||
|
snprintf(link_name, sizeof(link_name), "led-%s", led->name);
|
||||||
|
WARN(sysfs_create_link(&card->ctl_dev.kobj, &led_card->dev.kobj, link_name),
|
||||||
|
"can't create symlink to controlC%i device\n", card->number);
|
||||||
|
WARN(sysfs_create_link(&led_card->dev.kobj, &card->card_dev.kobj, "card"),
|
||||||
|
"can't create symlink to card%i\n", card->number);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
cerr:
|
||||||
|
put_device(&led_card->dev);
|
||||||
|
cerr2:
|
||||||
|
printk(KERN_ERR "snd_ctl_led: unable to add card%d", card->number);
|
||||||
|
kfree(led_card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void snd_ctl_led_sysfs_remove(struct snd_card *card)
|
||||||
|
{
|
||||||
|
unsigned int group;
|
||||||
|
struct snd_ctl_led_card *led_card;
|
||||||
|
struct snd_ctl_led *led;
|
||||||
|
char link_name[32];
|
||||||
|
|
||||||
|
for (group = 0; group < MAX_LED; group++) {
|
||||||
|
led = &snd_ctl_leds[group];
|
||||||
|
led_card = led->cards[card->number];
|
||||||
|
if (!led_card)
|
||||||
|
continue;
|
||||||
|
snprintf(link_name, sizeof(link_name), "led-%s", led->name);
|
||||||
|
sysfs_remove_link(&card->ctl_dev.kobj, link_name);
|
||||||
|
sysfs_remove_link(&led_card->dev.kobj, "card");
|
||||||
|
device_del(&led_card->dev);
|
||||||
|
kfree(led_card);
|
||||||
|
led->cards[card->number] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control layer registration
|
||||||
|
*/
|
||||||
|
static struct snd_ctl_layer_ops snd_ctl_led_lops = {
|
||||||
|
.module_name = SND_CTL_LAYER_MODULE_LED,
|
||||||
|
.lregister = snd_ctl_led_register,
|
||||||
|
.ldisconnect = snd_ctl_led_disconnect,
|
||||||
|
.lnotify = snd_ctl_led_notify,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init snd_ctl_led_init(void)
|
||||||
|
{
|
||||||
|
struct snd_ctl_led *led;
|
||||||
|
unsigned int group;
|
||||||
|
|
||||||
|
device_initialize(&snd_ctl_led_dev);
|
||||||
|
snd_ctl_led_dev.class = sound_class;
|
||||||
|
dev_set_name(&snd_ctl_led_dev, "ctl-led");
|
||||||
|
if (device_add(&snd_ctl_led_dev)) {
|
||||||
|
put_device(&snd_ctl_led_dev);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
for (group = 0; group < MAX_LED; group++) {
|
||||||
|
led = &snd_ctl_leds[group];
|
||||||
|
INIT_LIST_HEAD(&led->controls);
|
||||||
|
device_initialize(&led->dev);
|
||||||
|
led->dev.parent = &snd_ctl_led_dev;
|
||||||
|
led->dev.groups = snd_ctl_led_dev_attr_groups;
|
||||||
|
dev_set_name(&led->dev, led->name);
|
||||||
|
if (device_add(&led->dev)) {
|
||||||
|
put_device(&led->dev);
|
||||||
|
for (; group > 0; group--) {
|
||||||
|
led = &snd_ctl_leds[group - 1];
|
||||||
|
device_del(&led->dev);
|
||||||
|
}
|
||||||
|
device_del(&snd_ctl_led_dev);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snd_ctl_register_layer(&snd_ctl_led_lops);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit snd_ctl_led_exit(void)
|
||||||
|
{
|
||||||
|
struct snd_ctl_led *led;
|
||||||
|
struct snd_card *card;
|
||||||
|
unsigned int group, card_number;
|
||||||
|
|
||||||
|
snd_ctl_disconnect_layer(&snd_ctl_led_lops);
|
||||||
|
for (card_number = 0; card_number < SNDRV_CARDS; card_number++) {
|
||||||
|
if (!snd_ctl_led_card_valid[card_number])
|
||||||
|
continue;
|
||||||
|
card = snd_card_ref(card_number);
|
||||||
|
if (card) {
|
||||||
|
snd_ctl_led_sysfs_remove(card);
|
||||||
|
snd_card_unref(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (group = 0; group < MAX_LED; group++) {
|
||||||
|
led = &snd_ctl_leds[group];
|
||||||
|
device_del(&led->dev);
|
||||||
|
}
|
||||||
|
device_del(&snd_ctl_led_dev);
|
||||||
|
snd_ctl_led_clean(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(snd_ctl_led_init)
|
||||||
|
module_exit(snd_ctl_led_exit)
|
|
@ -398,10 +398,8 @@ int snd_card_disconnect(struct snd_card *card)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
card->shutdown = 1;
|
card->shutdown = 1;
|
||||||
spin_unlock(&card->files_lock);
|
|
||||||
|
|
||||||
/* replace file->f_op with special dummy operations */
|
/* replace file->f_op with special dummy operations */
|
||||||
spin_lock(&card->files_lock);
|
|
||||||
list_for_each_entry(mfile, &card->files_list, list) {
|
list_for_each_entry(mfile, &card->files_list, list) {
|
||||||
/* it's critical part, use endless loop */
|
/* it's critical part, use endless loop */
|
||||||
/* we have no room to fail */
|
/* we have no room to fail */
|
||||||
|
|
|
@ -3069,8 +3069,12 @@ static void snd_pcm_oss_proc_done(struct snd_pcm *pcm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* !CONFIG_SND_VERBOSE_PROCFS */
|
#else /* !CONFIG_SND_VERBOSE_PROCFS */
|
||||||
#define snd_pcm_oss_proc_init(pcm)
|
static inline void snd_pcm_oss_proc_init(struct snd_pcm *pcm)
|
||||||
#define snd_pcm_oss_proc_done(pcm)
|
{
|
||||||
|
}
|
||||||
|
static inline void snd_pcm_oss_proc_done(struct snd_pcm *pcm)
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif /* CONFIG_SND_VERBOSE_PROCFS */
|
#endif /* CONFIG_SND_VERBOSE_PROCFS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -176,6 +176,10 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
|
||||||
substream->dma_buffer.dev.dev,
|
substream->dma_buffer.dev.dev,
|
||||||
size, &new_dmab) < 0) {
|
size, &new_dmab) < 0) {
|
||||||
buffer->error = -ENOMEM;
|
buffer->error = -ENOMEM;
|
||||||
|
pr_debug("ALSA pcmC%dD%d%c,%d:%s: cannot preallocate for size %zu\n",
|
||||||
|
substream->pcm->card->number, substream->pcm->device,
|
||||||
|
substream->stream ? 'c' : 'p', substream->number,
|
||||||
|
substream->pcm->name, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
substream->buffer_bytes_max = size;
|
substream->buffer_bytes_max = size;
|
||||||
|
@ -210,7 +214,9 @@ static inline void preallocate_info_init(struct snd_pcm_substream *substream)
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !CONFIG_SND_VERBOSE_PROCFS */
|
#else /* !CONFIG_SND_VERBOSE_PROCFS */
|
||||||
#define preallocate_info_init(s)
|
static inline void preallocate_info_init(struct snd_pcm_substream *substream)
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif /* CONFIG_SND_VERBOSE_PROCFS */
|
#endif /* CONFIG_SND_VERBOSE_PROCFS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -400,6 +406,10 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
|
||||||
substream->dma_buffer.dev.dev,
|
substream->dma_buffer.dev.dev,
|
||||||
size, dmab) < 0) {
|
size, dmab) < 0) {
|
||||||
kfree(dmab);
|
kfree(dmab);
|
||||||
|
pr_debug("ALSA pcmC%dD%d%c,%d:%s: cannot preallocate for size %zu\n",
|
||||||
|
substream->pcm->card->number, substream->pcm->device,
|
||||||
|
substream->stream ? 'c' : 'p', substream->number,
|
||||||
|
substream->pcm->name, size);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1425,7 +1425,7 @@ static int snd_pcm_do_stop(struct snd_pcm_substream *substream,
|
||||||
substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
|
substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
|
||||||
substream->runtime->stop_operating = true;
|
substream->runtime->stop_operating = true;
|
||||||
}
|
}
|
||||||
return 0; /* unconditonally stop all substreams */
|
return 0; /* unconditionally stop all substreams */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void snd_pcm_post_stop(struct snd_pcm_substream *substream,
|
static void snd_pcm_post_stop(struct snd_pcm_substream *substream,
|
||||||
|
@ -1469,7 +1469,7 @@ EXPORT_SYMBOL(snd_pcm_stop);
|
||||||
* After stopping, the state is changed to SETUP.
|
* After stopping, the state is changed to SETUP.
|
||||||
* Unlike snd_pcm_stop(), this affects only the given stream.
|
* Unlike snd_pcm_stop(), this affects only the given stream.
|
||||||
*
|
*
|
||||||
* Return: Zero if succesful, or a negative error code.
|
* Return: Zero if successful, or a negative error code.
|
||||||
*/
|
*/
|
||||||
int snd_pcm_drain_done(struct snd_pcm_substream *substream)
|
int snd_pcm_drain_done(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
|
|
|
@ -133,10 +133,19 @@ void snd_seq_device_load_drivers(void)
|
||||||
flush_work(&autoload_work);
|
flush_work(&autoload_work);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(snd_seq_device_load_drivers);
|
EXPORT_SYMBOL(snd_seq_device_load_drivers);
|
||||||
#define cancel_autoload_drivers() cancel_work_sync(&autoload_work)
|
|
||||||
|
static inline void cancel_autoload_drivers(void)
|
||||||
|
{
|
||||||
|
cancel_work_sync(&autoload_work);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#define queue_autoload_drivers() /* NOP */
|
static inline void queue_autoload_drivers(void)
|
||||||
#define cancel_autoload_drivers() /* NOP */
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void cancel_autoload_drivers(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -402,7 +402,7 @@ int vx_send_rih(struct vx_core *chip, int cmd)
|
||||||
#define END_OF_RESET_WAIT_TIME 500 /* us */
|
#define END_OF_RESET_WAIT_TIME 500 /* us */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_vx_boot_xilinx - boot up the xilinx interface
|
* snd_vx_load_boot_image - boot up the xilinx interface
|
||||||
* @chip: VX core instance
|
* @chip: VX core instance
|
||||||
* @boot: the boot record to load
|
* @boot: the boot record to load
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -200,6 +200,8 @@ int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit,
|
||||||
int avc_bridgeco_get_plug_type(struct fw_unit *unit,
|
int avc_bridgeco_get_plug_type(struct fw_unit *unit,
|
||||||
u8 addr[AVC_BRIDGECO_ADDR_BYTES],
|
u8 addr[AVC_BRIDGECO_ADDR_BYTES],
|
||||||
enum avc_bridgeco_plug_type *type);
|
enum avc_bridgeco_plug_type *type);
|
||||||
|
int avc_bridgeco_get_plug_ch_count(struct fw_unit *unit, u8 addr[AVC_BRIDGECO_ADDR_BYTES],
|
||||||
|
unsigned int *ch_count);
|
||||||
int avc_bridgeco_get_plug_section_type(struct fw_unit *unit,
|
int avc_bridgeco_get_plug_section_type(struct fw_unit *unit,
|
||||||
u8 addr[AVC_BRIDGECO_ADDR_BYTES],
|
u8 addr[AVC_BRIDGECO_ADDR_BYTES],
|
||||||
unsigned int id, u8 *type);
|
unsigned int id, u8 *type);
|
||||||
|
|
|
@ -143,6 +143,42 @@ end:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int avc_bridgeco_get_plug_ch_count(struct fw_unit *unit, u8 addr[AVC_BRIDGECO_ADDR_BYTES],
|
||||||
|
unsigned int *ch_count)
|
||||||
|
{
|
||||||
|
u8 *buf;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
buf = kzalloc(12, GFP_KERNEL);
|
||||||
|
if (buf == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
// Info type is 'plug type'.
|
||||||
|
avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x02);
|
||||||
|
|
||||||
|
err = fcp_avc_transaction(unit, buf, 12, buf, 12,
|
||||||
|
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) |
|
||||||
|
BIT(6) | BIT(7) | BIT(9));
|
||||||
|
if (err < 0)
|
||||||
|
;
|
||||||
|
else if (err < 11)
|
||||||
|
err = -EIO;
|
||||||
|
else if (buf[0] == 0x08) // NOT IMPLEMENTED
|
||||||
|
err = -ENOSYS;
|
||||||
|
else if (buf[0] == 0x0a) // REJECTED
|
||||||
|
err = -EINVAL;
|
||||||
|
else if (buf[0] == 0x0b) // IN TRANSITION
|
||||||
|
err = -EAGAIN;
|
||||||
|
if (err < 0)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
*ch_count = buf[10];
|
||||||
|
err = 0;
|
||||||
|
end:
|
||||||
|
kfree(buf);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit,
|
int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit,
|
||||||
u8 addr[AVC_BRIDGECO_ADDR_BYTES],
|
u8 addr[AVC_BRIDGECO_ADDR_BYTES],
|
||||||
u8 *buf, unsigned int len)
|
u8 *buf, unsigned int len)
|
||||||
|
|
|
@ -517,20 +517,22 @@ int snd_bebob_stream_init_duplex(struct snd_bebob *bebob)
|
||||||
static int keep_resources(struct snd_bebob *bebob, struct amdtp_stream *stream,
|
static int keep_resources(struct snd_bebob *bebob, struct amdtp_stream *stream,
|
||||||
unsigned int rate, unsigned int index)
|
unsigned int rate, unsigned int index)
|
||||||
{
|
{
|
||||||
struct snd_bebob_stream_formation *formation;
|
unsigned int pcm_channels;
|
||||||
|
unsigned int midi_ports;
|
||||||
struct cmp_connection *conn;
|
struct cmp_connection *conn;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (stream == &bebob->tx_stream) {
|
if (stream == &bebob->tx_stream) {
|
||||||
formation = bebob->tx_stream_formations + index;
|
pcm_channels = bebob->tx_stream_formations[index].pcm;
|
||||||
|
midi_ports = bebob->midi_input_ports;
|
||||||
conn = &bebob->out_conn;
|
conn = &bebob->out_conn;
|
||||||
} else {
|
} else {
|
||||||
formation = bebob->rx_stream_formations + index;
|
pcm_channels = bebob->rx_stream_formations[index].pcm;
|
||||||
|
midi_ports = bebob->midi_output_ports;
|
||||||
conn = &bebob->in_conn;
|
conn = &bebob->in_conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = amdtp_am824_set_parameters(stream, rate, formation->pcm,
|
err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports, false);
|
||||||
formation->midi, false);
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -796,42 +798,42 @@ parse_stream_formation(u8 *buf, unsigned int len,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int fill_stream_formations(struct snd_bebob *bebob, u8 addr[AVC_BRIDGECO_ADDR_BYTES],
|
||||||
fill_stream_formations(struct snd_bebob *bebob, enum avc_bridgeco_plug_dir dir,
|
enum avc_bridgeco_plug_dir plug_dir, unsigned int plug_id,
|
||||||
unsigned short pid)
|
struct snd_bebob_stream_formation *formations)
|
||||||
{
|
{
|
||||||
|
enum avc_bridgeco_plug_type plug_type;
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
struct snd_bebob_stream_formation *formations;
|
|
||||||
unsigned int len, eid;
|
unsigned int len, eid;
|
||||||
u8 addr[AVC_BRIDGECO_ADDR_BYTES];
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
avc_bridgeco_fill_unit_addr(addr, plug_dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, plug_id);
|
||||||
|
|
||||||
|
err = avc_bridgeco_get_plug_type(bebob->unit, addr, &plug_type);
|
||||||
|
if (err < 0) {
|
||||||
|
dev_err(&bebob->unit->device,
|
||||||
|
"Fail to get type for isoc %d plug 0: %d\n", plug_dir, err);
|
||||||
|
return err;
|
||||||
|
} else if (plug_type != AVC_BRIDGECO_PLUG_TYPE_ISOC)
|
||||||
|
return -ENXIO;
|
||||||
|
|
||||||
buf = kmalloc(FORMAT_MAXIMUM_LENGTH, GFP_KERNEL);
|
buf = kmalloc(FORMAT_MAXIMUM_LENGTH, GFP_KERNEL);
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (dir == AVC_BRIDGECO_PLUG_DIR_IN)
|
for (eid = 0; eid < SND_BEBOB_STRM_FMT_ENTRIES; ++eid) {
|
||||||
formations = bebob->rx_stream_formations;
|
avc_bridgeco_fill_unit_addr(addr, plug_dir, AVC_BRIDGECO_PLUG_UNIT_ISOC, plug_id);
|
||||||
else
|
|
||||||
formations = bebob->tx_stream_formations;
|
|
||||||
|
|
||||||
for (eid = 0; eid < SND_BEBOB_STRM_FMT_ENTRIES; eid++) {
|
|
||||||
len = FORMAT_MAXIMUM_LENGTH;
|
len = FORMAT_MAXIMUM_LENGTH;
|
||||||
avc_bridgeco_fill_unit_addr(addr, dir,
|
err = avc_bridgeco_get_plug_strm_fmt(bebob->unit, addr, buf, &len, eid);
|
||||||
AVC_BRIDGECO_PLUG_UNIT_ISOC, pid);
|
// No entries remained.
|
||||||
err = avc_bridgeco_get_plug_strm_fmt(bebob->unit, addr, buf,
|
|
||||||
&len, eid);
|
|
||||||
/* No entries remained. */
|
|
||||||
if (err == -EINVAL && eid > 0) {
|
if (err == -EINVAL && eid > 0) {
|
||||||
err = 0;
|
err = 0;
|
||||||
break;
|
break;
|
||||||
} else if (err < 0) {
|
} else if (err < 0) {
|
||||||
dev_err(&bebob->unit->device,
|
dev_err(&bebob->unit->device,
|
||||||
"fail to get stream format %d for isoc %s plug %d:%d\n",
|
"fail to get stream format %d for isoc %d plug %d:%d\n",
|
||||||
eid,
|
eid, plug_dir, plug_id, err);
|
||||||
(dir == AVC_BRIDGECO_PLUG_DIR_IN) ? "in" :
|
|
||||||
"out",
|
|
||||||
pid, err);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,6 +846,49 @@ fill_stream_formations(struct snd_bebob *bebob, enum avc_bridgeco_plug_dir dir,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int detect_midi_ports(struct snd_bebob *bebob,
|
||||||
|
const struct snd_bebob_stream_formation *formats,
|
||||||
|
u8 addr[AVC_BRIDGECO_ADDR_BYTES], enum avc_bridgeco_plug_dir plug_dir,
|
||||||
|
unsigned int plug_count, unsigned int *midi_ports)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
*midi_ports = 0;
|
||||||
|
|
||||||
|
/// Detect the number of available MIDI ports when packet has MIDI conformant data channel.
|
||||||
|
for (i = 0; i < SND_BEBOB_STRM_FMT_ENTRIES; ++i) {
|
||||||
|
if (formats[i].midi > 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i >= SND_BEBOB_STRM_FMT_ENTRIES)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < plug_count; ++i) {
|
||||||
|
enum avc_bridgeco_plug_type plug_type;
|
||||||
|
unsigned int ch_count;
|
||||||
|
|
||||||
|
avc_bridgeco_fill_unit_addr(addr, plug_dir, AVC_BRIDGECO_PLUG_UNIT_EXT, i);
|
||||||
|
|
||||||
|
err = avc_bridgeco_get_plug_type(bebob->unit, addr, &plug_type);
|
||||||
|
if (err < 0) {
|
||||||
|
dev_err(&bebob->unit->device,
|
||||||
|
"fail to get type for external %d plug %d: %d\n",
|
||||||
|
plug_dir, i, err);
|
||||||
|
break;
|
||||||
|
} else if (plug_type != AVC_BRIDGECO_PLUG_TYPE_MIDI) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = avc_bridgeco_get_plug_ch_count(bebob->unit, addr, &ch_count);
|
||||||
|
if (err < 0)
|
||||||
|
break;
|
||||||
|
*midi_ports += ch_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
seek_msu_sync_input_plug(struct snd_bebob *bebob)
|
seek_msu_sync_input_plug(struct snd_bebob *bebob)
|
||||||
{
|
{
|
||||||
|
@ -886,8 +931,6 @@ int snd_bebob_stream_discover(struct snd_bebob *bebob)
|
||||||
{
|
{
|
||||||
const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
|
const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
|
||||||
u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES];
|
u8 plugs[AVC_PLUG_INFO_BUF_BYTES], addr[AVC_BRIDGECO_ADDR_BYTES];
|
||||||
enum avc_bridgeco_plug_type type;
|
|
||||||
unsigned int i;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* the number of plugs for isoc in/out, ext in/out */
|
/* the number of plugs for isoc in/out, ext in/out */
|
||||||
|
@ -908,67 +951,25 @@ int snd_bebob_stream_discover(struct snd_bebob *bebob)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
avc_bridgeco_fill_unit_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN,
|
err = fill_stream_formations(bebob, addr, AVC_BRIDGECO_PLUG_DIR_IN, 0,
|
||||||
AVC_BRIDGECO_PLUG_UNIT_ISOC, 0);
|
bebob->rx_stream_formations);
|
||||||
err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type);
|
|
||||||
if (err < 0) {
|
|
||||||
dev_err(&bebob->unit->device,
|
|
||||||
"fail to get type for isoc in plug 0: %d\n", err);
|
|
||||||
goto end;
|
|
||||||
} else if (type != AVC_BRIDGECO_PLUG_TYPE_ISOC) {
|
|
||||||
err = -ENOSYS;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
err = fill_stream_formations(bebob, AVC_BRIDGECO_PLUG_DIR_IN, 0);
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
avc_bridgeco_fill_unit_addr(addr, AVC_BRIDGECO_PLUG_DIR_OUT,
|
err = fill_stream_formations(bebob, addr, AVC_BRIDGECO_PLUG_DIR_OUT, 0,
|
||||||
AVC_BRIDGECO_PLUG_UNIT_ISOC, 0);
|
bebob->tx_stream_formations);
|
||||||
err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type);
|
|
||||||
if (err < 0) {
|
|
||||||
dev_err(&bebob->unit->device,
|
|
||||||
"fail to get type for isoc out plug 0: %d\n", err);
|
|
||||||
goto end;
|
|
||||||
} else if (type != AVC_BRIDGECO_PLUG_TYPE_ISOC) {
|
|
||||||
err = -ENOSYS;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
err = fill_stream_formations(bebob, AVC_BRIDGECO_PLUG_DIR_OUT, 0);
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* count external input plugs for MIDI */
|
err = detect_midi_ports(bebob, bebob->rx_stream_formations, addr, AVC_BRIDGECO_PLUG_DIR_IN,
|
||||||
bebob->midi_input_ports = 0;
|
plugs[2], &bebob->midi_input_ports);
|
||||||
for (i = 0; i < plugs[2]; i++) {
|
if (err < 0)
|
||||||
avc_bridgeco_fill_unit_addr(addr, AVC_BRIDGECO_PLUG_DIR_IN,
|
goto end;
|
||||||
AVC_BRIDGECO_PLUG_UNIT_EXT, i);
|
|
||||||
err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type);
|
|
||||||
if (err < 0) {
|
|
||||||
dev_err(&bebob->unit->device,
|
|
||||||
"fail to get type for external in plug %d: %d\n",
|
|
||||||
i, err);
|
|
||||||
goto end;
|
|
||||||
} else if (type == AVC_BRIDGECO_PLUG_TYPE_MIDI) {
|
|
||||||
bebob->midi_input_ports++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* count external output plugs for MIDI */
|
err = detect_midi_ports(bebob, bebob->tx_stream_formations, addr, AVC_BRIDGECO_PLUG_DIR_OUT,
|
||||||
bebob->midi_output_ports = 0;
|
plugs[3], &bebob->midi_output_ports);
|
||||||
for (i = 0; i < plugs[3]; i++) {
|
if (err < 0)
|
||||||
avc_bridgeco_fill_unit_addr(addr, AVC_BRIDGECO_PLUG_DIR_OUT,
|
goto end;
|
||||||
AVC_BRIDGECO_PLUG_UNIT_EXT, i);
|
|
||||||
err = avc_bridgeco_get_plug_type(bebob->unit, addr, &type);
|
|
||||||
if (err < 0) {
|
|
||||||
dev_err(&bebob->unit->device,
|
|
||||||
"fail to get type for external out plug %d: %d\n",
|
|
||||||
i, err);
|
|
||||||
goto end;
|
|
||||||
} else if (type == AVC_BRIDGECO_PLUG_TYPE_MIDI) {
|
|
||||||
bebob->midi_output_ports++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for check source of clock later */
|
/* for check source of clock later */
|
||||||
if (!clk_spec)
|
if (!clk_spec)
|
||||||
|
|
|
@ -21,17 +21,16 @@ config SND_HDA_EXT_CORE
|
||||||
select SND_HDA_CORE
|
select SND_HDA_CORE
|
||||||
|
|
||||||
config SND_HDA_PREALLOC_SIZE
|
config SND_HDA_PREALLOC_SIZE
|
||||||
int "Pre-allocated buffer size for HD-audio driver"
|
int "Pre-allocated buffer size for HD-audio driver" if !SND_DMA_SGBUF
|
||||||
range 0 32768
|
range 0 32768
|
||||||
default 2048 if SND_DMA_SGBUF
|
default 0 if SND_DMA_SGBUF
|
||||||
default 64 if !SND_DMA_SGBUF
|
default 64 if !SND_DMA_SGBUF
|
||||||
help
|
help
|
||||||
Specifies the default pre-allocated buffer-size in kB for the
|
Specifies the default pre-allocated buffer-size in kB for the
|
||||||
HD-audio driver. A larger buffer (e.g. 2048) is preferred
|
HD-audio driver. A larger buffer (e.g. 2048) is preferred
|
||||||
for systems using PulseAudio. The default 64 is chosen just
|
for systems using PulseAudio. The default 64 is chosen just
|
||||||
for compatibility reasons.
|
for compatibility reasons.
|
||||||
On x86 systems, the default is 2048 as a reasonable value for
|
On x86 systems, the default is zero as we need no preallocation.
|
||||||
most of modern systems.
|
|
||||||
|
|
||||||
Note that the pre-allocation size can be changed dynamically
|
Note that the pre-allocation size can be changed dynamically
|
||||||
via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too.
|
via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too.
|
||||||
|
|
|
@ -618,7 +618,7 @@ void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
|
||||||
EXPORT_SYMBOL_GPL(snd_hdac_stream_sync_trigger);
|
EXPORT_SYMBOL_GPL(snd_hdac_stream_sync_trigger);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_hdac_stream_sync - sync with start/strop trigger operation
|
* snd_hdac_stream_sync - sync with start/stop trigger operation
|
||||||
* @azx_dev: HD-audio core stream (master stream)
|
* @azx_dev: HD-audio core stream (master stream)
|
||||||
* @start: true = start, false = stop
|
* @start: true = start, false = stop
|
||||||
* @streams: bit flags of streams to sync
|
* @streams: bit flags of streams to sync
|
||||||
|
|
|
@ -1029,8 +1029,10 @@ snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
|
||||||
|
|
||||||
memset(emu->controls, 0, sizeof(emu->controls));
|
memset(emu->controls, 0, sizeof(emu->controls));
|
||||||
for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
|
for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
|
||||||
if ((err = snd_ctl_add(card, emu->controls[i] = snd_ctl_new1(mixer_defs[i], emu))) < 0)
|
if ((err = snd_ctl_add(card, emu->controls[i] = snd_ctl_new1(mixer_defs[i], emu))) < 0) {
|
||||||
|
emu->controls[i] = NULL;
|
||||||
goto __error;
|
goto __error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -1045,10 +1045,14 @@ static int snd_sb_qsound_build(struct snd_sb_csp * p)
|
||||||
|
|
||||||
spin_lock_init(&p->q_lock);
|
spin_lock_init(&p->q_lock);
|
||||||
|
|
||||||
if ((err = snd_ctl_add(card, p->qsound_switch = snd_ctl_new1(&snd_sb_qsound_switch, p))) < 0)
|
if ((err = snd_ctl_add(card, p->qsound_switch = snd_ctl_new1(&snd_sb_qsound_switch, p))) < 0) {
|
||||||
|
p->qsound_switch = NULL;
|
||||||
goto __error;
|
goto __error;
|
||||||
if ((err = snd_ctl_add(card, p->qsound_space = snd_ctl_new1(&snd_sb_qsound_space, p))) < 0)
|
}
|
||||||
|
if ((err = snd_ctl_add(card, p->qsound_space = snd_ctl_new1(&snd_sb_qsound_space, p))) < 0) {
|
||||||
|
p->qsound_space = NULL;
|
||||||
goto __error;
|
goto __error;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
|
|
||||||
AudioScience HPI driver
|
AudioScience HPI driver
|
||||||
Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com>
|
Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/**
|
/*
|
||||||
|
|
||||||
AudioScience HPI driver
|
AudioScience HPI driver
|
||||||
Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
|
Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctamixer.c
|
* @File ctamixer.c
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctamixer.h
|
* @File ctamixer.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctatc.c
|
* @File ctatc.c
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctatc.h
|
* @File ctatc.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctdaio.c
|
* @File ctdaio.c
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctdaio.h
|
* @File ctdaio.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File cthardware.h
|
* @File cthardware.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File cthw20k1.h
|
* @File cthw20k1.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File cthw20k2.h
|
* @File cthw20k2.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctimap.h
|
* @File ctimap.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctmixer.h
|
* @File ctmixer.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctpcm.h
|
* @File ctpcm.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctresource.c
|
* @File ctresource.c
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctresource.h
|
* @File ctresource.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctsrc.c
|
* @File ctsrc.c
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctsrc.h
|
* @File ctsrc.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctvmem.c
|
* @File ctvmem.c
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/**
|
/*
|
||||||
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* @File ctvmem.h
|
* @File ctvmem.h
|
||||||
|
|
|
@ -221,10 +221,8 @@ comment "Set to Y if you want auto-loading the codec driver"
|
||||||
|
|
||||||
config SND_HDA_GENERIC
|
config SND_HDA_GENERIC
|
||||||
tristate "Enable generic HD-audio codec parser"
|
tristate "Enable generic HD-audio codec parser"
|
||||||
select NEW_LEDS if SND_HDA_GENERIC_LEDS
|
select SND_CTL_LED if SND_HDA_GENERIC_LEDS
|
||||||
select LEDS_CLASS if SND_HDA_GENERIC_LEDS
|
select LEDS_CLASS if SND_HDA_GENERIC_LEDS
|
||||||
select LEDS_TRIGGERS if SND_HDA_GENERIC_LEDS
|
|
||||||
select LEDS_TRIGGER_AUDIO if SND_HDA_GENERIC_LEDS
|
|
||||||
help
|
help
|
||||||
Say Y or M here to enable the generic HD-audio codec parser
|
Say Y or M here to enable the generic HD-audio codec parser
|
||||||
in snd-hda-intel driver.
|
in snd-hda-intel driver.
|
||||||
|
|
|
@ -27,7 +27,7 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AUTO_CFG_MAX_OUTS HDA_MAX_OUTS
|
#define AUTO_CFG_MAX_OUTS HDA_MAX_OUTS
|
||||||
#define AUTO_CFG_MAX_INS 8
|
#define AUTO_CFG_MAX_INS 18
|
||||||
|
|
||||||
struct auto_pin_cfg_item {
|
struct auto_pin_cfg_item {
|
||||||
hda_nid_t pin;
|
hda_nid_t pin;
|
||||||
|
|
|
@ -1938,6 +1938,7 @@ static int add_follower(struct hda_codec *codec,
|
||||||
* @followers: follower control names (optional)
|
* @followers: follower control names (optional)
|
||||||
* @suffix: suffix string to each follower name (optional)
|
* @suffix: suffix string to each follower name (optional)
|
||||||
* @init_follower_vol: initialize followers to unmute/0dB
|
* @init_follower_vol: initialize followers to unmute/0dB
|
||||||
|
* @access: kcontrol access rights
|
||||||
* @ctl_ret: store the vmaster kcontrol in return
|
* @ctl_ret: store the vmaster kcontrol in return
|
||||||
*
|
*
|
||||||
* Create a virtual master control with the given name. The TLV data
|
* Create a virtual master control with the given name. The TLV data
|
||||||
|
@ -1952,7 +1953,7 @@ static int add_follower(struct hda_codec *codec,
|
||||||
int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
|
int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
|
||||||
unsigned int *tlv, const char * const *followers,
|
unsigned int *tlv, const char * const *followers,
|
||||||
const char *suffix, bool init_follower_vol,
|
const char *suffix, bool init_follower_vol,
|
||||||
struct snd_kcontrol **ctl_ret)
|
unsigned int access, struct snd_kcontrol **ctl_ret)
|
||||||
{
|
{
|
||||||
struct snd_kcontrol *kctl;
|
struct snd_kcontrol *kctl;
|
||||||
int err;
|
int err;
|
||||||
|
@ -1968,6 +1969,7 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
|
||||||
kctl = snd_ctl_make_virtual_master(name, tlv);
|
kctl = snd_ctl_make_virtual_master(name, tlv);
|
||||||
if (!kctl)
|
if (!kctl)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
kctl->vd[0].access |= access;
|
||||||
err = snd_hda_ctl_add(codec, 0, kctl);
|
err = snd_hda_ctl_add(codec, 0, kctl);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
@ -1994,87 +1996,29 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__snd_hda_add_vmaster);
|
EXPORT_SYMBOL_GPL(__snd_hda_add_vmaster);
|
||||||
|
|
||||||
/*
|
|
||||||
* mute-LED control using vmaster
|
|
||||||
*/
|
|
||||||
static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_info *uinfo)
|
|
||||||
{
|
|
||||||
static const char * const texts[] = {
|
|
||||||
"On", "Off", "Follow Master"
|
|
||||||
};
|
|
||||||
|
|
||||||
return snd_ctl_enum_info(uinfo, 1, 3, texts);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
|
||||||
{
|
|
||||||
struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
|
|
||||||
ucontrol->value.enumerated.item[0] = hook->mute_mode;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
|
||||||
{
|
|
||||||
struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
|
|
||||||
unsigned int old_mode = hook->mute_mode;
|
|
||||||
|
|
||||||
hook->mute_mode = ucontrol->value.enumerated.item[0];
|
|
||||||
if (hook->mute_mode > HDA_VMUTE_FOLLOW_MASTER)
|
|
||||||
hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
|
|
||||||
if (old_mode == hook->mute_mode)
|
|
||||||
return 0;
|
|
||||||
snd_hda_sync_vmaster_hook(hook);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct snd_kcontrol_new vmaster_mute_mode = {
|
|
||||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
|
||||||
.name = "Mute-LED Mode",
|
|
||||||
.info = vmaster_mute_mode_info,
|
|
||||||
.get = vmaster_mute_mode_get,
|
|
||||||
.put = vmaster_mute_mode_put,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* meta hook to call each driver's vmaster hook */
|
/* meta hook to call each driver's vmaster hook */
|
||||||
static void vmaster_hook(void *private_data, int enabled)
|
static void vmaster_hook(void *private_data, int enabled)
|
||||||
{
|
{
|
||||||
struct hda_vmaster_mute_hook *hook = private_data;
|
struct hda_vmaster_mute_hook *hook = private_data;
|
||||||
|
|
||||||
if (hook->mute_mode != HDA_VMUTE_FOLLOW_MASTER)
|
|
||||||
enabled = hook->mute_mode;
|
|
||||||
hook->hook(hook->codec, enabled);
|
hook->hook(hook->codec, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_hda_add_vmaster_hook - Add a vmaster hook for mute-LED
|
* snd_hda_add_vmaster_hook - Add a vmaster hw specific hook
|
||||||
* @codec: the HDA codec
|
* @codec: the HDA codec
|
||||||
* @hook: the vmaster hook object
|
* @hook: the vmaster hook object
|
||||||
* @expose_enum_ctl: flag to create an enum ctl
|
|
||||||
*
|
*
|
||||||
* Add a mute-LED hook with the given vmaster switch kctl.
|
* Add a hw specific hook (like EAPD) with the given vmaster switch kctl.
|
||||||
* When @expose_enum_ctl is set, "Mute-LED Mode" control is automatically
|
|
||||||
* created and associated with the given hook.
|
|
||||||
*/
|
*/
|
||||||
int snd_hda_add_vmaster_hook(struct hda_codec *codec,
|
int snd_hda_add_vmaster_hook(struct hda_codec *codec,
|
||||||
struct hda_vmaster_mute_hook *hook,
|
struct hda_vmaster_mute_hook *hook)
|
||||||
bool expose_enum_ctl)
|
|
||||||
{
|
{
|
||||||
struct snd_kcontrol *kctl;
|
|
||||||
|
|
||||||
if (!hook->hook || !hook->sw_kctl)
|
if (!hook->hook || !hook->sw_kctl)
|
||||||
return 0;
|
return 0;
|
||||||
hook->codec = codec;
|
hook->codec = codec;
|
||||||
hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
|
|
||||||
snd_ctl_add_vmaster_hook(hook->sw_kctl, vmaster_hook, hook);
|
snd_ctl_add_vmaster_hook(hook->sw_kctl, vmaster_hook, hook);
|
||||||
if (!expose_enum_ctl)
|
return 0;
|
||||||
return 0;
|
|
||||||
kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
|
|
||||||
if (!kctl)
|
|
||||||
return -ENOMEM;
|
|
||||||
return snd_hda_ctl_add(codec, 0, kctl);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_hda_add_vmaster_hook);
|
EXPORT_SYMBOL_GPL(snd_hda_add_vmaster_hook);
|
||||||
|
|
||||||
|
|
|
@ -981,6 +981,8 @@ add_control(struct hda_gen_spec *spec, int type, const char *name,
|
||||||
knew->index = cidx;
|
knew->index = cidx;
|
||||||
if (get_amp_nid_(val))
|
if (get_amp_nid_(val))
|
||||||
knew->subdevice = HDA_SUBDEV_AMP_FLAG;
|
knew->subdevice = HDA_SUBDEV_AMP_FLAG;
|
||||||
|
if (knew->access == 0)
|
||||||
|
knew->access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
|
||||||
knew->private_value = val;
|
knew->private_value = val;
|
||||||
return knew;
|
return knew;
|
||||||
}
|
}
|
||||||
|
@ -3618,8 +3620,11 @@ static int add_single_cap_ctl(struct hda_codec *codec, const char *label,
|
||||||
amp_val_replace_channels(ctl, chs));
|
amp_val_replace_channels(ctl, chs));
|
||||||
if (!knew)
|
if (!knew)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if (is_switch)
|
if (is_switch) {
|
||||||
knew->put = cap_single_sw_put;
|
knew->put = cap_single_sw_put;
|
||||||
|
if (spec->mic_mute_led)
|
||||||
|
knew->access |= SNDRV_CTL_ELEM_ACCESS_MIC_LED;
|
||||||
|
}
|
||||||
if (!inv_dmic)
|
if (!inv_dmic)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -3634,8 +3639,11 @@ static int add_single_cap_ctl(struct hda_codec *codec, const char *label,
|
||||||
amp_val_replace_channels(ctl, 2));
|
amp_val_replace_channels(ctl, 2));
|
||||||
if (!knew)
|
if (!knew)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if (is_switch)
|
if (is_switch) {
|
||||||
knew->put = cap_single_sw_put;
|
knew->put = cap_single_sw_put;
|
||||||
|
if (spec->mic_mute_led)
|
||||||
|
knew->access |= SNDRV_CTL_ELEM_ACCESS_MIC_LED;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3676,6 +3684,8 @@ static int create_bind_cap_vol_ctl(struct hda_codec *codec, int idx,
|
||||||
knew->index = idx;
|
knew->index = idx;
|
||||||
knew->private_value = sw_ctl;
|
knew->private_value = sw_ctl;
|
||||||
knew->subdevice = HDA_SUBDEV_AMP_FLAG;
|
knew->subdevice = HDA_SUBDEV_AMP_FLAG;
|
||||||
|
if (spec->mic_mute_led)
|
||||||
|
knew->access |= SNDRV_CTL_ELEM_ACCESS_MIC_LED;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3917,11 +3927,6 @@ static int create_mute_led_cdev(struct hda_codec *codec,
|
||||||
return devm_led_classdev_register(&codec->core.dev, cdev);
|
return devm_led_classdev_register(&codec->core.dev, cdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vmaster_update_mute_led(void *private_data, int enabled)
|
|
||||||
{
|
|
||||||
ledtrig_audio_set(LED_AUDIO_MUTE, enabled ? LED_OFF : LED_ON);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_hda_gen_add_mute_led_cdev - Create a LED classdev and enable as vmaster mute LED
|
* snd_hda_gen_add_mute_led_cdev - Create a LED classdev and enable as vmaster mute LED
|
||||||
* @codec: the HDA codec
|
* @codec: the HDA codec
|
||||||
|
@ -3945,134 +3950,11 @@ int snd_hda_gen_add_mute_led_cdev(struct hda_codec *codec,
|
||||||
if (spec->vmaster_mute.hook)
|
if (spec->vmaster_mute.hook)
|
||||||
codec_err(codec, "vmaster hook already present before cdev!\n");
|
codec_err(codec, "vmaster hook already present before cdev!\n");
|
||||||
|
|
||||||
spec->vmaster_mute.hook = vmaster_update_mute_led;
|
spec->vmaster_mute_led = 1;
|
||||||
spec->vmaster_mute_enum = 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_hda_gen_add_mute_led_cdev);
|
EXPORT_SYMBOL_GPL(snd_hda_gen_add_mute_led_cdev);
|
||||||
|
|
||||||
/*
|
|
||||||
* mic mute LED hook helpers
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
MICMUTE_LED_ON,
|
|
||||||
MICMUTE_LED_OFF,
|
|
||||||
MICMUTE_LED_FOLLOW_CAPTURE,
|
|
||||||
MICMUTE_LED_FOLLOW_MUTE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void call_micmute_led_update(struct hda_codec *codec)
|
|
||||||
{
|
|
||||||
struct hda_gen_spec *spec = codec->spec;
|
|
||||||
unsigned int val;
|
|
||||||
|
|
||||||
switch (spec->micmute_led.led_mode) {
|
|
||||||
case MICMUTE_LED_ON:
|
|
||||||
val = 1;
|
|
||||||
break;
|
|
||||||
case MICMUTE_LED_OFF:
|
|
||||||
val = 0;
|
|
||||||
break;
|
|
||||||
case MICMUTE_LED_FOLLOW_CAPTURE:
|
|
||||||
val = !!spec->micmute_led.capture;
|
|
||||||
break;
|
|
||||||
case MICMUTE_LED_FOLLOW_MUTE:
|
|
||||||
default:
|
|
||||||
val = !spec->micmute_led.capture;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val == spec->micmute_led.led_value)
|
|
||||||
return;
|
|
||||||
spec->micmute_led.led_value = val;
|
|
||||||
ledtrig_audio_set(LED_AUDIO_MICMUTE,
|
|
||||||
spec->micmute_led.led_value ? LED_ON : LED_OFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_micmute_led(struct hda_codec *codec,
|
|
||||||
struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
|
||||||
{
|
|
||||||
struct hda_gen_spec *spec = codec->spec;
|
|
||||||
unsigned int mask;
|
|
||||||
|
|
||||||
if (spec->micmute_led.old_hook)
|
|
||||||
spec->micmute_led.old_hook(codec, kcontrol, ucontrol);
|
|
||||||
|
|
||||||
if (!ucontrol)
|
|
||||||
return;
|
|
||||||
mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
|
|
||||||
if (!strcmp("Capture Switch", ucontrol->id.name)) {
|
|
||||||
/* TODO: How do I verify if it's a mono or stereo here? */
|
|
||||||
if (ucontrol->value.integer.value[0] ||
|
|
||||||
ucontrol->value.integer.value[1])
|
|
||||||
spec->micmute_led.capture |= mask;
|
|
||||||
else
|
|
||||||
spec->micmute_led.capture &= ~mask;
|
|
||||||
call_micmute_led_update(codec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int micmute_led_mode_info(struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_info *uinfo)
|
|
||||||
{
|
|
||||||
static const char * const texts[] = {
|
|
||||||
"On", "Off", "Follow Capture", "Follow Mute",
|
|
||||||
};
|
|
||||||
|
|
||||||
return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int micmute_led_mode_get(struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
|
||||||
{
|
|
||||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
|
||||||
struct hda_gen_spec *spec = codec->spec;
|
|
||||||
|
|
||||||
ucontrol->value.enumerated.item[0] = spec->micmute_led.led_mode;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int micmute_led_mode_put(struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
|
||||||
{
|
|
||||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
|
||||||
struct hda_gen_spec *spec = codec->spec;
|
|
||||||
unsigned int mode;
|
|
||||||
|
|
||||||
mode = ucontrol->value.enumerated.item[0];
|
|
||||||
if (mode > MICMUTE_LED_FOLLOW_MUTE)
|
|
||||||
mode = MICMUTE_LED_FOLLOW_MUTE;
|
|
||||||
if (mode == spec->micmute_led.led_mode)
|
|
||||||
return 0;
|
|
||||||
spec->micmute_led.led_mode = mode;
|
|
||||||
call_micmute_led_update(codec);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct snd_kcontrol_new micmute_led_mode_ctl = {
|
|
||||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
|
||||||
.name = "Mic Mute-LED Mode",
|
|
||||||
.info = micmute_led_mode_info,
|
|
||||||
.get = micmute_led_mode_get,
|
|
||||||
.put = micmute_led_mode_put,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Set up the capture sync hook for controlling the mic-mute LED */
|
|
||||||
static int add_micmute_led_hook(struct hda_codec *codec)
|
|
||||||
{
|
|
||||||
struct hda_gen_spec *spec = codec->spec;
|
|
||||||
|
|
||||||
spec->micmute_led.led_mode = MICMUTE_LED_FOLLOW_MUTE;
|
|
||||||
spec->micmute_led.capture = 0;
|
|
||||||
spec->micmute_led.led_value = -1;
|
|
||||||
spec->micmute_led.old_hook = spec->cap_sync_hook;
|
|
||||||
spec->cap_sync_hook = update_micmute_led;
|
|
||||||
if (!snd_hda_gen_add_kctl(spec, NULL, &micmute_led_mode_ctl))
|
|
||||||
return -ENOMEM;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_hda_gen_add_micmute_led_cdev - Create a LED classdev and enable as mic-mute LED
|
* snd_hda_gen_add_micmute_led_cdev - Create a LED classdev and enable as mic-mute LED
|
||||||
* @codec: the HDA codec
|
* @codec: the HDA codec
|
||||||
|
@ -4091,6 +3973,7 @@ int snd_hda_gen_add_micmute_led_cdev(struct hda_codec *codec,
|
||||||
int (*callback)(struct led_classdev *,
|
int (*callback)(struct led_classdev *,
|
||||||
enum led_brightness))
|
enum led_brightness))
|
||||||
{
|
{
|
||||||
|
struct hda_gen_spec *spec = codec->spec;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
|
@ -4101,7 +3984,8 @@ int snd_hda_gen_add_micmute_led_cdev(struct hda_codec *codec,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return add_micmute_led_hook(codec);
|
spec->mic_mute_led = 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_hda_gen_add_micmute_led_cdev);
|
EXPORT_SYMBOL_GPL(snd_hda_gen_add_micmute_led_cdev);
|
||||||
#endif /* CONFIG_SND_HDA_GENERIC_LEDS */
|
#endif /* CONFIG_SND_HDA_GENERIC_LEDS */
|
||||||
|
@ -5060,6 +4944,9 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
|
||||||
|
|
||||||
parse_user_hints(codec);
|
parse_user_hints(codec);
|
||||||
|
|
||||||
|
if (spec->vmaster_mute_led || spec->mic_mute_led)
|
||||||
|
snd_ctl_led_request();
|
||||||
|
|
||||||
if (spec->mixer_nid && !spec->mixer_merge_nid)
|
if (spec->mixer_nid && !spec->mixer_merge_nid)
|
||||||
spec->mixer_merge_nid = spec->mixer_nid;
|
spec->mixer_merge_nid = spec->mixer_nid;
|
||||||
|
|
||||||
|
@ -5291,7 +5178,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
|
||||||
!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
|
!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
|
||||||
err = snd_hda_add_vmaster(codec, "Master Playback Volume",
|
err = snd_hda_add_vmaster(codec, "Master Playback Volume",
|
||||||
spec->vmaster_tlv, follower_pfxs,
|
spec->vmaster_tlv, follower_pfxs,
|
||||||
"Playback Volume");
|
"Playback Volume", 0);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -5299,13 +5186,14 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
|
||||||
!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
|
!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
|
||||||
err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
|
err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
|
||||||
NULL, follower_pfxs,
|
NULL, follower_pfxs,
|
||||||
"Playback Switch",
|
"Playback Switch", true,
|
||||||
true, &spec->vmaster_mute.sw_kctl);
|
spec->vmaster_mute_led ?
|
||||||
|
SNDRV_CTL_ELEM_ACCESS_SPK_LED : 0,
|
||||||
|
&spec->vmaster_mute.sw_kctl);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
if (spec->vmaster_mute.hook) {
|
if (spec->vmaster_mute.hook) {
|
||||||
snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute,
|
snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute);
|
||||||
spec->vmaster_mute_enum);
|
|
||||||
snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
|
snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,15 +84,6 @@ struct badness_table {
|
||||||
extern const struct badness_table hda_main_out_badness;
|
extern const struct badness_table hda_main_out_badness;
|
||||||
extern const struct badness_table hda_extra_out_badness;
|
extern const struct badness_table hda_extra_out_badness;
|
||||||
|
|
||||||
struct hda_micmute_hook {
|
|
||||||
unsigned int led_mode;
|
|
||||||
unsigned int capture;
|
|
||||||
unsigned int led_value;
|
|
||||||
void (*old_hook)(struct hda_codec *codec,
|
|
||||||
struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_value *ucontrol);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hda_gen_spec {
|
struct hda_gen_spec {
|
||||||
char stream_name_analog[32]; /* analog PCM stream */
|
char stream_name_analog[32]; /* analog PCM stream */
|
||||||
const struct hda_pcm_stream *stream_analog_playback;
|
const struct hda_pcm_stream *stream_analog_playback;
|
||||||
|
@ -229,7 +220,8 @@ struct hda_gen_spec {
|
||||||
unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */
|
unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */
|
||||||
unsigned int own_eapd_ctl:1; /* set EAPD by own function */
|
unsigned int own_eapd_ctl:1; /* set EAPD by own function */
|
||||||
unsigned int keep_eapd_on:1; /* don't turn off EAPD automatically */
|
unsigned int keep_eapd_on:1; /* don't turn off EAPD automatically */
|
||||||
unsigned int vmaster_mute_enum:1; /* add vmaster mute mode enum */
|
unsigned int vmaster_mute_led:1; /* add SPK-LED flag to vmaster mute switch */
|
||||||
|
unsigned int mic_mute_led:1; /* add MIC-LED flag to capture mute switch */
|
||||||
unsigned int indep_hp:1; /* independent HP supported */
|
unsigned int indep_hp:1; /* independent HP supported */
|
||||||
unsigned int prefer_hp_amp:1; /* enable HP amp for speaker if any */
|
unsigned int prefer_hp_amp:1; /* enable HP amp for speaker if any */
|
||||||
unsigned int add_stereo_mix_input:2; /* add aamix as a capture src */
|
unsigned int add_stereo_mix_input:2; /* add aamix as a capture src */
|
||||||
|
@ -285,9 +277,6 @@ struct hda_gen_spec {
|
||||||
struct snd_kcontrol *kcontrol,
|
struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol);
|
struct snd_ctl_elem_value *ucontrol);
|
||||||
|
|
||||||
/* mic mute LED hook; called via cap_sync_hook */
|
|
||||||
struct hda_micmute_hook micmute_led;
|
|
||||||
|
|
||||||
/* PCM hooks */
|
/* PCM hooks */
|
||||||
void (*pcm_playback_hook)(struct hda_pcm_stream *hinfo,
|
void (*pcm_playback_hook)(struct hda_pcm_stream *hinfo,
|
||||||
struct hda_codec *codec,
|
struct hda_codec *codec,
|
||||||
|
|
|
@ -388,6 +388,69 @@ int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_hda_jack_set_gating_jack);
|
EXPORT_SYMBOL_GPL(snd_hda_jack_set_gating_jack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_hda_jack_bind_keymap - bind keys generated from one NID to another jack.
|
||||||
|
* @codec: the HDA codec
|
||||||
|
* @key_nid: key event is generated by this pin NID
|
||||||
|
* @keymap: map of key type and key code
|
||||||
|
* @jack_nid: key reports to the jack of this pin NID
|
||||||
|
*
|
||||||
|
* This function is used in the case of key is generated from one NID while is
|
||||||
|
* reported to the jack of another NID.
|
||||||
|
*/
|
||||||
|
int snd_hda_jack_bind_keymap(struct hda_codec *codec, hda_nid_t key_nid,
|
||||||
|
const struct hda_jack_keymap *keymap,
|
||||||
|
hda_nid_t jack_nid)
|
||||||
|
{
|
||||||
|
const struct hda_jack_keymap *map;
|
||||||
|
struct hda_jack_tbl *key_gen = snd_hda_jack_tbl_get(codec, key_nid);
|
||||||
|
struct hda_jack_tbl *report_to = snd_hda_jack_tbl_get(codec, jack_nid);
|
||||||
|
|
||||||
|
WARN_ON(codec->dp_mst);
|
||||||
|
|
||||||
|
if (!key_gen || !report_to || !report_to->jack)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
key_gen->key_report_jack = jack_nid;
|
||||||
|
|
||||||
|
if (keymap)
|
||||||
|
for (map = keymap; map->type; map++)
|
||||||
|
snd_jack_set_key(report_to->jack, map->type, map->key);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_hda_jack_bind_keymap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_hda_jack_set_button_state - report button event to the hda_jack_tbl button_state.
|
||||||
|
* @codec: the HDA codec
|
||||||
|
* @jack_nid: the button event reports to the jack_tbl of this NID
|
||||||
|
* @button_state: the button event captured by codec
|
||||||
|
*
|
||||||
|
* Codec driver calls this function to report the button event.
|
||||||
|
*/
|
||||||
|
void snd_hda_jack_set_button_state(struct hda_codec *codec, hda_nid_t jack_nid,
|
||||||
|
int button_state)
|
||||||
|
{
|
||||||
|
struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, jack_nid);
|
||||||
|
|
||||||
|
if (!jack)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (jack->key_report_jack) {
|
||||||
|
struct hda_jack_tbl *report_to =
|
||||||
|
snd_hda_jack_tbl_get(codec, jack->key_report_jack);
|
||||||
|
|
||||||
|
if (report_to) {
|
||||||
|
report_to->button_state = button_state;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jack->button_state = button_state;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_hda_jack_set_button_state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_hda_jack_report_sync - sync the states of all jacks and report if changed
|
* snd_hda_jack_report_sync - sync the states of all jacks and report if changed
|
||||||
* @codec: the HDA codec
|
* @codec: the HDA codec
|
||||||
|
@ -651,7 +714,15 @@ void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res)
|
||||||
}
|
}
|
||||||
if (!event)
|
if (!event)
|
||||||
return;
|
return;
|
||||||
event->jack_dirty = 1;
|
|
||||||
|
if (event->key_report_jack) {
|
||||||
|
struct hda_jack_tbl *report_to =
|
||||||
|
snd_hda_jack_tbl_get_mst(codec, event->key_report_jack,
|
||||||
|
event->dev_id);
|
||||||
|
if (report_to)
|
||||||
|
report_to->jack_dirty = 1;
|
||||||
|
} else
|
||||||
|
event->jack_dirty = 1;
|
||||||
|
|
||||||
call_jack_callback(codec, res, event);
|
call_jack_callback(codec, res, event);
|
||||||
snd_hda_jack_report_sync(codec);
|
snd_hda_jack_report_sync(codec);
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct hda_jack_tbl {
|
||||||
unsigned int block_report:1; /* in a transitional state - do not report to userspace */
|
unsigned int block_report:1; /* in a transitional state - do not report to userspace */
|
||||||
hda_nid_t gating_jack; /* valid when gating jack plugged */
|
hda_nid_t gating_jack; /* valid when gating jack plugged */
|
||||||
hda_nid_t gated_jack; /* gated is dependent on this jack */
|
hda_nid_t gated_jack; /* gated is dependent on this jack */
|
||||||
|
hda_nid_t key_report_jack; /* key reports to this jack */
|
||||||
int type;
|
int type;
|
||||||
int button_state;
|
int button_state;
|
||||||
struct snd_jack *jack;
|
struct snd_jack *jack;
|
||||||
|
@ -99,6 +100,13 @@ snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
|
||||||
int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
|
int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
|
||||||
hda_nid_t gating_nid);
|
hda_nid_t gating_nid);
|
||||||
|
|
||||||
|
int snd_hda_jack_bind_keymap(struct hda_codec *codec, hda_nid_t key_nid,
|
||||||
|
const struct hda_jack_keymap *keymap,
|
||||||
|
hda_nid_t jack_nid);
|
||||||
|
|
||||||
|
void snd_hda_jack_set_button_state(struct hda_codec *codec, hda_nid_t jack_nid,
|
||||||
|
int button_state);
|
||||||
|
|
||||||
u32 snd_hda_jack_pin_sense(struct hda_codec *codec, hda_nid_t nid, int dev_id);
|
u32 snd_hda_jack_pin_sense(struct hda_codec *codec, hda_nid_t nid, int dev_id);
|
||||||
|
|
||||||
/* the jack state returned from snd_hda_jack_detect_state() */
|
/* the jack state returned from snd_hda_jack_detect_state() */
|
||||||
|
|
|
@ -131,21 +131,15 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
|
||||||
int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
|
int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
|
||||||
unsigned int *tlv, const char * const *followers,
|
unsigned int *tlv, const char * const *followers,
|
||||||
const char *suffix, bool init_follower_vol,
|
const char *suffix, bool init_follower_vol,
|
||||||
struct snd_kcontrol **ctl_ret);
|
unsigned int access, struct snd_kcontrol **ctl_ret);
|
||||||
#define snd_hda_add_vmaster(codec, name, tlv, followers, suffix) \
|
#define snd_hda_add_vmaster(codec, name, tlv, followers, suffix, access) \
|
||||||
__snd_hda_add_vmaster(codec, name, tlv, followers, suffix, true, NULL)
|
__snd_hda_add_vmaster(codec, name, tlv, followers, suffix, true, access, NULL)
|
||||||
int snd_hda_codec_reset(struct hda_codec *codec);
|
int snd_hda_codec_reset(struct hda_codec *codec);
|
||||||
void snd_hda_codec_register(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_cleanup_for_unbind(struct hda_codec *codec);
|
||||||
|
|
||||||
#define snd_hda_regmap_sync(codec) snd_hdac_regmap_sync(&(codec)->core)
|
#define snd_hda_regmap_sync(codec) snd_hdac_regmap_sync(&(codec)->core)
|
||||||
|
|
||||||
enum {
|
|
||||||
HDA_VMUTE_OFF,
|
|
||||||
HDA_VMUTE_ON,
|
|
||||||
HDA_VMUTE_FOLLOW_MASTER,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hda_vmaster_mute_hook {
|
struct hda_vmaster_mute_hook {
|
||||||
/* below two fields must be filled by the caller of
|
/* below two fields must be filled by the caller of
|
||||||
* snd_hda_add_vmaster_hook() beforehand
|
* snd_hda_add_vmaster_hook() beforehand
|
||||||
|
@ -153,13 +147,11 @@ struct hda_vmaster_mute_hook {
|
||||||
struct snd_kcontrol *sw_kctl;
|
struct snd_kcontrol *sw_kctl;
|
||||||
void (*hook)(void *, int);
|
void (*hook)(void *, int);
|
||||||
/* below are initialized automatically */
|
/* below are initialized automatically */
|
||||||
unsigned int mute_mode; /* HDA_VMUTE_XXX */
|
|
||||||
struct hda_codec *codec;
|
struct hda_codec *codec;
|
||||||
};
|
};
|
||||||
|
|
||||||
int snd_hda_add_vmaster_hook(struct hda_codec *codec,
|
int snd_hda_add_vmaster_hook(struct hda_codec *codec,
|
||||||
struct hda_vmaster_mute_hook *hook,
|
struct hda_vmaster_mute_hook *hook);
|
||||||
bool expose_enum_ctl);
|
|
||||||
void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
|
void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
|
||||||
|
|
||||||
/* amp value bits */
|
/* amp value bits */
|
||||||
|
@ -180,7 +172,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
|
||||||
/*
|
/*
|
||||||
* input MUX helper
|
* input MUX helper
|
||||||
*/
|
*/
|
||||||
#define HDA_MAX_NUM_INPUTS 16
|
#define HDA_MAX_NUM_INPUTS 36
|
||||||
struct hda_input_mux_item {
|
struct hda_input_mux_item {
|
||||||
char label[32];
|
char label[32];
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
|
|
492
sound/pci/hda/ideapad_s740_helper.c
Normal file
492
sound/pci/hda/ideapad_s740_helper.c
Normal file
|
@ -0,0 +1,492 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/* Fixes for Lenovo Ideapad S740, to be included from codec driver */
|
||||||
|
|
||||||
|
static const struct hda_verb alc285_ideapad_s740_coefs[] = {
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x10 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0320 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0041 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0041 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001d },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x004e },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001d },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x004e },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0042 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x007f },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x003c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0011 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x002a },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x002a },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0046 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x000f },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0046 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0044 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0044 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0009 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x004c },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001b },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0019 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0025 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0018 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0037 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x001a },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0040 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0016 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0076 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0017 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0010 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0015 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0007 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0086 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x29 },
|
||||||
|
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
|
||||||
|
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void alc285_fixup_ideapad_s740_coef(struct hda_codec *codec,
|
||||||
|
const struct hda_fixup *fix,
|
||||||
|
int action)
|
||||||
|
{
|
||||||
|
switch (action) {
|
||||||
|
case HDA_FIXUP_ACT_PRE_PROBE:
|
||||||
|
snd_hda_add_verbs(codec, alc285_ideapad_s740_coefs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7041,11 +7041,11 @@ static int ca0132_build_controls(struct hda_codec *codec)
|
||||||
spec->tlv);
|
spec->tlv);
|
||||||
snd_hda_add_vmaster(codec, "Master Playback Volume",
|
snd_hda_add_vmaster(codec, "Master Playback Volume",
|
||||||
spec->tlv, ca0132_alt_follower_pfxs,
|
spec->tlv, ca0132_alt_follower_pfxs,
|
||||||
"Playback Volume");
|
"Playback Volume", 0);
|
||||||
err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
|
err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
|
||||||
NULL, ca0132_alt_follower_pfxs,
|
NULL, ca0132_alt_follower_pfxs,
|
||||||
"Playback Switch",
|
"Playback Switch",
|
||||||
true, &spec->vmaster_mute.sw_kctl);
|
true, 0, &spec->vmaster_mute.sw_kctl);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -930,18 +930,18 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
|
||||||
SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK),
|
SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK),
|
||||||
SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK),
|
SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK),
|
||||||
SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK),
|
SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO),
|
||||||
SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK),
|
SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x836e, "HP ProBook 455 G5", CXT_FIXUP_MUTE_LED_GPIO),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x837f, "HP ProBook 470 G5", CXT_FIXUP_MUTE_LED_GPIO),
|
||||||
SND_PCI_QUIRK(0x103c, 0x83b2, "HP EliteBook 840 G5", CXT_FIXUP_HP_DOCK),
|
SND_PCI_QUIRK(0x103c, 0x83b2, "HP EliteBook 840 G5", CXT_FIXUP_HP_DOCK),
|
||||||
SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK),
|
SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK),
|
||||||
SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK),
|
SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x822e, "HP ProBook 440 G4", CXT_FIXUP_MUTE_LED_GPIO),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x836e, "HP ProBook 455 G5", CXT_FIXUP_MUTE_LED_GPIO),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x837f, "HP ProBook 470 G5", CXT_FIXUP_MUTE_LED_GPIO),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x8402, "HP ProBook 645 G4", CXT_FIXUP_MUTE_LED_GPIO),
|
SND_PCI_QUIRK(0x103c, 0x8402, "HP ProBook 645 G4", CXT_FIXUP_MUTE_LED_GPIO),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8427, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
|
SND_PCI_QUIRK(0x103c, 0x8427, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x844f, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
|
SND_PCI_QUIRK(0x103c, 0x844f, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
|
||||||
|
|
|
@ -1848,16 +1848,12 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
|
||||||
*/
|
*/
|
||||||
if (spec->intel_hsw_fixup) {
|
if (spec->intel_hsw_fixup) {
|
||||||
/*
|
/*
|
||||||
* On Intel platforms, device entries number is
|
* On Intel platforms, device entries count returned
|
||||||
* changed dynamically. If there is a DP MST
|
* by AC_PAR_DEVLIST_LEN is dynamic, and depends on
|
||||||
* hub connected, the device entries number is 3.
|
* the type of receiver that is connected. Allocate pin
|
||||||
* Otherwise, it is 1.
|
* structures based on worst case.
|
||||||
* Here we manually set dev_num to 3, so that
|
|
||||||
* we can initialize all the device entries when
|
|
||||||
* bootup statically.
|
|
||||||
*/
|
*/
|
||||||
dev_num = 3;
|
dev_num = spec->dev_num;
|
||||||
spec->dev_num = 3;
|
|
||||||
} else if (spec->dyn_pcm_assign && codec->dp_mst) {
|
} else if (spec->dyn_pcm_assign && codec->dp_mst) {
|
||||||
dev_num = snd_hda_get_num_devices(codec, pin_nid) + 1;
|
dev_num = snd_hda_get_num_devices(codec, pin_nid) + 1;
|
||||||
/*
|
/*
|
||||||
|
@ -2658,7 +2654,7 @@ static void generic_acomp_pin_eld_notify(void *audio_ptr, int port, int dev_id)
|
||||||
/* skip notification during system suspend (but not in runtime PM);
|
/* skip notification during system suspend (but not in runtime PM);
|
||||||
* the state will be updated at resume
|
* the state will be updated at resume
|
||||||
*/
|
*/
|
||||||
if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0)
|
if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND)
|
||||||
return;
|
return;
|
||||||
/* ditto during suspend/resume process itself */
|
/* ditto during suspend/resume process itself */
|
||||||
if (snd_hdac_is_in_pm(&codec->core))
|
if (snd_hdac_is_in_pm(&codec->core))
|
||||||
|
@ -2844,7 +2840,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe)
|
||||||
/* skip notification during system suspend (but not in runtime PM);
|
/* skip notification during system suspend (but not in runtime PM);
|
||||||
* the state will be updated at resume
|
* the state will be updated at resume
|
||||||
*/
|
*/
|
||||||
if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0)
|
if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND)
|
||||||
return;
|
return;
|
||||||
/* ditto during suspend/resume process itself */
|
/* ditto during suspend/resume process itself */
|
||||||
if (snd_hdac_is_in_pm(&codec->core))
|
if (snd_hdac_is_in_pm(&codec->core))
|
||||||
|
@ -2942,7 +2938,7 @@ static int parse_intel_hdmi(struct hda_codec *codec)
|
||||||
|
|
||||||
/* Intel Haswell and onwards; audio component with eld notifier */
|
/* Intel Haswell and onwards; audio component with eld notifier */
|
||||||
static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid,
|
static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid,
|
||||||
const int *port_map, int port_num)
|
const int *port_map, int port_num, int dev_num)
|
||||||
{
|
{
|
||||||
struct hdmi_spec *spec;
|
struct hdmi_spec *spec;
|
||||||
int err;
|
int err;
|
||||||
|
@ -2957,6 +2953,7 @@ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid,
|
||||||
spec->port_map = port_map;
|
spec->port_map = port_map;
|
||||||
spec->port_num = port_num;
|
spec->port_num = port_num;
|
||||||
spec->intel_hsw_fixup = true;
|
spec->intel_hsw_fixup = true;
|
||||||
|
spec->dev_num = dev_num;
|
||||||
|
|
||||||
intel_haswell_enable_all_pins(codec, true);
|
intel_haswell_enable_all_pins(codec, true);
|
||||||
intel_haswell_fixup_enable_dp12(codec);
|
intel_haswell_fixup_enable_dp12(codec);
|
||||||
|
@ -2982,12 +2979,12 @@ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid,
|
||||||
|
|
||||||
static int patch_i915_hsw_hdmi(struct hda_codec *codec)
|
static int patch_i915_hsw_hdmi(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
return intel_hsw_common_init(codec, 0x08, NULL, 0);
|
return intel_hsw_common_init(codec, 0x08, NULL, 0, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int patch_i915_glk_hdmi(struct hda_codec *codec)
|
static int patch_i915_glk_hdmi(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
return intel_hsw_common_init(codec, 0x0b, NULL, 0);
|
return intel_hsw_common_init(codec, 0x0b, NULL, 0, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int patch_i915_icl_hdmi(struct hda_codec *codec)
|
static int patch_i915_icl_hdmi(struct hda_codec *codec)
|
||||||
|
@ -2998,7 +2995,7 @@ static int patch_i915_icl_hdmi(struct hda_codec *codec)
|
||||||
*/
|
*/
|
||||||
static const int map[] = {0x0, 0x4, 0x6, 0x8, 0xa, 0xb};
|
static const int map[] = {0x0, 0x4, 0x6, 0x8, 0xa, 0xb};
|
||||||
|
|
||||||
return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map));
|
return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int patch_i915_tgl_hdmi(struct hda_codec *codec)
|
static int patch_i915_tgl_hdmi(struct hda_codec *codec)
|
||||||
|
@ -3010,7 +3007,7 @@ static int patch_i915_tgl_hdmi(struct hda_codec *codec)
|
||||||
static const int map[] = {0x4, 0x6, 0x8, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
|
static const int map[] = {0x4, 0x6, 0x8, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map));
|
ret = intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map), 4);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
struct hdmi_spec *spec = codec->spec;
|
struct hdmi_spec *spec = codec->spec;
|
||||||
|
|
||||||
|
|
|
@ -292,7 +292,7 @@ static void alc_fixup_gpio4(struct hda_codec *codec,
|
||||||
static void alc_fixup_micmute_led(struct hda_codec *codec,
|
static void alc_fixup_micmute_led(struct hda_codec *codec,
|
||||||
const struct hda_fixup *fix, int action)
|
const struct hda_fixup *fix, int action)
|
||||||
{
|
{
|
||||||
if (action == HDA_FIXUP_ACT_PROBE)
|
if (action == HDA_FIXUP_ACT_PRE_PROBE)
|
||||||
snd_hda_gen_add_micmute_led_cdev(codec, NULL);
|
snd_hda_gen_add_micmute_led_cdev(codec, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2470,13 +2470,13 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||||
ALC882_FIXUP_ACER_ASPIRE_8930G),
|
ALC882_FIXUP_ACER_ASPIRE_8930G),
|
||||||
SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
|
SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
|
||||||
ALC882_FIXUP_ACER_ASPIRE_8930G),
|
ALC882_FIXUP_ACER_ASPIRE_8930G),
|
||||||
|
SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
|
||||||
|
ALC882_FIXUP_ACER_ASPIRE_4930G),
|
||||||
|
SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
|
||||||
SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
|
SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
|
||||||
ALC882_FIXUP_ACER_ASPIRE_4930G),
|
ALC882_FIXUP_ACER_ASPIRE_4930G),
|
||||||
SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
|
SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
|
||||||
ALC882_FIXUP_ACER_ASPIRE_4930G),
|
ALC882_FIXUP_ACER_ASPIRE_4930G),
|
||||||
SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
|
|
||||||
ALC882_FIXUP_ACER_ASPIRE_4930G),
|
|
||||||
SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
|
|
||||||
SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
|
SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
|
||||||
ALC882_FIXUP_ACER_ASPIRE_4930G),
|
ALC882_FIXUP_ACER_ASPIRE_4930G),
|
||||||
SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
|
SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
|
||||||
|
@ -2489,11 +2489,11 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
|
SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
|
||||||
SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
|
SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
|
||||||
SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
|
SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
|
||||||
|
SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
|
||||||
|
SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
|
||||||
SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
|
SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
|
||||||
SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
|
SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
|
||||||
SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
|
SND_PCI_QUIRK(0x104d, 0x9060, "Sony Vaio VPCL14M1R", ALC882_FIXUP_NO_PRIMARY_HP),
|
||||||
SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
|
|
||||||
SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
|
|
||||||
|
|
||||||
/* All Apple entries are in codec SSIDs */
|
/* All Apple entries are in codec SSIDs */
|
||||||
SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
|
SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
|
||||||
|
@ -2536,9 +2536,19 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
|
SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
|
||||||
SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
|
SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
|
||||||
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
|
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x65e1, "Clevo PB51[ED][DF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x65e5, "Clevo PC50D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
|
SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
||||||
SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
|
SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
|
||||||
SND_PCI_QUIRK(0x1558, 0x9506, "Clevo P955HQ", ALC1220_FIXUP_CLEVO_P950),
|
SND_PCI_QUIRK(0x1558, 0x9506, "Clevo P955HQ", ALC1220_FIXUP_CLEVO_P950),
|
||||||
SND_PCI_QUIRK(0x1558, 0x950A, "Clevo P955H[PR]", ALC1220_FIXUP_CLEVO_P950),
|
SND_PCI_QUIRK(0x1558, 0x950a, "Clevo P955H[PR]", ALC1220_FIXUP_CLEVO_P950),
|
||||||
SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
|
SND_PCI_QUIRK(0x1558, 0x95e1, "Clevo P95xER", ALC1220_FIXUP_CLEVO_P950),
|
||||||
SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
|
SND_PCI_QUIRK(0x1558, 0x95e2, "Clevo P950ER", ALC1220_FIXUP_CLEVO_P950),
|
||||||
SND_PCI_QUIRK(0x1558, 0x95e3, "Clevo P955[ER]T", ALC1220_FIXUP_CLEVO_P950),
|
SND_PCI_QUIRK(0x1558, 0x95e3, "Clevo P955[ER]T", ALC1220_FIXUP_CLEVO_P950),
|
||||||
|
@ -2548,14 +2558,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
|
SND_PCI_QUIRK(0x1558, 0x96e1, "Clevo P960[ER][CDFN]-K", ALC1220_FIXUP_CLEVO_P950),
|
||||||
SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
|
SND_PCI_QUIRK(0x1558, 0x97e1, "Clevo P970[ER][CDFN]", ALC1220_FIXUP_CLEVO_P950),
|
||||||
SND_PCI_QUIRK(0x1558, 0x97e2, "Clevo P970RC-M", ALC1220_FIXUP_CLEVO_P950),
|
SND_PCI_QUIRK(0x1558, 0x97e2, "Clevo P970RC-M", ALC1220_FIXUP_CLEVO_P950),
|
||||||
SND_PCI_QUIRK(0x1558, 0x50d3, "Clevo PC50[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
|
||||||
SND_PCI_QUIRK(0x1558, 0x65d1, "Clevo PB51[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
|
||||||
SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
|
||||||
SND_PCI_QUIRK(0x1558, 0x65e1, "Clevo PB51[ED][DF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
|
||||||
SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
|
||||||
SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
|
||||||
SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
|
||||||
SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
|
|
||||||
SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
|
SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
|
||||||
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
|
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
|
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
|
||||||
|
@ -3103,7 +3105,7 @@ static void alc_headset_btn_callback(struct hda_codec *codec,
|
||||||
if (jack->unsol_res & (7 << 10))
|
if (jack->unsol_res & (7 << 10))
|
||||||
report |= SND_JACK_BTN_3;
|
report |= SND_JACK_BTN_3;
|
||||||
|
|
||||||
jack->jack->button_state = report;
|
snd_hda_jack_set_button_state(codec, jack->nid, report);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void alc_disable_headset_jack_key(struct hda_codec *codec)
|
static void alc_disable_headset_jack_key(struct hda_codec *codec)
|
||||||
|
@ -3164,16 +3166,23 @@ static void alc_fixup_headset_jack(struct hda_codec *codec,
|
||||||
const struct hda_fixup *fix, int action)
|
const struct hda_fixup *fix, int action)
|
||||||
{
|
{
|
||||||
struct alc_spec *spec = codec->spec;
|
struct alc_spec *spec = codec->spec;
|
||||||
|
hda_nid_t hp_pin;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case HDA_FIXUP_ACT_PRE_PROBE:
|
case HDA_FIXUP_ACT_PRE_PROBE:
|
||||||
spec->has_hs_key = 1;
|
spec->has_hs_key = 1;
|
||||||
snd_hda_jack_detect_enable_callback(codec, 0x55,
|
snd_hda_jack_detect_enable_callback(codec, 0x55,
|
||||||
alc_headset_btn_callback);
|
alc_headset_btn_callback);
|
||||||
snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack", false,
|
|
||||||
SND_JACK_HEADSET, alc_headset_btn_keymap);
|
|
||||||
break;
|
break;
|
||||||
case HDA_FIXUP_ACT_INIT:
|
case HDA_FIXUP_ACT_BUILD:
|
||||||
|
hp_pin = alc_get_hp_pin(spec);
|
||||||
|
if (!hp_pin || snd_hda_jack_bind_keymap(codec, 0x55,
|
||||||
|
alc_headset_btn_keymap,
|
||||||
|
hp_pin))
|
||||||
|
snd_hda_jack_add_kctl(codec, 0x55, "Headset Jack",
|
||||||
|
false, SND_JACK_HEADSET,
|
||||||
|
alc_headset_btn_keymap);
|
||||||
|
|
||||||
alc_enable_headset_jack_key(codec);
|
alc_enable_headset_jack_key(codec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4438,6 +4447,25 @@ static void alc236_fixup_hp_mute_led(struct hda_codec *codec,
|
||||||
alc236_fixup_hp_coef_micmute_led(codec, fix, action);
|
alc236_fixup_hp_coef_micmute_led(codec, fix, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void alc236_fixup_hp_micmute_led_vref(struct hda_codec *codec,
|
||||||
|
const struct hda_fixup *fix, int action)
|
||||||
|
{
|
||||||
|
struct alc_spec *spec = codec->spec;
|
||||||
|
|
||||||
|
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
|
||||||
|
spec->cap_mute_led_nid = 0x1a;
|
||||||
|
snd_hda_gen_add_micmute_led_cdev(codec, vref_micmute_led_set);
|
||||||
|
codec->power_filter = led_power_filter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void alc236_fixup_hp_mute_led_micmute_vref(struct hda_codec *codec,
|
||||||
|
const struct hda_fixup *fix, int action)
|
||||||
|
{
|
||||||
|
alc236_fixup_hp_mute_led_coefbit(codec, fix, action);
|
||||||
|
alc236_fixup_hp_micmute_led_vref(codec, fix, action);
|
||||||
|
}
|
||||||
|
|
||||||
#if IS_REACHABLE(CONFIG_INPUT)
|
#if IS_REACHABLE(CONFIG_INPUT)
|
||||||
static void gpio2_mic_hotkey_event(struct hda_codec *codec,
|
static void gpio2_mic_hotkey_event(struct hda_codec *codec,
|
||||||
struct hda_jack_callback *event)
|
struct hda_jack_callback *event)
|
||||||
|
@ -6232,6 +6260,9 @@ static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
|
||||||
/* for alc295_fixup_hp_top_speakers */
|
/* for alc295_fixup_hp_top_speakers */
|
||||||
#include "hp_x360_helper.c"
|
#include "hp_x360_helper.c"
|
||||||
|
|
||||||
|
/* for alc285_fixup_ideapad_s740_coef() */
|
||||||
|
#include "ideapad_s740_helper.c"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ALC269_FIXUP_GPIO2,
|
ALC269_FIXUP_GPIO2,
|
||||||
ALC269_FIXUP_SONY_VAIO,
|
ALC269_FIXUP_SONY_VAIO,
|
||||||
|
@ -6400,6 +6431,7 @@ enum {
|
||||||
ALC285_FIXUP_HP_MUTE_LED,
|
ALC285_FIXUP_HP_MUTE_LED,
|
||||||
ALC236_FIXUP_HP_GPIO_LED,
|
ALC236_FIXUP_HP_GPIO_LED,
|
||||||
ALC236_FIXUP_HP_MUTE_LED,
|
ALC236_FIXUP_HP_MUTE_LED,
|
||||||
|
ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF,
|
||||||
ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
|
ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
|
||||||
ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
|
ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
|
||||||
ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS,
|
ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS,
|
||||||
|
@ -6415,6 +6447,8 @@ enum {
|
||||||
ALC269_FIXUP_LEMOTE_A1802,
|
ALC269_FIXUP_LEMOTE_A1802,
|
||||||
ALC269_FIXUP_LEMOTE_A190X,
|
ALC269_FIXUP_LEMOTE_A190X,
|
||||||
ALC256_FIXUP_INTEL_NUC8_RUGGED,
|
ALC256_FIXUP_INTEL_NUC8_RUGGED,
|
||||||
|
ALC233_FIXUP_INTEL_NUC8_DMIC,
|
||||||
|
ALC233_FIXUP_INTEL_NUC8_BOOST,
|
||||||
ALC256_FIXUP_INTEL_NUC10,
|
ALC256_FIXUP_INTEL_NUC10,
|
||||||
ALC255_FIXUP_XIAOMI_HEADSET_MIC,
|
ALC255_FIXUP_XIAOMI_HEADSET_MIC,
|
||||||
ALC274_FIXUP_HP_MIC,
|
ALC274_FIXUP_HP_MIC,
|
||||||
|
@ -6427,6 +6461,8 @@ enum {
|
||||||
ALC282_FIXUP_ACER_DISABLE_LINEOUT,
|
ALC282_FIXUP_ACER_DISABLE_LINEOUT,
|
||||||
ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST,
|
ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST,
|
||||||
ALC256_FIXUP_ACER_HEADSET_MIC,
|
ALC256_FIXUP_ACER_HEADSET_MIC,
|
||||||
|
ALC285_FIXUP_IDEAPAD_S740_COEF,
|
||||||
|
ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct hda_fixup alc269_fixups[] = {
|
static const struct hda_fixup alc269_fixups[] = {
|
||||||
|
@ -7136,6 +7172,16 @@ static const struct hda_fixup alc269_fixups[] = {
|
||||||
.type = HDA_FIXUP_FUNC,
|
.type = HDA_FIXUP_FUNC,
|
||||||
.v.func = alc233_fixup_lenovo_line2_mic_hotkey,
|
.v.func = alc233_fixup_lenovo_line2_mic_hotkey,
|
||||||
},
|
},
|
||||||
|
[ALC233_FIXUP_INTEL_NUC8_DMIC] = {
|
||||||
|
.type = HDA_FIXUP_FUNC,
|
||||||
|
.v.func = alc_fixup_inv_dmic,
|
||||||
|
.chained = true,
|
||||||
|
.chain_id = ALC233_FIXUP_INTEL_NUC8_BOOST,
|
||||||
|
},
|
||||||
|
[ALC233_FIXUP_INTEL_NUC8_BOOST] = {
|
||||||
|
.type = HDA_FIXUP_FUNC,
|
||||||
|
.v.func = alc269_fixup_limit_int_mic_boost
|
||||||
|
},
|
||||||
[ALC255_FIXUP_DELL_SPK_NOISE] = {
|
[ALC255_FIXUP_DELL_SPK_NOISE] = {
|
||||||
.type = HDA_FIXUP_FUNC,
|
.type = HDA_FIXUP_FUNC,
|
||||||
.v.func = alc_fixup_disable_aamix,
|
.v.func = alc_fixup_disable_aamix,
|
||||||
|
@ -7646,6 +7692,10 @@ static const struct hda_fixup alc269_fixups[] = {
|
||||||
.type = HDA_FIXUP_FUNC,
|
.type = HDA_FIXUP_FUNC,
|
||||||
.v.func = alc236_fixup_hp_mute_led,
|
.v.func = alc236_fixup_hp_mute_led,
|
||||||
},
|
},
|
||||||
|
[ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF] = {
|
||||||
|
.type = HDA_FIXUP_FUNC,
|
||||||
|
.v.func = alc236_fixup_hp_mute_led_micmute_vref,
|
||||||
|
},
|
||||||
[ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = {
|
[ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET] = {
|
||||||
.type = HDA_FIXUP_VERBS,
|
.type = HDA_FIXUP_VERBS,
|
||||||
.v.verbs = (const struct hda_verb[]) {
|
.v.verbs = (const struct hda_verb[]) {
|
||||||
|
@ -7901,6 +7951,18 @@ static const struct hda_fixup alc269_fixups[] = {
|
||||||
.chained = true,
|
.chained = true,
|
||||||
.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
|
.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
|
||||||
},
|
},
|
||||||
|
[ALC285_FIXUP_IDEAPAD_S740_COEF] = {
|
||||||
|
.type = HDA_FIXUP_FUNC,
|
||||||
|
.v.func = alc285_fixup_ideapad_s740_coef,
|
||||||
|
.chained = true,
|
||||||
|
.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
|
||||||
|
},
|
||||||
|
[ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST] = {
|
||||||
|
.type = HDA_FIXUP_FUNC,
|
||||||
|
.v.func = alc269_fixup_limit_int_mic_boost,
|
||||||
|
.chained = true,
|
||||||
|
.chain_id = ALC285_FIXUP_HP_MUTE_LED,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
|
@ -7909,12 +7971,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
|
SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
|
||||||
SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
|
SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
|
||||||
SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
|
SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
|
|
||||||
SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
|
SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
|
||||||
SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
|
SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
|
||||||
SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
|
SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
|
||||||
SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
|
SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
|
||||||
SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
|
SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
|
||||||
|
SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x1025, 0x0840, "Acer Aspire E1", ALC269VB_FIXUP_ASPIRE_E1_COEF),
|
SND_PCI_QUIRK(0x1025, 0x0840, "Acer Aspire E1", ALC269VB_FIXUP_ASPIRE_E1_COEF),
|
||||||
SND_PCI_QUIRK(0x1025, 0x101c, "Acer Veriton N2510G", ALC269_FIXUP_LIFEBOOK),
|
SND_PCI_QUIRK(0x1025, 0x101c, "Acer Veriton N2510G", ALC269_FIXUP_LIFEBOOK),
|
||||||
SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
|
||||||
|
@ -7970,8 +8032,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
|
SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP),
|
||||||
SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
|
SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME),
|
||||||
SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
|
SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
|
||||||
SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
|
SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
|
||||||
|
SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
|
||||||
SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
|
SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
|
||||||
SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
|
SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
|
||||||
|
@ -7981,8 +8043,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
|
SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
|
||||||
SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
|
SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
|
||||||
|
SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
|
||||||
SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x0a2e, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC),
|
SND_PCI_QUIRK(0x1028, 0x0a2e, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC),
|
||||||
|
@ -7993,35 +8055,18 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
|
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
|
||||||
SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
|
SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
|
SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
|
|
||||||
/* ALC282 */
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
|
||||||
/* ALC290 */
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
|
@ -8029,28 +8074,45 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
|
||||||
SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
|
|
||||||
SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x103c, 0x802e, "HP Z240 SFF", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x103c, 0x802f, "HP Z240", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x8077, "HP", ALC256_FIXUP_HP_HEADSET_MIC),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x8158, "HP", ALC256_FIXUP_HP_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
|
SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
|
SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
|
||||||
SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
|
SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
|
||||||
|
@ -8063,6 +8125,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED),
|
SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED),
|
SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED),
|
SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x8730, "HP ProBook 445 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT),
|
SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED),
|
SND_PCI_QUIRK(0x103c, 0x8760, "HP", ALC285_FIXUP_HP_MUTE_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
|
SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
|
||||||
|
@ -8079,6 +8142,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP),
|
SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP),
|
||||||
SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
|
SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
|
||||||
SND_PCI_QUIRK(0x103c, 0x884c, "HP EliteBook 840 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
|
SND_PCI_QUIRK(0x103c, 0x884c, "HP EliteBook 840 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
|
||||||
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
|
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
|
||||||
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
|
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
|
||||||
SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||||
|
@ -8087,16 +8151,18 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||||
SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||||
|
SND_PCI_QUIRK(0x1043, 0x125e, "ASUS Q524UQK", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1043, 0x1271, "ASUS X430UN", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1043, 0x1271, "ASUS X430UN", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
|
|
||||||
SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
|
SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC),
|
||||||
|
SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC),
|
||||||
SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
|
SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC),
|
||||||
SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
|
SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
|
||||||
SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
|
SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
|
||||||
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
|
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
|
||||||
SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
|
SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
|
||||||
|
SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS),
|
||||||
SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
|
SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
|
SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x1043, 0x194e, "ASUS UX563FD", ALC294_FIXUP_ASUS_HPE),
|
SND_PCI_QUIRK(0x1043, 0x194e, "ASUS UX563FD", ALC294_FIXUP_ASUS_HPE),
|
||||||
|
@ -8109,31 +8175,31 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
|
SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
|
||||||
SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||||
SND_PCI_QUIRK(0x1043, 0x125e, "ASUS Q524UQK", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE),
|
|
||||||
SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
|
SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
|
||||||
SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
|
SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
|
||||||
SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
|
SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
|
||||||
|
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, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
|
||||||
SND_PCI_QUIRK(0x1043, 0x1881, "ASUS Zephyrus S/M", ALC294_FIXUP_ASUS_GX502_PINS),
|
|
||||||
SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
|
SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
|
||||||
SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
|
SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
|
||||||
SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
|
SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
|
||||||
SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
|
SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
|
||||||
SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
|
SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
|
||||||
SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
|
SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
|
||||||
SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
|
|
||||||
SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
|
|
||||||
SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
|
SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
|
||||||
SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
|
SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
|
||||||
SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
|
SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
|
||||||
SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
|
SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
|
||||||
|
SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
|
||||||
|
SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
|
SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
|
||||||
SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
|
SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
|
||||||
SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
|
SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
|
||||||
SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
|
|
||||||
SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
|
SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC),
|
||||||
|
SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
|
||||||
SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
|
SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
|
||||||
SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
|
SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
|
||||||
|
SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
|
SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
|
||||||
SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
|
SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
|
||||||
SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
|
SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
|
||||||
|
@ -8143,9 +8209,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
|
SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
|
||||||
SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
|
SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
|
||||||
SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET),
|
SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", 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, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
|
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, 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(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
|
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, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
|
SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
|
||||||
|
@ -8201,9 +8267,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
|
SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
|
SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
|
SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
|
||||||
|
SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST),
|
SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK_LIMIT_BOOST),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
|
SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
|
|
||||||
SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
|
SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
|
SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
|
SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
|
||||||
|
@ -8244,9 +8310,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
|
SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
|
SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940", ALC298_FIXUP_LENOVO_SPK_VOLUME),
|
SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940", ALC298_FIXUP_LENOVO_SPK_VOLUME),
|
||||||
|
SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
|
SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
|
SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
|
SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
|
||||||
|
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
|
SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
|
SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
|
||||||
|
@ -8265,20 +8333,19 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
|
SND_PCI_QUIRK(0x17aa, 0x511e, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
|
SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
|
|
||||||
SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
|
SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
|
||||||
SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
|
SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
|
||||||
SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),
|
SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),
|
||||||
SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI),
|
SND_PCI_QUIRK(0x1b35, 0x1236, "CZC TMI", ALC269_FIXUP_CZC_TMI),
|
||||||
SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101),
|
SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101),
|
||||||
SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
|
SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
|
||||||
|
SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
|
||||||
|
SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
|
||||||
SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
|
SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
|
SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
|
SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
|
||||||
SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
|
SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC),
|
||||||
SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
|
|
||||||
SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
|
|
||||||
SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
|
SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
|
||||||
SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10),
|
SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10),
|
||||||
|
|
||||||
|
@ -8733,12 +8800,7 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
|
||||||
{0x12, 0x90a60130},
|
{0x12, 0x90a60130},
|
||||||
{0x19, 0x03a11020},
|
{0x19, 0x03a11020},
|
||||||
{0x21, 0x0321101f}),
|
{0x21, 0x0321101f}),
|
||||||
SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK,
|
|
||||||
{0x14, 0x90170110},
|
|
||||||
{0x19, 0x04a11040},
|
|
||||||
{0x21, 0x04211020}),
|
|
||||||
SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
|
SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE,
|
||||||
{0x12, 0x90a60130},
|
|
||||||
{0x14, 0x90170110},
|
{0x14, 0x90170110},
|
||||||
{0x19, 0x04a11040},
|
{0x19, 0x04a11040},
|
||||||
{0x21, 0x04211020}),
|
{0x21, 0x04211020}),
|
||||||
|
@ -8909,6 +8971,10 @@ static const struct snd_hda_pin_quirk alc269_fallback_pin_fixup_tbl[] = {
|
||||||
SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
|
SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
|
||||||
{0x19, 0x40000000},
|
{0x19, 0x40000000},
|
||||||
{0x1a, 0x40000000}),
|
{0x1a, 0x40000000}),
|
||||||
|
SND_HDA_PIN_QUIRK(0x10ec0285, 0x17aa, "Lenovo", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK,
|
||||||
|
{0x14, 0x90170110},
|
||||||
|
{0x19, 0x04a11040},
|
||||||
|
{0x21, 0x04211020}),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9224,8 +9290,7 @@ static const struct snd_pci_quirk alc861_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
|
SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
|
||||||
SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
|
SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
|
||||||
SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
|
SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
|
||||||
SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
|
SND_PCI_QUIRK_VENDOR(0x1584, "Haier/Uniwill", ALC861_FIXUP_AMP_VREF_0F),
|
||||||
SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
|
|
||||||
SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
|
SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
@ -10020,6 +10085,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
|
SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
|
||||||
SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
|
SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
|
||||||
SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
|
SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
|
||||||
|
SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS),
|
||||||
SND_PCI_QUIRK(0x1025, 0x123c, "Acer Nitro N50-600", ALC662_FIXUP_ACER_NITRO_HEADSET_MODE),
|
SND_PCI_QUIRK(0x1025, 0x123c, "Acer Nitro N50-600", ALC662_FIXUP_ACER_NITRO_HEADSET_MODE),
|
||||||
SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE),
|
SND_PCI_QUIRK(0x1025, 0x124e, "Acer 2660G", ALC662_FIXUP_ACER_X2660G_HEADSET_MODE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
||||||
|
@ -10036,9 +10102,9 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2),
|
SND_PCI_QUIRK(0x103c, 0x873e, "HP", ALC671_FIXUP_HP_HEADSET_MIC2),
|
||||||
SND_PCI_QUIRK(0x1043, 0x1080, "Asus UX501VW", ALC668_FIXUP_HEADSET_MODE),
|
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, 0x11cd, "Asus N550", ALC662_FIXUP_ASUS_Nx50),
|
||||||
SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
|
|
||||||
SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
|
SND_PCI_QUIRK(0x1043, 0x129d, "Asus N750", ALC662_FIXUP_ASUS_Nx50),
|
||||||
SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
|
SND_PCI_QUIRK(0x1043, 0x12ff, "ASUS G751", ALC668_FIXUP_ASUS_G751),
|
||||||
|
SND_PCI_QUIRK(0x1043, 0x13df, "Asus N550JX", ALC662_FIXUP_BASS_1A),
|
||||||
SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
|
SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
|
||||||
SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
|
SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
|
||||||
SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
|
SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
|
||||||
|
@ -10058,7 +10124,6 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
|
SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
|
||||||
SND_PCI_QUIRK(0x1b35, 0x1234, "CZC ET26", ALC662_FIXUP_CZC_ET26),
|
SND_PCI_QUIRK(0x1b35, 0x1234, "CZC ET26", ALC662_FIXUP_CZC_ET26),
|
||||||
SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
|
SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
|
||||||
SND_PCI_QUIRK(0x1025, 0x0566, "Acer Aspire Ethos 8951G", ALC669_FIXUP_ACER_ASPIRE_ETHOS),
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Below is a quirk table taken from the old code.
|
/* Below is a quirk table taken from the old code.
|
||||||
|
|
|
@ -4277,6 +4277,9 @@ static int stac_parse_auto_config(struct hda_codec *codec)
|
||||||
|
|
||||||
spec->gen.automute_hook = stac_update_outputs;
|
spec->gen.automute_hook = stac_update_outputs;
|
||||||
|
|
||||||
|
if (spec->gpio_led)
|
||||||
|
snd_hda_gen_add_mute_led_cdev(codec, stac_vmaster_hook);
|
||||||
|
|
||||||
err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
|
err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
@ -4318,9 +4321,6 @@ static int stac_parse_auto_config(struct hda_codec *codec)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (spec->gpio_led)
|
|
||||||
snd_hda_gen_add_mute_led_cdev(codec, stac_vmaster_hook);
|
|
||||||
|
|
||||||
if (spec->aloopback_ctl &&
|
if (spec->aloopback_ctl &&
|
||||||
snd_hda_get_bool_hint(codec, "loopback") == 1) {
|
snd_hda_get_bool_hint(codec, "loopback") == 1) {
|
||||||
unsigned int wr_verb =
|
unsigned int wr_verb =
|
||||||
|
|
|
@ -18,7 +18,7 @@ static bool is_thinkpad(struct hda_codec *codec)
|
||||||
static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
|
static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
|
||||||
const struct hda_fixup *fix, int action)
|
const struct hda_fixup *fix, int action)
|
||||||
{
|
{
|
||||||
if (action == HDA_FIXUP_ACT_PROBE) {
|
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
|
||||||
if (!is_thinkpad(codec))
|
if (!is_thinkpad(codec))
|
||||||
return;
|
return;
|
||||||
snd_hda_gen_add_mute_led_cdev(codec, NULL);
|
snd_hda_gen_add_mute_led_cdev(codec, NULL);
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wait for a value on a peudo register, exit with a timeout
|
* mixart_wait_nice_for_register_value - wait for a value on a peudo register,
|
||||||
|
* exit with a timeout
|
||||||
*
|
*
|
||||||
* @mgr: pointer to miXart manager structure
|
* @mgr: pointer to miXart manager structure
|
||||||
* @offset: unsigned pseudo_register base + offset of value
|
* @offset: unsigned pseudo_register base + offset of value
|
||||||
|
|
|
@ -5390,7 +5390,8 @@ static int snd_hdsp_free(struct hdsp *hdsp)
|
||||||
if (hdsp->port)
|
if (hdsp->port)
|
||||||
pci_release_regions(hdsp->pci);
|
pci_release_regions(hdsp->pci);
|
||||||
|
|
||||||
pci_disable_device(hdsp->pci);
|
if (pci_is_enabled(hdsp->pci))
|
||||||
|
pci_disable_device(hdsp->pci);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6883,7 +6883,8 @@ static int snd_hdspm_free(struct hdspm * hdspm)
|
||||||
if (hdspm->port)
|
if (hdspm->port)
|
||||||
pci_release_regions(hdspm->pci);
|
pci_release_regions(hdspm->pci);
|
||||||
|
|
||||||
pci_disable_device(hdspm->pci);
|
if (pci_is_enabled(hdspm->pci))
|
||||||
|
pci_disable_device(hdspm->pci);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1731,7 +1731,8 @@ static int snd_rme9652_free(struct snd_rme9652 *rme9652)
|
||||||
if (rme9652->port)
|
if (rme9652->port)
|
||||||
pci_release_regions(rme9652->pci);
|
pci_release_regions(rme9652->pci);
|
||||||
|
|
||||||
pci_disable_device(rme9652->pci);
|
if (pci_is_enabled(rme9652->pci))
|
||||||
|
pci_disable_device(rme9652->pci);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue