Merge tag 'sound-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"This includes lots of file shuffling due to HD-audio code
reorganization and many trivial changes, but otherwise there shouldn't
be much surprise from the functionality POV. The PR includes the PM
changes as prerequisite, too. Some highlights below:
Core:
- Performance optimizations in PCM core code
- Refactoring of ASoC Kconfig menus to be hopefully more consistant
and easier to navigate.
- Refactoring of ASoC DAPM code, mainly hiding functionality that
doesn't need to be exposed to drivers
HD-audio reorganization:
- All code are moved under sound/hda with a bit more understandable
tree structure, as well as file renames
- The huge Realtek driver code is split to several parts, a common
helper module with driver modules per probe entry
- HDMI and Cirrus codec drivers also split
ASoC:
- Further work on the generic handling for SoundWire SDCA devices
- Support for AMD ACP7.2 and SoundWire on ACP 7.1, Fairphone 4 & 5,
various Intel systems, Qualcomm QCS8275, Richtek RTQ9124 and TI
TAS5753
HD-audio and USB-audio:
- TAS2781 driver cleanup and TAS2770 support
- EQ enablement in CA0132 driver
- USB audio quirk code cleanups
Others:
- Cleanups of PM autosuspend call patterns with the update from the
PM tree
- Lots of strcpy() -> strscpy() conversions for fixed size arrays"
* tag 'sound-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (385 commits)
ALSA: hda: Add TAS2770 support
ASoC: qcom: sm8250: Add Fairphone 4 soundcard compatible
ASoC: dt-bindings: qcom,sm8250: Add Fairphone 4 sound card
ASoC: dt-bindings: qcom,q6afe: Document q6usb subnode
ASoC: SDCA: Fix implicit cast from le16
ASoC: SDCA: Shrink detected_mode_handler() stack frame
ASoC: SDCA: Check devm_mutex_init() return value
ASoC: SDCA: add route by the number of input pins in MU entity
ALSA: hda/realtek: Add support for ASUS Commercial laptops using CS35L41 HDA
ASoC: Intel: sof_rt5682: Add HDMI-In capture with rt5682 support for PTL.
ASoC: codec: tlv320aic32x4: Fix reset GPIO check
ASoC: dt-bindings: qcom,lpass-va-macro: Define clock-names in top-level
ASoC: SDCA: Add hw_params() helper function
ASoC: SDCA: Add a helper to get the SoundWire port number
ASoC: SDCA: Add helper to add DAI constraints
ASoC: soc-dai: Add private data to snd_soc_dai
ASoC: SDCA: Move SDCA search functions and export
ASoC: SDCA: Remove overly chatty input pin list warning
ASoC: SDCA: Allow read-only controls to be deferrable
ASoC: SDCA: Update memory allocations to zero initialise
...
This commit is contained in:
@@ -41,6 +41,10 @@ properties:
|
||||
description: This pin is connected to the chip's RESET pin.
|
||||
maxItems: 1
|
||||
|
||||
port:
|
||||
$ref: audio-graph-port.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/fsl,mxs-audio-sgtl5000.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale MXS audio complex with SGTL5000 codec
|
||||
|
||||
maintainers:
|
||||
- Frank Li <Frank.Li@nxp.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- bluegiga,apx4devkit-sgtl5000
|
||||
- denx,m28evk-sgtl5000
|
||||
- fsl,imx28-evk-sgtl5000
|
||||
- fsl,imx28-mbmx28lc-sgtl5000
|
||||
- fsl,imx28-tx28-sgtl5000
|
||||
- const: fsl,mxs-audio-sgtl5000
|
||||
|
||||
model:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: The user-visible name of this sound complex
|
||||
|
||||
saif-controllers:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description: The phandle list of the MXS SAIF controller
|
||||
|
||||
audio-codec:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle of the SGTL5000 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. Valid names could be power supplies, SGTL5000
|
||||
pins, and the jacks on the board:
|
||||
|
||||
Power supplies:
|
||||
* Mic Bias
|
||||
|
||||
SGTL5000 pins:
|
||||
* MIC_IN
|
||||
* LINE_IN
|
||||
* HP_OUT
|
||||
* LINE_OUT
|
||||
|
||||
Board connectors:
|
||||
* Mic Jack
|
||||
* Line In Jack
|
||||
* Headphone Jack
|
||||
* Line Out Jack
|
||||
* Ext Spk
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- saif-controllers
|
||||
- audio-codec
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
sound {
|
||||
compatible = "fsl,imx28-evk-sgtl5000", "fsl,mxs-audio-sgtl5000";
|
||||
model = "imx28-evk-sgtl5000";
|
||||
saif-controllers = <&saif0 &saif1>;
|
||||
audio-codec = <&sgtl5000>;
|
||||
audio-routing =
|
||||
"MIC_IN", "Mic Jack",
|
||||
"Mic Jack", "Mic Bias",
|
||||
"Headphone Jack", "HP_OUT";
|
||||
};
|
||||
@@ -0,0 +1,98 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/sound/mediatek,mt8173-afe-pcm.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Mediatek AFE PCM controller for MT8173
|
||||
|
||||
maintainers:
|
||||
- Trevor Wu <trevor.wu@mediatek.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8173-afe-pcm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: audio infra sys clock
|
||||
- description: audio top mux
|
||||
- description: audio intbus mux
|
||||
- description: apll1 clock
|
||||
- description: apll2 clock
|
||||
- description: i2s0 mclk mux
|
||||
- description: i2s1 mclk mux
|
||||
- description: i2s2 mclk mux
|
||||
- description: i2s3 mclk mux
|
||||
- description: i2s3 bclk mux
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: infra_sys_audio_clk
|
||||
- const: top_pdn_audio
|
||||
- const: top_pdn_aud_intbus
|
||||
- const: bck0
|
||||
- const: bck1
|
||||
- const: i2s0_m
|
||||
- const: i2s1_m
|
||||
- const: i2s2_m
|
||||
- const: i2s3_m
|
||||
- const: i2s3_b
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
memory-region:
|
||||
description: memory region for audio DMA buffers
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/mt8173-clk.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/power/mt8173-power.h>
|
||||
|
||||
mt8173-afe-pcm@11220000 {
|
||||
compatible = "mediatek,mt8173-afe-pcm";
|
||||
reg = <0x11220000 0x1000>;
|
||||
interrupts = <GIC_SPI 134 IRQ_TYPE_EDGE_FALLING>;
|
||||
power-domains = <&spm MT8173_POWER_DOMAIN_AUDIO>;
|
||||
clocks = <&infracfg CLK_INFRA_AUDIO>,
|
||||
<&topckgen CLK_TOP_AUDIO_SEL>,
|
||||
<&topckgen CLK_TOP_AUD_INTBUS_SEL>,
|
||||
<&topckgen CLK_TOP_APLL1_DIV0>,
|
||||
<&topckgen CLK_TOP_APLL2_DIV0>,
|
||||
<&topckgen CLK_TOP_I2S0_M_SEL>,
|
||||
<&topckgen CLK_TOP_I2S1_M_SEL>,
|
||||
<&topckgen CLK_TOP_I2S2_M_SEL>,
|
||||
<&topckgen CLK_TOP_I2S3_M_SEL>,
|
||||
<&topckgen CLK_TOP_I2S3_B_SEL>;
|
||||
clock-names = "infra_sys_audio_clk",
|
||||
"top_pdn_audio",
|
||||
"top_pdn_aud_intbus",
|
||||
"bck0",
|
||||
"bck1",
|
||||
"i2s0_m",
|
||||
"i2s1_m",
|
||||
"i2s2_m",
|
||||
"i2s3_m",
|
||||
"i2s3_b";
|
||||
memory-region = <&afe_dma_mem>;
|
||||
};
|
||||
@@ -25,6 +25,10 @@ properties:
|
||||
reset-names:
|
||||
const: audiosys
|
||||
|
||||
memory-region:
|
||||
description: memory region for audio DMA buffers
|
||||
maxItems: 1
|
||||
|
||||
mediatek,apmixedsys:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle of the mediatek apmixedsys controller
|
||||
@@ -170,6 +174,7 @@ examples:
|
||||
"top_apll12_div_tdm",
|
||||
"top_mux_audio_h",
|
||||
"top_clk26m_clk";
|
||||
memory-region = <&afe_dma_mem>;
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
@@ -23,6 +23,10 @@ properties:
|
||||
reset-names:
|
||||
const: audiosys
|
||||
|
||||
memory-region:
|
||||
description: memory region for audio DMA buffers
|
||||
maxItems: 1
|
||||
|
||||
mediatek,apmixedsys:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: The phandle of the mediatek apmixedsys controller
|
||||
@@ -95,6 +99,7 @@ examples:
|
||||
"aud_dac_predis_clk",
|
||||
"aud_infra_clk",
|
||||
"aud_infra_26m_clk";
|
||||
memory-region = <&afe_dma_mem>;
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
Mediatek AFE PCM controller
|
||||
|
||||
Required properties:
|
||||
- compatible = "mediatek,mt8173-afe-pcm";
|
||||
- reg: register location and size
|
||||
- interrupts: Should contain AFE interrupt
|
||||
- clock-names: should have these clock names:
|
||||
"infra_sys_audio_clk",
|
||||
"top_pdn_audio",
|
||||
"top_pdn_aud_intbus",
|
||||
"bck0",
|
||||
"bck1",
|
||||
"i2s0_m",
|
||||
"i2s1_m",
|
||||
"i2s2_m",
|
||||
"i2s3_m",
|
||||
"i2s3_b";
|
||||
|
||||
Example:
|
||||
|
||||
afe: mt8173-afe-pcm@11220000 {
|
||||
compatible = "mediatek,mt8173-afe-pcm";
|
||||
reg = <0 0x11220000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 134 IRQ_TYPE_EDGE_FALLING>;
|
||||
clocks = <&infracfg INFRA_AUDIO>,
|
||||
<&topckgen TOP_AUDIO_SEL>,
|
||||
<&topckgen TOP_AUD_INTBUS_SEL>,
|
||||
<&topckgen TOP_APLL1_DIV0>,
|
||||
<&topckgen TOP_APLL2_DIV0>,
|
||||
<&topckgen TOP_I2S0_M_CK_SEL>,
|
||||
<&topckgen TOP_I2S1_M_CK_SEL>,
|
||||
<&topckgen TOP_I2S2_M_CK_SEL>,
|
||||
<&topckgen TOP_I2S3_M_CK_SEL>,
|
||||
<&topckgen TOP_I2S3_B_CK_SEL>;
|
||||
clock-names = "infra_sys_audio_clk",
|
||||
"top_pdn_audio",
|
||||
"top_pdn_aud_intbus",
|
||||
"bck0",
|
||||
"bck1",
|
||||
"i2s0_m",
|
||||
"i2s1_m",
|
||||
"i2s2_m",
|
||||
"i2s3_m",
|
||||
"i2s3_b";
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
* Freescale MXS audio complex with SGTL5000 codec
|
||||
|
||||
Required properties:
|
||||
- compatible : "fsl,mxs-audio-sgtl5000"
|
||||
- model : The user-visible name of this sound complex
|
||||
- saif-controllers : The phandle list of the MXS SAIF controller
|
||||
- audio-codec : The phandle of the SGTL5000 audio codec
|
||||
- audio-routing : A list of the connections between audio components.
|
||||
Each entry is a pair of strings, the first being the
|
||||
connection's sink, the second being the connection's
|
||||
source. Valid names could be power supplies, SGTL5000
|
||||
pins, and the jacks on the board:
|
||||
|
||||
Power supplies:
|
||||
* Mic Bias
|
||||
|
||||
SGTL5000 pins:
|
||||
* MIC_IN
|
||||
* LINE_IN
|
||||
* HP_OUT
|
||||
* LINE_OUT
|
||||
|
||||
Board connectors:
|
||||
* Mic Jack
|
||||
* Line In Jack
|
||||
* Headphone Jack
|
||||
* Line Out Jack
|
||||
* Ext Spk
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "fsl,imx28-evk-sgtl5000",
|
||||
"fsl,mxs-audio-sgtl5000";
|
||||
model = "imx28-evk-sgtl5000";
|
||||
saif-controllers = <&saif0 &saif1>;
|
||||
audio-codec = <&sgtl5000>;
|
||||
audio-routing =
|
||||
"MIC_IN", "Mic Jack",
|
||||
"Mic Jack", "Mic Bias",
|
||||
"Headphone Jack", "HP_OUT";
|
||||
};
|
||||
@@ -40,7 +40,11 @@ properties:
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
items:
|
||||
- const: mclk
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- const: npl
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
@@ -80,8 +84,7 @@ allOf:
|
||||
clocks:
|
||||
maxItems: 1
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
maxItems: 1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
@@ -94,10 +97,8 @@ allOf:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
|
||||
- if:
|
||||
properties:
|
||||
@@ -112,11 +113,8 @@ allOf:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
- const: npl
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
|
||||
- if:
|
||||
properties:
|
||||
@@ -130,10 +128,8 @@ allOf:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
- const: macro
|
||||
- const: dcodec
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
||||
@@ -29,6 +29,12 @@ properties:
|
||||
unevaluatedProperties: false
|
||||
description: Qualcomm DSP audio ports
|
||||
|
||||
usbd:
|
||||
type: object
|
||||
$ref: /schemas/sound/qcom,q6usb.yaml#
|
||||
unevaluatedProperties: false
|
||||
description: Qualcomm DSP USB audio ports
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- dais
|
||||
@@ -64,5 +70,12 @@ examples:
|
||||
qcom,sd-lines = <0 1 2 3>;
|
||||
};
|
||||
};
|
||||
|
||||
usbd {
|
||||
compatible = "qcom,q6usb";
|
||||
#sound-dai-cells = <1>;
|
||||
iommus = <&apps_smmu 0x180f 0x0>;
|
||||
qcom,usb-audio-intr-idx = /bits/ 16 <2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -28,10 +28,12 @@ properties:
|
||||
- qcom,sm8750-sndcard
|
||||
- const: qcom,sm8450-sndcard
|
||||
- enum:
|
||||
- fairphone,fp4-sndcard
|
||||
- fairphone,fp5-sndcard
|
||||
- qcom,apq8096-sndcard
|
||||
- qcom,qcm6490-idp-sndcard
|
||||
- qcom,qcs6490-rb3gen2-sndcard
|
||||
- qcom,qcs8275-sndcard
|
||||
- qcom,qcs9075-sndcard
|
||||
- qcom,qcs9100-sndcard
|
||||
- qcom,qrb4210-rb2-sndcard
|
||||
|
||||
@@ -45,6 +45,9 @@ properties:
|
||||
purpose of handling altmode muxing and orientation switching to detect and
|
||||
enable Audio Accessory Mode.
|
||||
|
||||
vdd-px-supply:
|
||||
description: A reference to the 1.2V PX supply
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/sound/richtek,rt9123.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Richtek RT9123 Audio Amplifier
|
||||
title: Richtek RT9123/RTQ9124 Audio Amplifier
|
||||
|
||||
maintainers:
|
||||
- ChiYuan Huang <cy_huang@richtek.com>
|
||||
@@ -15,6 +15,12 @@ description:
|
||||
support various formats, including I2S, left-justified, right-justified, and
|
||||
TDM formats.
|
||||
|
||||
RTQ9124 is an ultra-low output noise, digital input, mono-channel Class-D
|
||||
power amplifier that supports a 2.1MHz switching frequency. It integrates
|
||||
both DC and AC load diagnostics, as well as real-time load monitoring to
|
||||
assess speaker condition. The device operates from 4.5V to 18V and delivers
|
||||
up to 30W output power.
|
||||
|
||||
allOf:
|
||||
- $ref: dai-common.yaml#
|
||||
|
||||
@@ -22,6 +28,7 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- richtek,rt9123
|
||||
- richtek,rtq9124
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -18,6 +18,7 @@ properties:
|
||||
- ti,tas5719
|
||||
- ti,tas5721
|
||||
- ti,tas5733
|
||||
- ti,tas5753
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@@ -98,6 +99,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- ti,tas5721
|
||||
- ti,tas5753
|
||||
then:
|
||||
properties:
|
||||
HPVDD-supply: false
|
||||
|
||||
+16
-5
@@ -5745,9 +5745,9 @@ F: drivers/spi/spi-cs42l43*
|
||||
F: include/dt-bindings/sound/cs*
|
||||
F: include/linux/mfd/cs42l43*
|
||||
F: include/sound/cs*
|
||||
F: sound/pci/hda/cirrus*
|
||||
F: sound/pci/hda/cs*
|
||||
F: sound/pci/hda/hda_component*
|
||||
F: sound/hda/codecs/cirrus*
|
||||
F: sound/hda/codecs/side-codecs/cs*
|
||||
F: sound/hda/codecs/side-codecs/hda_component*
|
||||
F: sound/soc/codecs/cs*
|
||||
|
||||
CIRRUS LOGIC HAPTIC DRIVERS
|
||||
@@ -22332,6 +22332,17 @@ M: Jim Cromie <jim.cromie@gmail.com>
|
||||
S: Maintained
|
||||
F: drivers/clocksource/scx200_hrt.c
|
||||
|
||||
SDCA LIBRARY AND CLASS DRIVER
|
||||
M: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
M: Maciej Strozek <mstrozek@opensource.cirrus.com>
|
||||
R: Bard Liao <yung-chuan.liao@linux.intel.com>
|
||||
R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
L: linux-sound@vger.kernel.org
|
||||
L: patches@opensource.cirrus.com
|
||||
S: Maintained
|
||||
F: include/sound/sdca*
|
||||
F: sound/soc/sdca/*
|
||||
|
||||
SDRICOH_CS MMC/SD HOST CONTROLLER INTERFACE DRIVER
|
||||
M: Sascha Sommer <saschasommer@freenet.de>
|
||||
L: sdricohcs-devel@lists.sourceforge.net (subscribers-only)
|
||||
@@ -24539,7 +24550,7 @@ F: Documentation/devicetree/bindings/sound/ti,tlv320*.yaml
|
||||
F: Documentation/devicetree/bindings/sound/ti,tlv320adcx140.yaml
|
||||
F: include/sound/tas2*.h
|
||||
F: include/sound/tlv320*.h
|
||||
F: sound/pci/hda/tas2781_hda_i2c.c
|
||||
F: sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
|
||||
F: sound/soc/codecs/pcm1681.c
|
||||
F: sound/soc/codecs/pcm1789*.*
|
||||
F: sound/soc/codecs/pcm179x*.*
|
||||
@@ -27474,7 +27485,7 @@ SENARYTECH AUDIO CODEC DRIVER
|
||||
M: bo liu <bo.liu@senarytech.com>
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
|
||||
F: sound/pci/hda/patch_senarytech.c
|
||||
F: sound/hda/codecs/senarytech.c
|
||||
|
||||
THE REST
|
||||
M: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
|
||||
@@ -791,8 +791,11 @@ CONFIG_SND=m
|
||||
CONFIG_SND_HDA_TEGRA=m
|
||||
CONFIG_SND_HDA_INPUT_BEEP=y
|
||||
CONFIG_SND_HDA_PATCH_LOADER=y
|
||||
CONFIG_SND_HDA_CODEC_REALTEK=m
|
||||
CONFIG_SND_HDA_CODEC_REALTEK=y
|
||||
CONFIG_SND_HDA_CODEC_REALTEK_LIB=m
|
||||
CONFIG_SND_HDA_CODEC_ALC269=m
|
||||
CONFIG_SND_HDA_CODEC_HDMI=m
|
||||
CONFIG_SND_HDA_CODEC_HDMI_TEGRA=m
|
||||
CONFIG_SND_USB_AUDIO=m
|
||||
CONFIG_SND_SOC=m
|
||||
CONFIG_SND_ATMEL_SOC=m
|
||||
|
||||
@@ -50,4 +50,3 @@ CONFIG_CRYPTO_DEV_IMGTEC_HASH=y
|
||||
CONFIG_IMGPDC_WDT=y
|
||||
CONFIG_IR_IMG=y
|
||||
CONFIG_CC10001_ADC=y
|
||||
CONFIG_SND_SOC_IMG=y
|
||||
|
||||
@@ -292,7 +292,9 @@ CONFIG_SND_SEQ_DUMMY=m
|
||||
# CONFIG_SND_ISA is not set
|
||||
CONFIG_SND_HDA_INTEL=m
|
||||
CONFIG_SND_HDA_PATCH_LOADER=y
|
||||
CONFIG_SND_HDA_CODEC_REALTEK=m
|
||||
CONFIG_SND_HDA_CODEC_REALTEK=y
|
||||
CONFIG_SND_HDA_CODEC_REALTEK_LIB=m
|
||||
CONFIG_SND_HDA_CODEC_ALC269=m
|
||||
CONFIG_SND_HDA_CODEC_SIGMATEL=m
|
||||
CONFIG_SND_HDA_CODEC_HDMI=m
|
||||
CONFIG_SND_HDA_CODEC_CONEXANT=m
|
||||
|
||||
@@ -311,6 +311,11 @@ static const struct cs_dsp_ops cs_dsp_adsp2_ops[];
|
||||
static const struct cs_dsp_ops cs_dsp_halo_ops;
|
||||
static const struct cs_dsp_ops cs_dsp_halo_ao_ops;
|
||||
|
||||
struct cs_dsp_alg_region_list_item {
|
||||
struct list_head list;
|
||||
struct cs_dsp_alg_region alg_region;
|
||||
};
|
||||
|
||||
struct cs_dsp_buf {
|
||||
struct list_head list;
|
||||
void *buf;
|
||||
@@ -1752,13 +1757,13 @@ static void *cs_dsp_read_algs(struct cs_dsp *dsp, size_t n_algs,
|
||||
struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp,
|
||||
int type, unsigned int id)
|
||||
{
|
||||
struct cs_dsp_alg_region *alg_region;
|
||||
struct cs_dsp_alg_region_list_item *item;
|
||||
|
||||
lockdep_assert_held(&dsp->pwr_lock);
|
||||
|
||||
list_for_each_entry(alg_region, &dsp->alg_regions, list) {
|
||||
if (id == alg_region->alg && type == alg_region->type)
|
||||
return alg_region;
|
||||
list_for_each_entry(item, &dsp->alg_regions, list) {
|
||||
if (id == item->alg_region.alg && type == item->alg_region.type)
|
||||
return &item->alg_region;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -1769,35 +1774,35 @@ static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp,
|
||||
int type, __be32 id,
|
||||
__be32 ver, __be32 base)
|
||||
{
|
||||
struct cs_dsp_alg_region *alg_region;
|
||||
struct cs_dsp_alg_region_list_item *item;
|
||||
|
||||
alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL);
|
||||
if (!alg_region)
|
||||
item = kzalloc(sizeof(*item), GFP_KERNEL);
|
||||
if (!item)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
alg_region->type = type;
|
||||
alg_region->alg = be32_to_cpu(id);
|
||||
alg_region->ver = be32_to_cpu(ver);
|
||||
alg_region->base = be32_to_cpu(base);
|
||||
item->alg_region.type = type;
|
||||
item->alg_region.alg = be32_to_cpu(id);
|
||||
item->alg_region.ver = be32_to_cpu(ver);
|
||||
item->alg_region.base = be32_to_cpu(base);
|
||||
|
||||
list_add_tail(&alg_region->list, &dsp->alg_regions);
|
||||
list_add_tail(&item->list, &dsp->alg_regions);
|
||||
|
||||
if (dsp->wmfw_ver > 0)
|
||||
cs_dsp_ctl_fixup_base(dsp, alg_region);
|
||||
cs_dsp_ctl_fixup_base(dsp, &item->alg_region);
|
||||
|
||||
return alg_region;
|
||||
return &item->alg_region;
|
||||
}
|
||||
|
||||
static void cs_dsp_free_alg_regions(struct cs_dsp *dsp)
|
||||
{
|
||||
struct cs_dsp_alg_region *alg_region;
|
||||
struct cs_dsp_alg_region_list_item *item;
|
||||
|
||||
while (!list_empty(&dsp->alg_regions)) {
|
||||
alg_region = list_first_entry(&dsp->alg_regions,
|
||||
struct cs_dsp_alg_region,
|
||||
list);
|
||||
list_del(&alg_region->list);
|
||||
kfree(alg_region);
|
||||
item = list_first_entry(&dsp->alg_regions,
|
||||
struct cs_dsp_alg_region_list_item,
|
||||
list);
|
||||
list_del(&item->list);
|
||||
kfree(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2303,6 +2303,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
|
||||
case BUS_I2C:
|
||||
bus = "I2C";
|
||||
break;
|
||||
case BUS_SDW:
|
||||
bus = "SOUNDWIRE";
|
||||
break;
|
||||
case BUS_VIRTUAL:
|
||||
bus = "VIRTUAL";
|
||||
break;
|
||||
|
||||
@@ -64,14 +64,12 @@ struct cs_dsp_region {
|
||||
|
||||
/**
|
||||
* struct cs_dsp_alg_region - Describes a logical algorithm region in DSP address space
|
||||
* @list: List node for internal use
|
||||
* @alg: Algorithm id
|
||||
* @ver: Expected algorithm version
|
||||
* @type: Memory region type
|
||||
* @base: Address of region
|
||||
*/
|
||||
struct cs_dsp_alg_region {
|
||||
struct list_head list;
|
||||
unsigned int alg;
|
||||
unsigned int ver;
|
||||
int type;
|
||||
|
||||
@@ -11,12 +11,20 @@
|
||||
#include <linux/scmi_imx_protocol.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define SCMI_IMX_CTRL_PDM_CLK_SEL 0 /* AON PDM clock sel */
|
||||
#define SCMI_IMX_CTRL_MQS1_SETTINGS 1 /* AON MQS settings */
|
||||
#define SCMI_IMX_CTRL_SAI1_MCLK 2 /* AON SAI1 MCLK */
|
||||
#define SCMI_IMX_CTRL_SAI3_MCLK 3 /* WAKE SAI3 MCLK */
|
||||
#define SCMI_IMX_CTRL_SAI4_MCLK 4 /* WAKE SAI4 MCLK */
|
||||
#define SCMI_IMX_CTRL_SAI5_MCLK 5 /* WAKE SAI5 MCLK */
|
||||
#define SCMI_IMX95_CTRL_PDM_CLK_SEL 0 /* AON PDM clock sel */
|
||||
#define SCMI_IMX95_CTRL_MQS1_SETTINGS 1 /* AON MQS settings */
|
||||
#define SCMI_IMX95_CTRL_SAI1_MCLK 2 /* AON SAI1 MCLK */
|
||||
#define SCMI_IMX95_CTRL_SAI3_MCLK 3 /* WAKE SAI3 MCLK */
|
||||
#define SCMI_IMX95_CTRL_SAI4_MCLK 4 /* WAKE SAI4 MCLK */
|
||||
#define SCMI_IMX95_CTRL_SAI5_MCLK 5 /* WAKE SAI5 MCLK */
|
||||
|
||||
#define SCMI_IMX94_CTRL_PDM_CLK_SEL 0U /*!< AON PDM clock sel */
|
||||
#define SCMI_IMX94_CTRL_MQS1_SETTINGS 1U /*!< AON MQS settings */
|
||||
#define SCMI_IMX94_CTRL_MQS2_SETTINGS 2U /*!< WAKE MQS settings */
|
||||
#define SCMI_IMX94_CTRL_SAI1_MCLK 3U /*!< AON SAI1 MCLK */
|
||||
#define SCMI_IMX94_CTRL_SAI2_MCLK 4U /*!< WAKE SAI2 MCLK */
|
||||
#define SCMI_IMX94_CTRL_SAI3_MCLK 5U /*!< WAKE SAI3 MCLK */
|
||||
#define SCMI_IMX94_CTRL_SAI4_MCLK 6U /*!< WAKE SAI4 MCLK */
|
||||
|
||||
int scmi_imx_misc_ctrl_get(u32 id, u32 *num, u32 *val);
|
||||
int scmi_imx_misc_ctrl_set(u32 id, u32 val);
|
||||
|
||||
@@ -609,6 +609,18 @@
|
||||
#define CS35L41_DSP_NG_DELAY_MASK 0x0F00
|
||||
#define CS35L41_DSP_NG_DELAY_SHIFT 8
|
||||
|
||||
#define CS35L41_ASP_RX1_EN_MASK 0x00010000
|
||||
#define CS35L41_ASP_RX1_EN_SHIFT 16
|
||||
#define CS35L41_ASP_RX2_EN_MASK 0x00020000
|
||||
#define CS35L41_ASP_RX2_EN_SHIFT 17
|
||||
#define CS35L41_ASP_TX1_EN_MASK 0x00000001
|
||||
#define CS35L41_ASP_TX1_EN_SHIFT 0
|
||||
#define CS35L41_ASP_TX2_EN_MASK 0x00000002
|
||||
#define CS35L41_ASP_TX2_EN_SHIFT 1
|
||||
#define CS35L41_ASP_TX3_EN_MASK 0x00000004
|
||||
#define CS35L41_ASP_TX3_EN_SHIFT 2
|
||||
#define CS35L41_ASP_TX4_EN_MASK 0x00000008
|
||||
#define CS35L41_ASP_TX4_EN_SHIFT 3
|
||||
#define CS35L41_ASP_FMT_MASK 0x0700
|
||||
#define CS35L41_ASP_FMT_SHIFT 8
|
||||
#define CS35L41_ASP_DOUT_HIZ_MASK 0x03
|
||||
|
||||
+22
-18
@@ -27,6 +27,7 @@ struct hda_beep;
|
||||
struct hda_codec;
|
||||
struct hda_pcm;
|
||||
struct hda_pcm_stream;
|
||||
struct hda_codec_ops;
|
||||
|
||||
/*
|
||||
* codec bus
|
||||
@@ -69,28 +70,31 @@ struct hda_bus {
|
||||
|
||||
/*
|
||||
* codec preset
|
||||
*
|
||||
* Known codecs have the patch to build and set up the controls/PCMs
|
||||
* better than the generic parser.
|
||||
*/
|
||||
typedef int (*hda_codec_patch_t)(struct hda_codec *);
|
||||
|
||||
|
||||
#define HDA_CODEC_ID_SKIP_PROBE 0x00000001
|
||||
#define HDA_CODEC_ID_GENERIC_HDMI 0x00000101
|
||||
#define HDA_CODEC_ID_GENERIC 0x00000201
|
||||
|
||||
#define HDA_CODEC_REV_ENTRY(_vid, _rev, _name, _patch) \
|
||||
#define HDA_CODEC_ID_REV_MODEL(_vid, _rev, _name, _model) \
|
||||
{ .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \
|
||||
.api_version = HDA_DEV_LEGACY, \
|
||||
.driver_data = (unsigned long)(_patch) }
|
||||
#define HDA_CODEC_ENTRY(_vid, _name, _patch) \
|
||||
HDA_CODEC_REV_ENTRY(_vid, 0, _name, _patch)
|
||||
.api_version = HDA_DEV_LEGACY, .driver_data = (_model) }
|
||||
#define HDA_CODEC_ID_MODEL(_vid, _name, _model) \
|
||||
HDA_CODEC_ID_REV_MODEL(_vid, 0, _name, _model)
|
||||
#define HDA_CODEC_ID_REV(_vid, _rev, _name) \
|
||||
HDA_CODEC_ID_REV_MODEL(_vid, _rev, _name, 0)
|
||||
#define HDA_CODEC_ID(_vid, _name) \
|
||||
HDA_CODEC_ID_REV(_vid, 0, _name)
|
||||
|
||||
struct hda_codec_driver {
|
||||
struct hdac_driver core;
|
||||
const struct hda_device_id *id;
|
||||
const struct hda_codec_ops *ops;
|
||||
};
|
||||
|
||||
#define hda_codec_to_driver(codec) \
|
||||
container_of((codec)->core.dev.driver, struct hda_codec_driver, core.driver)
|
||||
|
||||
int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
|
||||
struct module *owner);
|
||||
#define hda_codec_driver_register(drv) \
|
||||
@@ -100,12 +104,13 @@ void hda_codec_driver_unregister(struct hda_codec_driver *drv);
|
||||
module_driver(drv, hda_codec_driver_register, \
|
||||
hda_codec_driver_unregister)
|
||||
|
||||
/* ops set by the preset patch */
|
||||
/* ops for hda codec driver */
|
||||
struct hda_codec_ops {
|
||||
int (*probe)(struct hda_codec *codec, const struct hda_device_id *id);
|
||||
void (*remove)(struct hda_codec *codec);
|
||||
int (*build_controls)(struct hda_codec *codec);
|
||||
int (*build_pcms)(struct hda_codec *codec);
|
||||
int (*init)(struct hda_codec *codec);
|
||||
void (*free)(struct hda_codec *codec);
|
||||
void (*unsol_event)(struct hda_codec *codec, unsigned int res);
|
||||
void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
|
||||
unsigned int power_state);
|
||||
@@ -181,10 +186,7 @@ struct hda_codec {
|
||||
const struct hda_device_id *preset;
|
||||
const char *modelname; /* model name for preset */
|
||||
|
||||
/* set by patch */
|
||||
struct hda_codec_ops patch_ops;
|
||||
|
||||
/* PCM to create, set by patch_ops.build_pcms callback */
|
||||
/* PCM to create, set by hda_codec_ops.build_pcms callback */
|
||||
struct list_head pcm_list_head;
|
||||
refcount_t pcm_ref;
|
||||
wait_queue_head_t remove_sleep;
|
||||
@@ -478,8 +480,10 @@ extern const struct dev_pm_ops hda_codec_driver_pm;
|
||||
static inline
|
||||
int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid)
|
||||
{
|
||||
if (codec->patch_ops.check_power_status)
|
||||
return codec->patch_ops.check_power_status(codec, nid);
|
||||
struct hda_codec_driver *driver = hda_codec_to_driver(codec);
|
||||
|
||||
if (driver->ops && driver->ops->check_power_status)
|
||||
return driver->ops->check_power_status(codec, nid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -680,6 +680,30 @@ static inline void snd_hdac_dsp_cleanup(struct hdac_stream *azx_dev,
|
||||
}
|
||||
#endif /* CONFIG_SND_HDA_DSP_LOADER */
|
||||
|
||||
/*
|
||||
* Easy macros for widget capabilities
|
||||
*/
|
||||
#define snd_hdac_get_wcaps(codec, nid) \
|
||||
snd_hdac_read_parm(codec, nid, AC_PAR_AUDIO_WIDGET_CAP)
|
||||
|
||||
/* get the widget type from widget capability bits */
|
||||
static inline int snd_hdac_get_wcaps_type(unsigned int wcaps)
|
||||
{
|
||||
if (!wcaps)
|
||||
return -1; /* invalid type */
|
||||
return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
|
||||
}
|
||||
|
||||
/* get the number of supported channels */
|
||||
static inline unsigned int snd_hdac_get_wcaps_channels(u32 wcaps)
|
||||
{
|
||||
unsigned int chans;
|
||||
|
||||
chans = (wcaps & AC_WCAP_CHAN_CNT_EXT) >> 13;
|
||||
chans = (chans + 1) * 2;
|
||||
|
||||
return chans;
|
||||
}
|
||||
|
||||
/*
|
||||
* generic array helpers
|
||||
|
||||
@@ -11,9 +11,13 @@
|
||||
#define __SDCA_ASOC_H__
|
||||
|
||||
struct device;
|
||||
struct regmap;
|
||||
struct sdca_function_data;
|
||||
struct snd_kcontrol_new;
|
||||
struct snd_pcm_hw_params;
|
||||
struct snd_pcm_substream;
|
||||
struct snd_soc_component_driver;
|
||||
struct snd_soc_dai;
|
||||
struct snd_soc_dai_driver;
|
||||
struct snd_soc_dai_ops;
|
||||
struct snd_soc_dapm_route;
|
||||
@@ -39,4 +43,19 @@ int sdca_asoc_populate_component(struct device *dev,
|
||||
struct snd_soc_dai_driver **dai_drv, int *num_dai_drv,
|
||||
const struct snd_soc_dai_ops *ops);
|
||||
|
||||
int sdca_asoc_set_constraints(struct device *dev, struct regmap *regmap,
|
||||
struct sdca_function_data *function,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai);
|
||||
void sdca_asoc_free_constraints(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai);
|
||||
int sdca_asoc_get_port(struct device *dev, struct regmap *regmap,
|
||||
struct sdca_function_data *function,
|
||||
struct snd_soc_dai *dai);
|
||||
int sdca_asoc_hw_params(struct device *dev, struct regmap *regmap,
|
||||
struct sdca_function_data *function,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai);
|
||||
|
||||
#endif // __SDCA_ASOC_H__
|
||||
|
||||
@@ -11,11 +11,14 @@
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/hid.h>
|
||||
|
||||
struct device;
|
||||
struct sdca_entity;
|
||||
struct sdca_function_desc;
|
||||
|
||||
#define SDCA_NO_INTERRUPT -1
|
||||
|
||||
/*
|
||||
* The addressing space for SDCA relies on 7 bits for Entities, so a
|
||||
* maximum of 128 Entities per function can be represented.
|
||||
@@ -182,6 +185,14 @@ enum sdca_usage_range {
|
||||
SDCA_USAGE_NCOLS = 7,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sdca_dataport_selector_range - Column definitions for DataPort_Selector
|
||||
*/
|
||||
enum sdca_dataport_selector_range {
|
||||
SDCA_DATAPORT_SELECTOR_NCOLS = 16,
|
||||
SDCA_DATAPORT_SELECTOR_NROWS = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sdca_mu_controls - SDCA Controls for Mixer Unit
|
||||
*
|
||||
@@ -318,6 +329,15 @@ enum sdca_selected_mode_range {
|
||||
SDCA_SELECTED_MODE_NCOLS = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sdca_detected_mode_values - Predefined GE Detected Mode values
|
||||
*/
|
||||
enum sdca_detected_mode_values {
|
||||
SDCA_DETECTED_MODE_JACK_UNPLUGGED = 0,
|
||||
SDCA_DETECTED_MODE_JACK_UNKNOWN = 1,
|
||||
SDCA_DETECTED_MODE_DETECTION_IN_PROGRESS = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sdca_spe_controls - SDCA Controls for Security & Privacy Unit
|
||||
*
|
||||
@@ -1040,6 +1060,32 @@ struct sdca_entity_ge {
|
||||
int num_modes;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sdca_entity_hide - information specific to HIDE Entities
|
||||
* @hid: HID device structure
|
||||
* @hidtx_ids: HIDTx Report ID
|
||||
* @num_hidtx_ids: number of HIDTx Report ID
|
||||
* @hidrx_ids: HIDRx Report ID
|
||||
* @num_hidrx_ids: number of HIDRx Report ID
|
||||
* @hide_reside_function_num: indicating which Audio Function Numbers within this Device
|
||||
* @max_delay: the maximum time in microseconds allowed for the Device to change the ownership from Device to Host
|
||||
* @af_number_list: which Audio Function Numbers within this Device are sending/receiving the messages in this HIDE
|
||||
* @hid_desc: HID descriptor for the HIDE Entity
|
||||
* @hid_report_desc: HID Report Descriptor for the HIDE Entity
|
||||
*/
|
||||
struct sdca_entity_hide {
|
||||
struct hid_device *hid;
|
||||
unsigned int *hidtx_ids;
|
||||
int num_hidtx_ids;
|
||||
unsigned int *hidrx_ids;
|
||||
int num_hidrx_ids;
|
||||
unsigned int hide_reside_function_num;
|
||||
unsigned int max_delay;
|
||||
unsigned int af_number_list[SDCA_MAX_FUNCTION_COUNT];
|
||||
struct hid_descriptor hid_desc;
|
||||
unsigned char *hid_report_desc;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sdca_entity - information for one SDCA Entity
|
||||
* @label: String such as "OT 12".
|
||||
@@ -1055,6 +1101,7 @@ struct sdca_entity_ge {
|
||||
* @cs: Clock Source specific Entity properties.
|
||||
* @pde: Power Domain Entity specific Entity properties.
|
||||
* @ge: Group Entity specific Entity properties.
|
||||
* @hide: HIDE Entity specific Entity properties.
|
||||
*/
|
||||
struct sdca_entity {
|
||||
const char *label;
|
||||
@@ -1071,6 +1118,7 @@ struct sdca_entity {
|
||||
struct sdca_entity_cs cs;
|
||||
struct sdca_entity_pde pde;
|
||||
struct sdca_entity_ge ge;
|
||||
struct sdca_entity_hide hide;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1228,6 +1276,15 @@ struct sdca_cluster {
|
||||
struct sdca_channel *channels;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sdca_cluster_range - SDCA Range column definitions for ClusterIndex
|
||||
*/
|
||||
enum sdca_cluster_range {
|
||||
SDCA_CLUSTER_BYTEINDEX = 0,
|
||||
SDCA_CLUSTER_CLUSTERID = 1,
|
||||
SDCA_CLUSTER_NCOLS = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sdca_function_data - top-level information for one SDCA function
|
||||
* @desc: Pointer to short descriptor from initial parsing.
|
||||
@@ -1276,4 +1333,18 @@ int sdca_parse_function(struct device *dev,
|
||||
struct sdca_function_desc *desc,
|
||||
struct sdca_function_data *function);
|
||||
|
||||
struct sdca_control *sdca_selector_find_control(struct device *dev,
|
||||
struct sdca_entity *entity,
|
||||
const int sel);
|
||||
struct sdca_control_range *sdca_control_find_range(struct device *dev,
|
||||
struct sdca_entity *entity,
|
||||
struct sdca_control *control,
|
||||
int cols, int rows);
|
||||
struct sdca_control_range *sdca_selector_find_range(struct device *dev,
|
||||
struct sdca_entity *entity,
|
||||
int sel, int cols, int rows);
|
||||
struct sdca_cluster *sdca_id_find_cluster(struct device *dev,
|
||||
struct sdca_function_data *function,
|
||||
const int id);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
|
||||
/*
|
||||
* The MIPI SDCA specification is available for public downloads at
|
||||
* https://www.mipi.org/mipi-sdca-v1-0-download
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SDCA_HID_H__
|
||||
#define __SDCA_HID_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/hid.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_SDCA_HID)
|
||||
int sdca_add_hid_device(struct device *dev, struct sdca_entity *entity);
|
||||
|
||||
#else
|
||||
static inline int sdca_add_hid_device(struct device *dev, struct sdca_entity *entity)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __SDCA_HID_H__ */
|
||||
@@ -0,0 +1,78 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* The MIPI SDCA specification is available for public downloads at
|
||||
* https://www.mipi.org/mipi-sdca-v1-0-download
|
||||
*
|
||||
* Copyright (C) 2025 Cirrus Logic, Inc. and
|
||||
* Cirrus Logic International Semiconductor Ltd.
|
||||
*/
|
||||
|
||||
#ifndef __SDCA_INTERRUPTS_H__
|
||||
#define __SDCA_INTERRUPTS_H__
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
struct device;
|
||||
struct snd_soc_component;
|
||||
struct sdca_function_data;
|
||||
|
||||
#define SDCA_MAX_INTERRUPTS 31 /* the last bit is reserved for future extensions */
|
||||
|
||||
/**
|
||||
* struct sdca_interrupt - contains information about a single SDCA interrupt
|
||||
* @name: The name of the interrupt.
|
||||
* @component: Pointer to the ASoC component owns the interrupt.
|
||||
* @function: Pointer to the Function that the interrupt is associated with.
|
||||
* @entity: Pointer to the Entity that the interrupt is associated with.
|
||||
* @control: Pointer to the Control that the interrupt is associated with.
|
||||
* @priv: Pointer to private data for use by the handler.
|
||||
* @externally_requested: Internal flag used to check if a client driver has
|
||||
* already requested the interrupt, for custom handling, allowing the core to
|
||||
* skip handling this interrupt.
|
||||
*/
|
||||
struct sdca_interrupt {
|
||||
const char *name;
|
||||
|
||||
struct snd_soc_component *component;
|
||||
struct sdca_function_data *function;
|
||||
struct sdca_entity *entity;
|
||||
struct sdca_control *control;
|
||||
|
||||
void *priv;
|
||||
|
||||
bool externally_requested;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sdca_interrupt_info - contains top-level SDCA interrupt information
|
||||
* @irq_chip: regmap irq chip structure.
|
||||
* @irq_data: regmap irq chip data structure.
|
||||
* @irqs: Array of data for each individual IRQ.
|
||||
* @irq_lock: Protects access to the list of sdca_interrupt structures.
|
||||
*/
|
||||
struct sdca_interrupt_info {
|
||||
struct regmap_irq_chip irq_chip;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
|
||||
struct sdca_interrupt irqs[SDCA_MAX_INTERRUPTS];
|
||||
|
||||
struct mutex irq_lock; /* Protect irqs list across functions */
|
||||
};
|
||||
|
||||
int sdca_irq_request(struct device *dev, struct sdca_interrupt_info *interrupt_info,
|
||||
int sdca_irq, const char *name, irq_handler_t handler,
|
||||
void *data);
|
||||
int sdca_irq_data_populate(struct snd_soc_component *component,
|
||||
struct sdca_function_data *function,
|
||||
struct sdca_entity *entity,
|
||||
struct sdca_control *control,
|
||||
struct sdca_interrupt *interrupt);
|
||||
int sdca_irq_populate(struct sdca_function_data *function,
|
||||
struct snd_soc_component *component,
|
||||
struct sdca_interrupt_info *info);
|
||||
struct sdca_interrupt_info *sdca_irq_allocate(struct device *dev,
|
||||
struct regmap *regmap, int irq);
|
||||
|
||||
#endif
|
||||
@@ -206,7 +206,6 @@ struct snd_soc_component_driver {
|
||||
|
||||
struct snd_soc_component {
|
||||
const char *name;
|
||||
int id;
|
||||
const char *name_prefix;
|
||||
struct device *dev;
|
||||
struct snd_soc_card *card;
|
||||
|
||||
@@ -463,6 +463,9 @@ struct snd_soc_dai {
|
||||
|
||||
/* bit field */
|
||||
unsigned int probed:1;
|
||||
|
||||
/* DAI private data */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
static inline const struct snd_soc_pcm_stream *
|
||||
|
||||
+113
-123
@@ -16,9 +16,10 @@
|
||||
#include <sound/asoc.h>
|
||||
|
||||
struct device;
|
||||
struct regulator;
|
||||
struct soc_enum;
|
||||
struct snd_pcm_substream;
|
||||
struct snd_soc_pcm_runtime;
|
||||
struct soc_enum;
|
||||
|
||||
/* widget has no PM register bit */
|
||||
#define SND_SOC_NOPM -1
|
||||
@@ -294,7 +295,7 @@ struct soc_enum;
|
||||
#define SND_SOC_DAPM_CLOCK_SUPPLY(wname) \
|
||||
(struct snd_soc_dapm_widget) { \
|
||||
.id = snd_soc_dapm_clock_supply, .name = wname, \
|
||||
.reg = SND_SOC_NOPM, .event = dapm_clock_event, \
|
||||
.reg = SND_SOC_NOPM, .event = snd_soc_dapm_clock_event, \
|
||||
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
|
||||
|
||||
/* generic widgets */
|
||||
@@ -311,7 +312,7 @@ struct soc_enum;
|
||||
#define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay, wflags) \
|
||||
(struct snd_soc_dapm_widget) { \
|
||||
.id = snd_soc_dapm_regulator_supply, .name = wname, \
|
||||
.reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \
|
||||
.reg = SND_SOC_NOPM, .shift = wdelay, .event = snd_soc_dapm_regulator_event, \
|
||||
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \
|
||||
.on_val = wflags}
|
||||
#define SND_SOC_DAPM_PINCTRL(wname, active, sleep) \
|
||||
@@ -319,7 +320,7 @@ struct soc_enum;
|
||||
.id = snd_soc_dapm_pinctrl, .name = wname, \
|
||||
.priv = (&(struct snd_soc_dapm_pinctrl_priv) \
|
||||
{ .active_state = active, .sleep_state = sleep,}), \
|
||||
.reg = SND_SOC_NOPM, .event = dapm_pinctrl_event, \
|
||||
.reg = SND_SOC_NOPM, .event = snd_soc_dapm_pinctrl_event, \
|
||||
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
|
||||
|
||||
|
||||
@@ -399,17 +400,6 @@ struct soc_enum;
|
||||
/* regulator widget flags */
|
||||
#define SND_SOC_DAPM_REGULATOR_BYPASS 0x1 /* bypass when disabled */
|
||||
|
||||
struct snd_soc_dapm_widget;
|
||||
enum snd_soc_dapm_type;
|
||||
struct snd_soc_dapm_path;
|
||||
struct snd_soc_dapm_pin;
|
||||
struct snd_soc_dapm_route;
|
||||
struct snd_soc_dapm_context;
|
||||
struct regulator;
|
||||
struct snd_soc_dapm_widget_list;
|
||||
struct snd_soc_dapm_update;
|
||||
enum snd_soc_dapm_direction;
|
||||
|
||||
/*
|
||||
* Bias levels
|
||||
*
|
||||
@@ -428,98 +418,6 @@ enum snd_soc_bias_level {
|
||||
SND_SOC_BIAS_ON = 3,
|
||||
};
|
||||
|
||||
int dapm_regulator_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event);
|
||||
int dapm_clock_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event);
|
||||
int dapm_pinctrl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event);
|
||||
|
||||
/* dapm controls */
|
||||
int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *uncontrol);
|
||||
int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *uncontrol);
|
||||
int snd_soc_dapm_get_component_pin_switch(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *uncontrol);
|
||||
int snd_soc_dapm_put_component_pin_switch(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *uncontrol);
|
||||
int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_widget *widget, unsigned int num);
|
||||
struct snd_soc_dapm_widget *snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_widget *widget);
|
||||
struct snd_soc_dapm_widget *snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_widget *widget);
|
||||
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, struct snd_soc_dai *dai);
|
||||
void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w);
|
||||
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
|
||||
void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);
|
||||
|
||||
int snd_soc_dapm_update_dai(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai);
|
||||
int snd_soc_dapm_widget_name_cmp(struct snd_soc_dapm_widget *widget, const char *s);
|
||||
|
||||
/* dapm path setup */
|
||||
int snd_soc_dapm_new_widgets(struct snd_soc_card *card);
|
||||
void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
|
||||
void snd_soc_dapm_init(struct snd_soc_dapm_context *dapm,
|
||||
struct snd_soc_card *card, struct snd_soc_component *component);
|
||||
int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_route *route, int num);
|
||||
int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_route *route, int num);
|
||||
int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_route *route, int num);
|
||||
void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w);
|
||||
|
||||
/* dapm events */
|
||||
void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, int event);
|
||||
void snd_soc_dapm_stream_stop(struct snd_soc_pcm_runtime *rtd, int stream);
|
||||
void snd_soc_dapm_shutdown(struct snd_soc_card *card);
|
||||
|
||||
/* external DAPM widget events */
|
||||
int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
|
||||
struct snd_kcontrol *kcontrol, int connect, struct snd_soc_dapm_update *update);
|
||||
int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm,
|
||||
struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e,
|
||||
struct snd_soc_dapm_update *update);
|
||||
|
||||
/* dapm sys fs - used by the core */
|
||||
extern struct attribute *soc_dapm_dev_attrs[];
|
||||
void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, struct dentry *parent);
|
||||
|
||||
/* dapm audio pin control and status */
|
||||
int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_nc_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm);
|
||||
int snd_soc_dapm_sync_unlocked(struct snd_soc_dapm_context *dapm);
|
||||
int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol);
|
||||
void dapm_mark_endpoints_dirty(struct snd_soc_card *card);
|
||||
|
||||
/* dapm path query */
|
||||
int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
|
||||
struct snd_soc_dapm_widget_list **list,
|
||||
bool (*custom_stop_condition)(struct snd_soc_dapm_widget *, enum snd_soc_dapm_direction));
|
||||
void snd_soc_dapm_dai_free_widgets(struct snd_soc_dapm_widget_list **list);
|
||||
|
||||
struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(struct snd_kcontrol *kcontrol);
|
||||
struct snd_soc_dapm_widget *snd_soc_dapm_kcontrol_widget(struct snd_kcontrol *kcontrol);
|
||||
|
||||
int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level);
|
||||
|
||||
/* dapm widget types */
|
||||
enum snd_soc_dapm_type {
|
||||
snd_soc_dapm_input = 0, /* input pin */
|
||||
@@ -603,7 +501,6 @@ struct snd_soc_dapm_path {
|
||||
/* status */
|
||||
u32 connect:1; /* source and sink widgets are connected */
|
||||
u32 walking:1; /* path is in the process of being walked */
|
||||
u32 weak:1; /* path ignored for power management */
|
||||
u32 is_supply:1; /* At least one of the connected widgets is a supply */
|
||||
|
||||
int (*connected)(struct snd_soc_dapm_widget *source,
|
||||
@@ -712,11 +609,6 @@ struct snd_soc_dapm_widget_list {
|
||||
struct snd_soc_dapm_widget *widgets[] __counted_by(num_widgets);
|
||||
};
|
||||
|
||||
#define for_each_dapm_widgets(list, i, widget) \
|
||||
for ((i) = 0; \
|
||||
(i) < list->num_widgets && (widget = list->widgets[i]); \
|
||||
(i)++)
|
||||
|
||||
struct snd_soc_dapm_stats {
|
||||
int power_checks;
|
||||
int path_checks;
|
||||
@@ -728,6 +620,114 @@ struct snd_soc_dapm_pinctrl_priv {
|
||||
const char *sleep_state;
|
||||
};
|
||||
|
||||
enum snd_soc_dapm_direction {
|
||||
SND_SOC_DAPM_DIR_IN,
|
||||
SND_SOC_DAPM_DIR_OUT
|
||||
};
|
||||
|
||||
#define SND_SOC_DAPM_DIR_TO_EP(x) BIT(x)
|
||||
|
||||
#define SND_SOC_DAPM_EP_SOURCE SND_SOC_DAPM_DIR_TO_EP(SND_SOC_DAPM_DIR_IN)
|
||||
#define SND_SOC_DAPM_EP_SINK SND_SOC_DAPM_DIR_TO_EP(SND_SOC_DAPM_DIR_OUT)
|
||||
|
||||
int snd_soc_dapm_regulator_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event);
|
||||
int snd_soc_dapm_clock_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event);
|
||||
int snd_soc_dapm_pinctrl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event);
|
||||
|
||||
/* dapm controls */
|
||||
int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
|
||||
int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *uncontrol);
|
||||
int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *uncontrol);
|
||||
int snd_soc_dapm_get_component_pin_switch(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *uncontrol);
|
||||
int snd_soc_dapm_put_component_pin_switch(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *uncontrol);
|
||||
int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_widget *widget, unsigned int num);
|
||||
struct snd_soc_dapm_widget *snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_widget *widget);
|
||||
struct snd_soc_dapm_widget *snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_widget *widget);
|
||||
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, struct snd_soc_dai *dai);
|
||||
void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w);
|
||||
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
|
||||
void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);
|
||||
|
||||
int snd_soc_dapm_update_dai(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai);
|
||||
int snd_soc_dapm_widget_name_cmp(struct snd_soc_dapm_widget *widget, const char *s);
|
||||
|
||||
/* dapm path setup */
|
||||
int snd_soc_dapm_new_widgets(struct snd_soc_card *card);
|
||||
void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm);
|
||||
void snd_soc_dapm_init(struct snd_soc_dapm_context *dapm,
|
||||
struct snd_soc_card *card, struct snd_soc_component *component);
|
||||
int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_route *route, int num);
|
||||
int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
|
||||
const struct snd_soc_dapm_route *route, int num);
|
||||
void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w);
|
||||
|
||||
/* dapm events */
|
||||
void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, int event);
|
||||
void snd_soc_dapm_stream_stop(struct snd_soc_pcm_runtime *rtd, int stream);
|
||||
void snd_soc_dapm_shutdown(struct snd_soc_card *card);
|
||||
|
||||
/* external DAPM widget events */
|
||||
int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
|
||||
struct snd_kcontrol *kcontrol, int connect, struct snd_soc_dapm_update *update);
|
||||
int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm,
|
||||
struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e,
|
||||
struct snd_soc_dapm_update *update);
|
||||
|
||||
/* dapm sys fs - used by the core */
|
||||
extern struct attribute *snd_soc_dapm_dev_attrs[];
|
||||
void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, struct dentry *parent);
|
||||
|
||||
/* dapm audio pin control and status */
|
||||
int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_disable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm);
|
||||
int snd_soc_dapm_sync_unlocked(struct snd_soc_dapm_context *dapm);
|
||||
int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_force_enable_pin_unlocked(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, const char *pin);
|
||||
unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol);
|
||||
void snd_soc_dapm_mark_endpoints_dirty(struct snd_soc_card *card);
|
||||
|
||||
/*
|
||||
* Marks the specified pin as being not connected, disabling it along
|
||||
* any parent or child widgets. At present this is identical to
|
||||
* snd_soc_dapm_disable_pin[_unlocked]() but in future it will be extended to do
|
||||
* additional things such as disabling controls which only affect
|
||||
* paths through the pin.
|
||||
*/
|
||||
#define snd_soc_dapm_nc_pin snd_soc_dapm_disable_pin
|
||||
#define snd_soc_dapm_nc_pin_unlocked snd_soc_dapm_disable_pin_unlocked
|
||||
|
||||
/* dapm path query */
|
||||
int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
|
||||
struct snd_soc_dapm_widget_list **list,
|
||||
bool (*custom_stop_condition)(struct snd_soc_dapm_widget *, enum snd_soc_dapm_direction));
|
||||
void snd_soc_dapm_dai_free_widgets(struct snd_soc_dapm_widget_list **list);
|
||||
|
||||
struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(struct snd_kcontrol *kcontrol);
|
||||
struct snd_soc_dapm_widget *snd_soc_dapm_kcontrol_widget(struct snd_kcontrol *kcontrol);
|
||||
|
||||
int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level);
|
||||
|
||||
#define for_each_dapm_widgets(list, i, widget) \
|
||||
for ((i) = 0; \
|
||||
(i) < list->num_widgets && (widget = list->widgets[i]); \
|
||||
(i)++)
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_init_bias_level() - Initialize DAPM bias level
|
||||
* @dapm: The DAPM context to initialize
|
||||
@@ -759,16 +759,6 @@ static inline enum snd_soc_bias_level snd_soc_dapm_get_bias_level(
|
||||
return dapm->bias_level;
|
||||
}
|
||||
|
||||
enum snd_soc_dapm_direction {
|
||||
SND_SOC_DAPM_DIR_IN,
|
||||
SND_SOC_DAPM_DIR_OUT
|
||||
};
|
||||
|
||||
#define SND_SOC_DAPM_DIR_TO_EP(x) BIT(x)
|
||||
|
||||
#define SND_SOC_DAPM_EP_SOURCE SND_SOC_DAPM_DIR_TO_EP(SND_SOC_DAPM_DIR_IN)
|
||||
#define SND_SOC_DAPM_EP_SINK SND_SOC_DAPM_DIR_TO_EP(SND_SOC_DAPM_DIR_OUT)
|
||||
|
||||
/**
|
||||
* snd_soc_dapm_widget_for_each_path - Iterates over all paths in the
|
||||
* specified direction of a widget
|
||||
|
||||
@@ -46,6 +46,7 @@ struct asoc_sdw_codec_info;
|
||||
struct asoc_sdw_dai_info {
|
||||
const bool direction[2]; /* playback & capture support */
|
||||
const char *dai_name;
|
||||
const char *component_name;
|
||||
const int dai_type;
|
||||
const int dailink[2]; /* dailink id for each direction */
|
||||
const struct snd_kcontrol_new *controls;
|
||||
|
||||
@@ -498,6 +498,8 @@ struct sof_ipc4_intel_mic_privacy_cap {
|
||||
#define SOF_IPC4_LOG_CORE_GET(x) (((x) & SOF_IPC4_LOG_CORE_MASK) >> \
|
||||
SOF_IPC4_LOG_CORE_SHIFT)
|
||||
|
||||
#define SOF_IPC4_FW_READY_LIB_RESTORED BIT(15)
|
||||
|
||||
/* Value of notification type field - must fit into 8 bits */
|
||||
enum sof_ipc4_notification_type {
|
||||
/* Phrase detected (notification from WoV module) */
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
//
|
||||
// ALSA SoC Texas Instruments TAS2770 Audio Smart Amplifier
|
||||
//
|
||||
// Copyright (C) 2025 Texas Instruments Incorporated
|
||||
// https://www.ti.com
|
||||
//
|
||||
// The TAS2770 hda driver implements for one, two, or even multiple
|
||||
// TAS2770 chips.
|
||||
//
|
||||
// Author: Baojun Xu <baojun.xu@ti.com>
|
||||
//
|
||||
|
||||
#ifndef __TAS2770_TLV_H__
|
||||
#define __TAS2770_TLV_H__
|
||||
|
||||
#define TAS2770_DVC_LEVEL TASDEVICE_REG(0x0, 0x0, 0x17)
|
||||
#define TAS2770_AMP_LEVEL TASDEVICE_REG(0x0, 0x0, 0x03)
|
||||
|
||||
static const __maybe_unused DECLARE_TLV_DB_SCALE(tas2770_dvc_tlv, 1650, 50, 0);
|
||||
static const __maybe_unused DECLARE_TLV_DB_SCALE(tas2770_amp_tlv, 1100, 50, 0);
|
||||
|
||||
#endif
|
||||
@@ -17,6 +17,10 @@
|
||||
#ifndef __TAS2781_H__
|
||||
#define __TAS2781_H__
|
||||
|
||||
#ifdef CONFIG_SND_SOC_TAS2781_ACOUST_I2C
|
||||
#include <linux/debugfs.h>
|
||||
#endif
|
||||
|
||||
#include "tas2781-dsp.h"
|
||||
|
||||
/* version number */
|
||||
|
||||
@@ -40,13 +40,4 @@
|
||||
struct aic32x4_setup_data {
|
||||
unsigned int gpio_func[5];
|
||||
};
|
||||
|
||||
struct aic32x4_pdata {
|
||||
struct aic32x4_setup_data *setup;
|
||||
u32 power_cfg;
|
||||
u32 micpga_routing;
|
||||
bool swapdacs;
|
||||
int rstn_gpio;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -275,6 +275,7 @@ struct input_mask {
|
||||
#define BUS_CEC 0x1E
|
||||
#define BUS_INTEL_ISHTP 0x1F
|
||||
#define BUS_AMD_SFH 0x20
|
||||
#define BUS_SDW 0x21
|
||||
|
||||
/*
|
||||
* MT_TOOL types
|
||||
|
||||
@@ -1435,7 +1435,7 @@ static int snd_ctl_elem_user_enum_info(struct snd_kcontrol *kcontrol,
|
||||
names = ue->priv_data;
|
||||
for (; item > 0; --item)
|
||||
names += strlen(names) + 1;
|
||||
strcpy(uinfo->value.enumerated.name, names);
|
||||
strscpy(uinfo->value.enumerated.name, names);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/hrtimer.h>
|
||||
@@ -138,7 +139,7 @@ static int __init snd_hrtimer_init(void)
|
||||
return err;
|
||||
|
||||
timer->module = THIS_MODULE;
|
||||
strcpy(timer->name, "HR timer");
|
||||
strscpy(timer->name, "HR timer");
|
||||
timer->hw = hrtimer_hw;
|
||||
timer->hw.resolution = resolution;
|
||||
timer->hw.ticks = NANO_SEC / resolution;
|
||||
|
||||
+7
-9
@@ -723,27 +723,25 @@ static void snd_card_set_id_no_lock(struct snd_card *card, const char *src,
|
||||
* ("card" conflicts with proc directories)
|
||||
*/
|
||||
if (!*id || !strncmp(id, "card", 4)) {
|
||||
strcpy(id, "Default");
|
||||
strscpy(card->id, "Default");
|
||||
is_default = true;
|
||||
}
|
||||
|
||||
len = strlen(id);
|
||||
for (loops = 0; loops < SNDRV_CARDS; loops++) {
|
||||
char *spos;
|
||||
char sfxstr[5]; /* "_012" */
|
||||
int sfxlen;
|
||||
int sfxlen, slen;
|
||||
|
||||
if (card_id_ok(card, id))
|
||||
return; /* OK */
|
||||
|
||||
/* Add _XYZ suffix */
|
||||
sprintf(sfxstr, "_%X", loops + 1);
|
||||
sfxlen = strlen(sfxstr);
|
||||
sfxlen = scnprintf(sfxstr, sizeof(sfxstr), "_%X", loops + 1);
|
||||
if (len + sfxlen >= sizeof(card->id))
|
||||
spos = id + sizeof(card->id) - sfxlen - 1;
|
||||
slen = sizeof(card->id) - sfxlen - 1;
|
||||
else
|
||||
spos = id + len;
|
||||
strcpy(spos, sfxstr);
|
||||
slen = len;
|
||||
strscpy(id + slen, sfxstr, sizeof(card->id) - slen);
|
||||
}
|
||||
/* fallback to the default id */
|
||||
if (!is_default) {
|
||||
@@ -801,7 +799,7 @@ static ssize_t id_store(struct device *dev, struct device_attribute *attr,
|
||||
guard(mutex)(&snd_card_mutex);
|
||||
if (!card_id_ok(NULL, buf1))
|
||||
return -EEXIST;
|
||||
strcpy(card->id, buf1);
|
||||
strscpy(card->id, buf1);
|
||||
snd_info_card_id_change(card);
|
||||
|
||||
return count;
|
||||
|
||||
@@ -991,7 +991,7 @@ static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer,
|
||||
struct slot *pslot;
|
||||
struct snd_kcontrol *kctl;
|
||||
struct snd_mixer_oss_slot *rslot;
|
||||
char str[64];
|
||||
const char *str;
|
||||
|
||||
/* check if already assigned */
|
||||
if (mixer->slots[ptr->oss_id].get_volume && ! replace_old)
|
||||
@@ -1014,11 +1014,11 @@ static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer,
|
||||
|
||||
if (kctl->info(kctl, uinfo))
|
||||
return 0;
|
||||
strcpy(str, ptr->name);
|
||||
str = ptr->name;
|
||||
if (!strcmp(str, "Master"))
|
||||
strcpy(str, "Mix");
|
||||
if (!strcmp(str, "Master Mono"))
|
||||
strcpy(str, "Mix Mono");
|
||||
str = "Mix";
|
||||
else if (!strcmp(str, "Master Mono"))
|
||||
str = "Mix Mono";
|
||||
slot.capture_item = 0;
|
||||
if (!strcmp(uinfo->value.enumerated.name, str)) {
|
||||
slot.present |= SNDRV_MIXER_OSS_PRESENT_CAPTURE;
|
||||
|
||||
+4
-16
@@ -377,12 +377,10 @@ struct snd_pcm_mmap_status_x32 {
|
||||
s32 pad1;
|
||||
u32 hw_ptr;
|
||||
u32 pad2; /* alignment */
|
||||
s64 tstamp_sec;
|
||||
s64 tstamp_nsec;
|
||||
struct __snd_timespec64 tstamp;
|
||||
snd_pcm_state_t suspended_state;
|
||||
s32 pad3;
|
||||
s64 audio_tstamp_sec;
|
||||
s64 audio_tstamp_nsec;
|
||||
struct __snd_timespec64 audio_tstamp;
|
||||
} __packed;
|
||||
|
||||
struct snd_pcm_mmap_control_x32 {
|
||||
@@ -418,9 +416,7 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
|
||||
if (snd_BUG_ON(!runtime))
|
||||
return -EINVAL;
|
||||
|
||||
if (get_user(sflags, &src->flags) ||
|
||||
get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
|
||||
get_user(scontrol.avail_min, &src->c.control.avail_min))
|
||||
if (snd_pcm_sync_ptr_get_user(sflags, scontrol, src))
|
||||
return -EFAULT;
|
||||
if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
|
||||
err = snd_pcm_hwsync(substream);
|
||||
@@ -450,15 +446,7 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
|
||||
}
|
||||
if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
if (put_user(sstatus.state, &src->s.status.state) ||
|
||||
put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
|
||||
put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp_sec) ||
|
||||
put_user(sstatus.tstamp.tv_nsec, &src->s.status.tstamp_nsec) ||
|
||||
put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
|
||||
put_user(sstatus.audio_tstamp.tv_sec, &src->s.status.audio_tstamp_sec) ||
|
||||
put_user(sstatus.audio_tstamp.tv_nsec, &src->s.status.audio_tstamp_nsec) ||
|
||||
put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
|
||||
put_user(scontrol.avail_min, &src->c.control.avail_min))
|
||||
if (snd_pcm_sync_ptr_put_user(sstatus, scontrol, src))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
||||
+77
-40
@@ -24,6 +24,7 @@
|
||||
#include <sound/minors.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include "pcm_local.h"
|
||||
|
||||
@@ -3051,49 +3052,87 @@ static inline int snd_pcm_hwsync(struct snd_pcm_substream *substream)
|
||||
return snd_pcm_delay(substream, NULL);
|
||||
}
|
||||
|
||||
#define snd_pcm_sync_ptr_get_user(__f, __c, __ptr) ({ \
|
||||
__label__ failed, failed_begin; \
|
||||
int __err = -EFAULT; \
|
||||
typeof(*(__ptr)) __user *__src = (__ptr); \
|
||||
\
|
||||
if (!user_read_access_begin(__src, sizeof(*__src))) \
|
||||
goto failed_begin; \
|
||||
unsafe_get_user(__f, &__src->flags, failed); \
|
||||
unsafe_get_user(__c.appl_ptr, &__src->c.control.appl_ptr, failed); \
|
||||
unsafe_get_user(__c.avail_min, &__src->c.control.avail_min, failed); \
|
||||
__err = 0; \
|
||||
failed: \
|
||||
user_read_access_end(); \
|
||||
failed_begin: \
|
||||
__err; \
|
||||
})
|
||||
|
||||
#define snd_pcm_sync_ptr_put_user(__s, __c, __ptr) ({ \
|
||||
__label__ failed, failed_begin; \
|
||||
int __err = -EFAULT; \
|
||||
typeof(*(__ptr)) __user *__src = (__ptr); \
|
||||
\
|
||||
if (!user_write_access_begin(__src, sizeof(*__src))) \
|
||||
goto failed_begin; \
|
||||
unsafe_put_user(__s.state, &__src->s.status.state, failed); \
|
||||
unsafe_put_user(__s.hw_ptr, &__src->s.status.hw_ptr, failed); \
|
||||
unsafe_put_user(__s.tstamp.tv_sec, &__src->s.status.tstamp.tv_sec, failed); \
|
||||
unsafe_put_user(__s.tstamp.tv_nsec, &__src->s.status.tstamp.tv_nsec, failed); \
|
||||
unsafe_put_user(__s.suspended_state, &__src->s.status.suspended_state, failed); \
|
||||
unsafe_put_user(__s.audio_tstamp.tv_sec, &__src->s.status.audio_tstamp.tv_sec, failed); \
|
||||
unsafe_put_user(__s.audio_tstamp.tv_nsec, &__src->s.status.audio_tstamp.tv_nsec, failed);\
|
||||
unsafe_put_user(__c.appl_ptr, &__src->c.control.appl_ptr, failed); \
|
||||
unsafe_put_user(__c.avail_min, &__src->c.control.avail_min, failed); \
|
||||
__err = 0; \
|
||||
failed: \
|
||||
user_write_access_end(); \
|
||||
failed_begin: \
|
||||
__err; \
|
||||
})
|
||||
|
||||
static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_sync_ptr __user *_sync_ptr)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct snd_pcm_sync_ptr sync_ptr;
|
||||
volatile struct snd_pcm_mmap_status *status;
|
||||
volatile struct snd_pcm_mmap_control *control;
|
||||
u32 sflags;
|
||||
struct snd_pcm_mmap_control scontrol;
|
||||
struct snd_pcm_mmap_status sstatus;
|
||||
int err;
|
||||
|
||||
memset(&sync_ptr, 0, sizeof(sync_ptr));
|
||||
if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
|
||||
if (snd_pcm_sync_ptr_get_user(sflags, scontrol, _sync_ptr))
|
||||
return -EFAULT;
|
||||
if (copy_from_user(&sync_ptr.c.control, &(_sync_ptr->c.control), sizeof(struct snd_pcm_mmap_control)))
|
||||
return -EFAULT;
|
||||
status = runtime->status;
|
||||
control = runtime->control;
|
||||
if (sync_ptr.flags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
|
||||
if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
|
||||
err = snd_pcm_hwsync(substream);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
scoped_guard(pcm_stream_lock_irq, substream) {
|
||||
if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL)) {
|
||||
err = pcm_lib_apply_appl_ptr(substream,
|
||||
sync_ptr.c.control.appl_ptr);
|
||||
if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL)) {
|
||||
err = pcm_lib_apply_appl_ptr(substream, scontrol.appl_ptr);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else {
|
||||
sync_ptr.c.control.appl_ptr = control->appl_ptr;
|
||||
scontrol.appl_ptr = control->appl_ptr;
|
||||
}
|
||||
if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
|
||||
control->avail_min = sync_ptr.c.control.avail_min;
|
||||
if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
|
||||
control->avail_min = scontrol.avail_min;
|
||||
else
|
||||
sync_ptr.c.control.avail_min = control->avail_min;
|
||||
sync_ptr.s.status.state = status->state;
|
||||
sync_ptr.s.status.hw_ptr = status->hw_ptr;
|
||||
sync_ptr.s.status.tstamp = status->tstamp;
|
||||
sync_ptr.s.status.suspended_state = status->suspended_state;
|
||||
sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
|
||||
scontrol.avail_min = control->avail_min;
|
||||
sstatus.state = status->state;
|
||||
sstatus.hw_ptr = status->hw_ptr;
|
||||
sstatus.tstamp = status->tstamp;
|
||||
sstatus.suspended_state = status->suspended_state;
|
||||
sstatus.audio_tstamp = status->audio_tstamp;
|
||||
}
|
||||
if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL))
|
||||
if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
|
||||
if (snd_pcm_sync_ptr_put_user(sstatus, scontrol, _sync_ptr))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
@@ -3102,11 +3141,9 @@ struct snd_pcm_mmap_status32 {
|
||||
snd_pcm_state_t state;
|
||||
s32 pad1;
|
||||
u32 hw_ptr;
|
||||
s32 tstamp_sec;
|
||||
s32 tstamp_nsec;
|
||||
struct __snd_timespec tstamp;
|
||||
snd_pcm_state_t suspended_state;
|
||||
s32 audio_tstamp_sec;
|
||||
s32 audio_tstamp_nsec;
|
||||
struct __snd_timespec audio_tstamp;
|
||||
} __packed;
|
||||
|
||||
struct snd_pcm_mmap_control32 {
|
||||
@@ -3130,13 +3167,23 @@ struct snd_pcm_sync_ptr32 {
|
||||
static snd_pcm_uframes_t recalculate_boundary(struct snd_pcm_runtime *runtime)
|
||||
{
|
||||
snd_pcm_uframes_t boundary;
|
||||
snd_pcm_uframes_t border;
|
||||
int order;
|
||||
|
||||
if (! runtime->buffer_size)
|
||||
return 0;
|
||||
boundary = runtime->buffer_size;
|
||||
while (boundary * 2 <= 0x7fffffffUL - runtime->buffer_size)
|
||||
boundary *= 2;
|
||||
return boundary;
|
||||
|
||||
border = 0x7fffffffUL - runtime->buffer_size;
|
||||
if (runtime->buffer_size > border)
|
||||
return runtime->buffer_size;
|
||||
|
||||
order = __fls(border) - __fls(runtime->buffer_size);
|
||||
boundary = runtime->buffer_size << order;
|
||||
|
||||
if (boundary <= border)
|
||||
return boundary;
|
||||
else
|
||||
return boundary / 2;
|
||||
}
|
||||
|
||||
static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
|
||||
@@ -3154,9 +3201,7 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
|
||||
if (snd_BUG_ON(!runtime))
|
||||
return -EINVAL;
|
||||
|
||||
if (get_user(sflags, &src->flags) ||
|
||||
get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
|
||||
get_user(scontrol.avail_min, &src->c.control.avail_min))
|
||||
if (snd_pcm_sync_ptr_get_user(sflags, scontrol, src))
|
||||
return -EFAULT;
|
||||
if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
|
||||
err = snd_pcm_hwsync(substream);
|
||||
@@ -3189,15 +3234,7 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
|
||||
}
|
||||
if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
if (put_user(sstatus.state, &src->s.status.state) ||
|
||||
put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
|
||||
put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp_sec) ||
|
||||
put_user(sstatus.tstamp.tv_nsec, &src->s.status.tstamp_nsec) ||
|
||||
put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
|
||||
put_user(sstatus.audio_tstamp.tv_sec, &src->s.status.audio_tstamp_sec) ||
|
||||
put_user(sstatus.audio_tstamp.tv_nsec, &src->s.status.audio_tstamp_nsec) ||
|
||||
put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
|
||||
put_user(scontrol.avail_min, &src->c.control.avail_min))
|
||||
if (snd_pcm_sync_ptr_put_user(sstatus, scontrol, src))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -631,9 +631,9 @@ static int snd_rawmidi_info(struct snd_rawmidi_substream *substream,
|
||||
info->flags = rmidi->info_flags;
|
||||
if (substream->inactive)
|
||||
info->flags |= SNDRV_RAWMIDI_INFO_STREAM_INACTIVE;
|
||||
strcpy(info->id, rmidi->id);
|
||||
strcpy(info->name, rmidi->name);
|
||||
strcpy(info->subname, substream->name);
|
||||
strscpy(info->id, rmidi->id);
|
||||
strscpy(info->name, rmidi->name);
|
||||
strscpy(info->subname, substream->name);
|
||||
info->subdevices_count = substream->pstr->substream_count;
|
||||
info->subdevices_avail = (substream->pstr->substream_count -
|
||||
substream->pstr->substream_opened);
|
||||
|
||||
@@ -79,7 +79,7 @@ snd_seq_oss_create_client(void)
|
||||
system_client = rc;
|
||||
|
||||
/* create announcement receiver port */
|
||||
strcpy(port->name, "Receiver");
|
||||
strscpy(port->name, "Receiver");
|
||||
port->addr.client = system_client;
|
||||
port->capability = SNDRV_SEQ_PORT_CAP_WRITE; /* receive only */
|
||||
port->type = 0;
|
||||
@@ -347,7 +347,7 @@ alloc_seq_queue(struct seq_oss_devinfo *dp)
|
||||
memset(&qinfo, 0, sizeof(qinfo));
|
||||
qinfo.owner = system_client;
|
||||
qinfo.locked = 1;
|
||||
strcpy(qinfo.name, "OSS Sequencer Emulation");
|
||||
strscpy(qinfo.name, "OSS Sequencer Emulation");
|
||||
rc = call_ctl(SNDRV_SEQ_IOCTL_CREATE_QUEUE, &qinfo);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
@@ -1256,7 +1256,7 @@ static void get_client_info(struct snd_seq_client *cptr,
|
||||
|
||||
/* fill the info fields */
|
||||
info->type = cptr->type;
|
||||
strcpy(info->name, cptr->name);
|
||||
strscpy(info->name, cptr->name);
|
||||
info->filter = cptr->filter;
|
||||
info->event_lost = cptr->event_lost;
|
||||
memcpy(info->event_filter, cptr->event_filter, 32);
|
||||
|
||||
@@ -344,7 +344,7 @@ snd_seq_midisynth_probe(struct device *_dev)
|
||||
info->stream = SNDRV_RAWMIDI_STREAM_INPUT;
|
||||
info->subdevice = p;
|
||||
if (snd_rawmidi_info_select(card, info) >= 0)
|
||||
strcpy(port->name, info->subname);
|
||||
strscpy(port->name, info->subname);
|
||||
if (! port->name[0]) {
|
||||
if (info->name[0]) {
|
||||
if (ports > 1)
|
||||
|
||||
@@ -146,7 +146,7 @@ int __init snd_seq_system_client_init(void)
|
||||
}
|
||||
|
||||
/* register timer */
|
||||
strcpy(port->name, "Timer");
|
||||
strscpy(port->name, "Timer");
|
||||
port->capability = SNDRV_SEQ_PORT_CAP_WRITE; /* accept queue control */
|
||||
port->capability |= SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ; /* for broadcast */
|
||||
port->kernel = &pcallbacks;
|
||||
@@ -160,7 +160,7 @@ int __init snd_seq_system_client_init(void)
|
||||
goto error_port;
|
||||
|
||||
/* register announcement port */
|
||||
strcpy(port->name, "Announce");
|
||||
strscpy(port->name, "Announce");
|
||||
port->capability = SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ; /* for broadcast only */
|
||||
pcallbacks.event_input = NULL;
|
||||
pcallbacks.subscribe = sys_announce_subscribe;
|
||||
|
||||
@@ -310,7 +310,7 @@ static int create_ump_endpoint_port(struct seq_ump_client *client)
|
||||
SNDRV_SEQ_PORT_TYPE_HARDWARE |
|
||||
SNDRV_SEQ_PORT_TYPE_PORT;
|
||||
port->midi_channels = 16;
|
||||
strcpy(port->name, "MIDI 2.0");
|
||||
strscpy(port->name, "MIDI 2.0");
|
||||
memset(&pcallbacks, 0, sizeof(pcallbacks));
|
||||
pcallbacks.owner = THIS_MODULE;
|
||||
pcallbacks.private_data = client;
|
||||
|
||||
@@ -497,7 +497,7 @@ int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmi
|
||||
&rmidi);
|
||||
if (err < 0)
|
||||
return err;
|
||||
strcpy(rmidi->name, rmidi->id);
|
||||
strscpy(rmidi->name, rmidi->id);
|
||||
rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
|
||||
if (rdev == NULL) {
|
||||
snd_device_free(card, rmidi);
|
||||
|
||||
+1
-1
@@ -1195,7 +1195,7 @@ static int snd_timer_register_system(void)
|
||||
err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer);
|
||||
if (err < 0)
|
||||
return err;
|
||||
strcpy(timer->name, "system timer");
|
||||
strscpy(timer->name, "system timer");
|
||||
timer->hw = snd_timer_system;
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (priv == NULL) {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/module.h>
|
||||
@@ -1368,7 +1369,7 @@ static int loopback_pcm_new(struct loopback *loopback,
|
||||
|
||||
pcm->private_data = loopback;
|
||||
pcm->info_flags = 0;
|
||||
strcpy(pcm->name, "Loopback PCM");
|
||||
strscpy(pcm->name, "Loopback PCM");
|
||||
|
||||
loopback->pcm[device] = pcm;
|
||||
return 0;
|
||||
@@ -1631,7 +1632,7 @@ static int loopback_mixer_new(struct loopback *loopback, int notify)
|
||||
struct loopback_setup *setup;
|
||||
int err, dev, substr, substr_count, idx;
|
||||
|
||||
strcpy(card->mixername, "Loopback Mixer");
|
||||
strscpy(card->mixername, "Loopback Mixer");
|
||||
for (dev = 0; dev < 2; dev++) {
|
||||
pcm = loopback->pcm[dev];
|
||||
substr_count =
|
||||
@@ -1824,8 +1825,8 @@ static int loopback_probe(struct platform_device *devptr)
|
||||
loopback_cable_proc_new(loopback, 0);
|
||||
loopback_cable_proc_new(loopback, 1);
|
||||
loopback_timer_source_proc_new(loopback);
|
||||
strcpy(card->driver, "Loopback");
|
||||
strcpy(card->shortname, "Loopback");
|
||||
strscpy(card->driver, "Loopback");
|
||||
strscpy(card->shortname, "Loopback");
|
||||
sprintf(card->longname, "Loopback %i", dev + 1);
|
||||
err = snd_card_register(card);
|
||||
if (err < 0)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/hrtimer.h>
|
||||
@@ -684,7 +685,7 @@ static int snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, ops);
|
||||
pcm->private_data = dummy;
|
||||
pcm->info_flags = 0;
|
||||
strcpy(pcm->name, "Dummy PCM");
|
||||
strscpy(pcm->name, "Dummy PCM");
|
||||
if (!fake_buffer) {
|
||||
snd_pcm_set_managed_buffer_all(pcm,
|
||||
SNDRV_DMA_TYPE_CONTINUOUS,
|
||||
@@ -875,7 +876,7 @@ static int snd_card_dummy_new_mixer(struct snd_dummy *dummy)
|
||||
int err;
|
||||
|
||||
spin_lock_init(&dummy->mixer_lock);
|
||||
strcpy(card->mixername, "Dummy Mixer");
|
||||
strscpy(card->mixername, "Dummy Mixer");
|
||||
dummy->iobox = 1;
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) {
|
||||
@@ -1083,8 +1084,8 @@ static int snd_dummy_probe(struct platform_device *devptr)
|
||||
err = snd_card_dummy_new_mixer(dummy);
|
||||
if (err < 0)
|
||||
return err;
|
||||
strcpy(card->driver, "Dummy");
|
||||
strcpy(card->shortname, "Dummy");
|
||||
strscpy(card->driver, "Dummy");
|
||||
strscpy(card->shortname, "Dummy");
|
||||
sprintf(card->longname, "Dummy %i", dev + 1);
|
||||
|
||||
dummy_proc_init(dummy);
|
||||
|
||||
@@ -63,8 +63,8 @@ static int snd_mpu401_create(struct device *devptr, int dev,
|
||||
0, &card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
strcpy(card->driver, "MPU-401 UART");
|
||||
strcpy(card->shortname, card->driver);
|
||||
strscpy(card->driver, "MPU-401 UART");
|
||||
strscpy(card->shortname, card->driver);
|
||||
sprintf(card->longname, "%s at %#lx, ", card->shortname, port[dev]);
|
||||
if (irq[dev] >= 0) {
|
||||
sprintf(card->longname + strlen(card->longname), "irq %d", irq[dev]);
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <sound/initval.h>
|
||||
#include <sound/rawmidi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
/*
|
||||
* globals
|
||||
@@ -605,11 +606,11 @@ static void snd_mtpav_set_name(struct mtpav *chip,
|
||||
else if (substream->number >= 8 && substream->number < chip->num_ports * 2)
|
||||
sprintf(substream->name, "MTP remote %d", (substream->number % chip->num_ports) + 1);
|
||||
else if (substream->number == chip->num_ports * 2)
|
||||
strcpy(substream->name, "MTP computer");
|
||||
strscpy(substream->name, "MTP computer");
|
||||
else if (substream->number == chip->num_ports * 2 + 1)
|
||||
strcpy(substream->name, "MTP ADAT");
|
||||
strscpy(substream->name, "MTP ADAT");
|
||||
else
|
||||
strcpy(substream->name, "MTP broadcast");
|
||||
strscpy(substream->name, "MTP broadcast");
|
||||
}
|
||||
|
||||
static int snd_mtpav_get_RAWMIDI(struct mtpav *mcard)
|
||||
@@ -697,8 +698,8 @@ static int snd_mtpav_probe(struct platform_device *dev)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
strcpy(card->driver, "MTPAV");
|
||||
strcpy(card->shortname, "MTPAV on parallel port");
|
||||
strscpy(card->driver, "MTPAV");
|
||||
strscpy(card->shortname, "MTPAV on parallel port");
|
||||
snprintf(card->longname, sizeof(card->longname),
|
||||
"MTPAV on parallel port at 0x%lx", port);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/rawmidi.h>
|
||||
@@ -763,7 +764,7 @@ static int snd_mts64_rawmidi_create(struct snd_card *card)
|
||||
return err;
|
||||
|
||||
rmidi->private_data = mts;
|
||||
strcpy(rmidi->name, CARD_NAME);
|
||||
strscpy(rmidi->name, CARD_NAME);
|
||||
rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
|
||||
SNDRV_RAWMIDI_INFO_INPUT |
|
||||
SNDRV_RAWMIDI_INFO_DUPLEX;
|
||||
@@ -791,7 +792,7 @@ static int snd_mts64_rawmidi_create(struct snd_card *card)
|
||||
mts->midi_input_substream[substream->number] = substream;
|
||||
switch(substream->number) {
|
||||
case MTS64_SMPTE_SUBSTREAM:
|
||||
strcpy(substream->name, "Miditerminal SMPTE");
|
||||
strscpy(substream->name, "Miditerminal SMPTE");
|
||||
break;
|
||||
default:
|
||||
sprintf(substream->name,
|
||||
@@ -929,8 +930,8 @@ static int snd_mts64_probe(struct platform_device *pdev)
|
||||
dev_dbg(&pdev->dev, "Cannot create card\n");
|
||||
return err;
|
||||
}
|
||||
strcpy(card->driver, DRIVER_NAME);
|
||||
strcpy(card->shortname, "ESI " CARD_NAME);
|
||||
strscpy(card->driver, DRIVER_NAME);
|
||||
strscpy(card->shortname, "ESI " CARD_NAME);
|
||||
sprintf(card->longname, "%s at 0x%lx, irq %i",
|
||||
card->shortname, p->base, p->irq);
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ static int snd_opl3_timer1_init(struct snd_opl3 * opl3, int timer_no)
|
||||
tid.subdevice = 0;
|
||||
err = snd_timer_new(opl3->card, "AdLib timer #1", &tid, &timer);
|
||||
if (err >= 0) {
|
||||
strcpy(timer->name, "AdLib timer #1");
|
||||
strscpy(timer->name, "AdLib timer #1");
|
||||
timer->private_data = opl3;
|
||||
timer->hw = snd_opl3_timer1;
|
||||
}
|
||||
@@ -266,7 +266,7 @@ static int snd_opl3_timer2_init(struct snd_opl3 * opl3, int timer_no)
|
||||
tid.subdevice = 0;
|
||||
err = snd_timer_new(opl3->card, "AdLib timer #2", &tid, &timer);
|
||||
if (err >= 0) {
|
||||
strcpy(timer->name, "AdLib timer #2");
|
||||
strscpy(timer->name, "AdLib timer #2");
|
||||
timer->private_data = opl3;
|
||||
timer->hw = snd_opl3_timer2;
|
||||
}
|
||||
@@ -497,18 +497,18 @@ int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
|
||||
if (device == 0)
|
||||
hw->oss_type = SNDRV_OSS_DEVICE_TYPE_DMFM;
|
||||
#endif
|
||||
strcpy(hw->name, hw->id);
|
||||
strscpy(hw->name, hw->id);
|
||||
switch (opl3->hardware & OPL3_HW_MASK) {
|
||||
case OPL3_HW_OPL2:
|
||||
strcpy(hw->name, "OPL2 FM");
|
||||
strscpy(hw->name, "OPL2 FM");
|
||||
hw->iface = SNDRV_HWDEP_IFACE_OPL2;
|
||||
break;
|
||||
case OPL3_HW_OPL3:
|
||||
strcpy(hw->name, "OPL3 FM");
|
||||
strscpy(hw->name, "OPL3 FM");
|
||||
hw->iface = SNDRV_HWDEP_IFACE_OPL3;
|
||||
break;
|
||||
case OPL3_HW_OPL4:
|
||||
strcpy(hw->name, "OPL4 FM");
|
||||
strscpy(hw->name, "OPL4 FM");
|
||||
hw->iface = SNDRV_HWDEP_IFACE_OPL4;
|
||||
break;
|
||||
}
|
||||
@@ -524,7 +524,7 @@ int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
|
||||
#if IS_ENABLED(CONFIG_SND_SEQUENCER)
|
||||
if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3,
|
||||
sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) {
|
||||
strcpy(opl3->seq_dev->name, hw->name);
|
||||
strscpy(opl3->seq_dev->name, hw->name);
|
||||
*(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -152,7 +152,7 @@ static int snd_opl4_create_seq_dev(struct snd_opl4 *opl4, int seq_device)
|
||||
opl4->seq_dev_num = seq_device;
|
||||
if (snd_seq_device_new(opl4->card, seq_device, SNDRV_SEQ_DEV_ID_OPL4,
|
||||
sizeof(struct snd_opl4 *), &opl4->seq_dev) >= 0) {
|
||||
strcpy(opl4->seq_dev->name, "OPL4 Wavetable");
|
||||
strscpy(opl4->seq_dev->name, "OPL4 Wavetable");
|
||||
*(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(opl4->seq_dev) = opl4;
|
||||
opl4->seq_dev->private_data = opl4;
|
||||
opl4->seq_dev->private_free = snd_opl4_seq_dev_free;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <sound/core.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/debugfs.h>
|
||||
@@ -555,7 +556,7 @@ static int snd_pcmtst_new_pcm(struct pcmtst *pcmtst)
|
||||
if (err < 0)
|
||||
return err;
|
||||
pcm->private_data = pcmtst;
|
||||
strcpy(pcm->name, "PCMTest");
|
||||
strscpy(pcm->name, "PCMTest");
|
||||
pcmtst->pcm = pcm;
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_pcmtst_playback_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_pcmtst_capture_ops);
|
||||
@@ -613,9 +614,9 @@ static int pcmtst_probe(struct platform_device *pdev)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
strcpy(card->driver, "PCM-TEST Driver");
|
||||
strcpy(card->shortname, "PCM-Test");
|
||||
strcpy(card->longname, "PCM-Test virtual driver");
|
||||
strscpy(card->driver, "PCM-TEST Driver");
|
||||
strscpy(card->shortname, "PCM-Test");
|
||||
strscpy(card->longname, "PCM-Test virtual driver");
|
||||
|
||||
err = snd_card_register(card);
|
||||
if (err < 0)
|
||||
|
||||
@@ -122,8 +122,8 @@ static int snd_card_pcsp_probe(int devnum, struct device *dev)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
strcpy(card->driver, "PC-Speaker");
|
||||
strcpy(card->shortname, "pcsp");
|
||||
strscpy(card->driver, "PC-Speaker");
|
||||
strscpy(card->shortname, "pcsp");
|
||||
sprintf(card->longname, "Internal PC-Speaker at port 0x%x",
|
||||
pcsp_chip.port);
|
||||
|
||||
|
||||
@@ -340,7 +340,7 @@ int snd_pcsp_new_pcm(struct snd_pcsp *chip)
|
||||
|
||||
chip->pcm->private_data = chip;
|
||||
chip->pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
|
||||
strcpy(chip->pcm->name, "pcsp");
|
||||
strscpy(chip->pcm->name, "pcsp");
|
||||
|
||||
snd_pcm_set_managed_buffer_all(chip->pcm,
|
||||
SNDRV_DMA_TYPE_CONTINUOUS,
|
||||
|
||||
@@ -158,7 +158,7 @@ int snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
strcpy(card->mixername, "PC-Speaker");
|
||||
strscpy(card->mixername, "PC-Speaker");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -549,7 +549,7 @@ static int snd_portman_rawmidi_create(struct snd_card *card)
|
||||
return err;
|
||||
|
||||
rmidi->private_data = pm;
|
||||
strcpy(rmidi->name, CARD_NAME);
|
||||
strscpy(rmidi->name, CARD_NAME);
|
||||
rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
|
||||
SNDRV_RAWMIDI_INFO_INPUT |
|
||||
SNDRV_RAWMIDI_INFO_DUPLEX;
|
||||
@@ -714,8 +714,8 @@ static int snd_portman_probe(struct platform_device *pdev)
|
||||
dev_dbg(&pdev->dev, "Cannot create card\n");
|
||||
return err;
|
||||
}
|
||||
strcpy(card->driver, DRIVER_NAME);
|
||||
strcpy(card->shortname, CARD_NAME);
|
||||
strscpy(card->driver, DRIVER_NAME);
|
||||
strscpy(card->shortname, CARD_NAME);
|
||||
sprintf(card->longname, "%s at 0x%lx, irq %i",
|
||||
card->shortname, p->base, p->irq);
|
||||
|
||||
|
||||
@@ -300,7 +300,7 @@ static int snd_serial_generic_rmidi(struct snd_serial_generic *drvdata,
|
||||
&snd_serial_generic_input);
|
||||
snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
|
||||
&snd_serial_generic_output);
|
||||
strcpy(rrawmidi->name, drvdata->card->shortname);
|
||||
strscpy(rrawmidi->name, drvdata->card->shortname);
|
||||
|
||||
snd_serial_generic_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT],
|
||||
drvdata->serdev->ctrl->nr);
|
||||
@@ -329,7 +329,7 @@ static int snd_serial_generic_probe(struct serdev_device *serdev)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
strcpy(card->driver, "SerialMIDI");
|
||||
strscpy(card->driver, "SerialMIDI");
|
||||
sprintf(card->shortname, "SerialMIDI-%d", serdev->ctrl->nr);
|
||||
sprintf(card->longname, "Serial MIDI device at serial%d", serdev->ctrl->nr);
|
||||
|
||||
|
||||
@@ -845,7 +845,7 @@ static int snd_uart16550_rmidi(struct snd_uart16550 *uart, int device,
|
||||
&snd_uart16550_input);
|
||||
snd_rawmidi_set_ops(rrawmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
|
||||
&snd_uart16550_output);
|
||||
strcpy(rrawmidi->name, "Serial MIDI");
|
||||
strscpy(rrawmidi->name, "Serial MIDI");
|
||||
snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);
|
||||
snd_uart16550_substreams(&rrawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]);
|
||||
rrawmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
|
||||
@@ -905,8 +905,8 @@ static int snd_serial_probe(struct platform_device *devptr)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
strcpy(card->driver, "Serial");
|
||||
strcpy(card->shortname, "Serial MIDI (UART16550A)");
|
||||
strscpy(card->driver, "Serial");
|
||||
strscpy(card->shortname, "Serial MIDI (UART16550A)");
|
||||
|
||||
err = snd_uart16550_create(card, port[dev], irq[dev], speed[dev],
|
||||
base[dev], adaptor[dev], droponfull[dev],
|
||||
|
||||
@@ -95,11 +95,11 @@ static int snd_virmidi_probe(struct platform_device *devptr)
|
||||
if (err < 0)
|
||||
return err;
|
||||
vmidi->midi[idx] = rmidi;
|
||||
strcpy(rmidi->name, "Virtual Raw MIDI");
|
||||
strscpy(rmidi->name, "Virtual Raw MIDI");
|
||||
}
|
||||
|
||||
strcpy(card->driver, "VirMIDI");
|
||||
strcpy(card->shortname, "VirMIDI");
|
||||
strscpy(card->driver, "VirMIDI");
|
||||
strscpy(card->shortname, "VirMIDI");
|
||||
sprintf(card->longname, "Virtual MIDI Card %i", dev + 1);
|
||||
|
||||
err = snd_card_register(card);
|
||||
|
||||
@@ -806,7 +806,7 @@ struct vx_core *snd_vx_create(struct snd_card *card,
|
||||
|
||||
chip->card = card;
|
||||
card->private_data = chip;
|
||||
strcpy(card->driver, hw->name);
|
||||
strscpy(card->driver, hw->name);
|
||||
sprintf(card->shortname, "Digigram %s", hw->name);
|
||||
|
||||
vx_proc_init(chip);
|
||||
|
||||
@@ -903,7 +903,7 @@ int snd_vx_mixer_new(struct vx_core *chip)
|
||||
struct snd_card *card = chip->card;
|
||||
char name[32];
|
||||
|
||||
strcpy(card->mixername, card->driver);
|
||||
strscpy(card->mixername, card->driver);
|
||||
|
||||
/* output level controls */
|
||||
for (i = 0; i < chip->hw->num_outs; i++) {
|
||||
|
||||
@@ -1226,7 +1226,7 @@ int snd_vx_pcm_new(struct vx_core *chip)
|
||||
pcm->private_free = snd_vx_pcm_free;
|
||||
pcm->info_flags = 0;
|
||||
pcm->nonatomic = true;
|
||||
strcpy(pcm->name, chip->card->shortname);
|
||||
strscpy(pcm->name, chip->card->shortname);
|
||||
chip->pcm[i] = pcm;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,9 +105,9 @@ name_device(struct snd_bebob *bebob)
|
||||
if (err < 0)
|
||||
goto end;
|
||||
|
||||
strcpy(bebob->card->driver, "BeBoB");
|
||||
strcpy(bebob->card->shortname, model);
|
||||
strcpy(bebob->card->mixername, model);
|
||||
strscpy(bebob->card->driver, "BeBoB");
|
||||
strscpy(bebob->card->shortname, model);
|
||||
strscpy(bebob->card->mixername, model);
|
||||
snprintf(bebob->card->longname, sizeof(bebob->card->longname),
|
||||
"%s %s (id:%d, rev:%d), GUID %08x%08x at %s, S%d",
|
||||
vendor, model, hw_id, revision,
|
||||
|
||||
@@ -183,7 +183,7 @@ int snd_bebob_create_hwdep_device(struct snd_bebob *bebob)
|
||||
err = snd_hwdep_new(bebob->card, "BeBoB", 0, &hwdep);
|
||||
if (err < 0)
|
||||
goto end;
|
||||
strcpy(hwdep->name, "BeBoB");
|
||||
strscpy(hwdep->name, "BeBoB");
|
||||
hwdep->iface = SNDRV_HWDEP_IFACE_FW_BEBOB;
|
||||
hwdep->ops = ops;
|
||||
hwdep->private_data = bebob;
|
||||
|
||||
@@ -179,7 +179,7 @@ int snd_dice_create_hwdep(struct snd_dice *dice)
|
||||
err = snd_hwdep_new(dice->card, "DICE", 0, &hwdep);
|
||||
if (err < 0)
|
||||
return err;
|
||||
strcpy(hwdep->name, "DICE");
|
||||
strscpy(hwdep->name, "DICE");
|
||||
hwdep->iface = SNDRV_HWDEP_IFACE_FW_DICE;
|
||||
hwdep->ops = ops;
|
||||
hwdep->private_data = dice;
|
||||
|
||||
@@ -442,7 +442,7 @@ int snd_dice_create_pcm(struct snd_dice *dice)
|
||||
return err;
|
||||
pcm->private_data = dice;
|
||||
pcm->nonatomic = true;
|
||||
strcpy(pcm->name, dice->card->shortname);
|
||||
strscpy(pcm->name, dice->card->shortname);
|
||||
|
||||
if (capture > 0)
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
|
||||
|
||||
@@ -102,9 +102,9 @@ static void dice_card_strings(struct snd_dice *dice)
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
strcpy(card->driver, "DICE");
|
||||
strscpy(card->driver, "DICE");
|
||||
|
||||
strcpy(card->shortname, "DICE");
|
||||
strscpy(card->shortname, "DICE");
|
||||
BUILD_BUG_ON(NICK_NAME_SIZE < sizeof(card->shortname));
|
||||
err = snd_dice_transaction_read_global(dice, GLOBAL_NICK_NAME,
|
||||
card->shortname,
|
||||
@@ -117,16 +117,16 @@ static void dice_card_strings(struct snd_dice *dice)
|
||||
card->shortname[sizeof(card->shortname) - 1] = '\0';
|
||||
}
|
||||
|
||||
strcpy(vendor, "?");
|
||||
strscpy(vendor, "?");
|
||||
fw_csr_string(dev->config_rom + 5, CSR_VENDOR, vendor, sizeof(vendor));
|
||||
strcpy(model, "?");
|
||||
strscpy(model, "?");
|
||||
fw_csr_string(dice->unit->directory, CSR_MODEL, model, sizeof(model));
|
||||
snprintf(card->longname, sizeof(card->longname),
|
||||
"%s %s (serial %u) at %s, S%d",
|
||||
vendor, model, dev->config_rom[4] & 0x3fffff,
|
||||
dev_name(&dice->unit->device), 100 << dev->max_speed);
|
||||
|
||||
strcpy(card->mixername, "DICE");
|
||||
strscpy(card->mixername, "DICE");
|
||||
}
|
||||
|
||||
static void dice_card_free(struct snd_card *card)
|
||||
|
||||
@@ -188,7 +188,7 @@ int snd_dg00x_create_hwdep_device(struct snd_dg00x *dg00x)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
strcpy(hwdep->name, "Digi00x");
|
||||
strscpy(hwdep->name, "Digi00x");
|
||||
hwdep->iface = SNDRV_HWDEP_IFACE_FW_DIGI00X;
|
||||
hwdep->ops = ops;
|
||||
hwdep->private_data = dg00x;
|
||||
|
||||
@@ -30,9 +30,9 @@ static int name_card(struct snd_dg00x *dg00x)
|
||||
|
||||
model = skip_spaces(name);
|
||||
|
||||
strcpy(dg00x->card->driver, "Digi00x");
|
||||
strcpy(dg00x->card->shortname, model);
|
||||
strcpy(dg00x->card->mixername, model);
|
||||
strscpy(dg00x->card->driver, "Digi00x");
|
||||
strscpy(dg00x->card->shortname, model);
|
||||
strscpy(dg00x->card->mixername, model);
|
||||
snprintf(dg00x->card->longname, sizeof(dg00x->card->longname),
|
||||
"Digidesign %s, GUID %08x%08x at %s, S%d", model,
|
||||
fw_dev->config_rom[3], fw_dev->config_rom[4],
|
||||
|
||||
@@ -197,7 +197,7 @@ int snd_ff_create_hwdep_devices(struct snd_ff *ff)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
strcpy(hwdep->name, ff->card->driver);
|
||||
strscpy(hwdep->name, ff->card->driver);
|
||||
hwdep->iface = SNDRV_HWDEP_IFACE_FW_FIREFACE;
|
||||
hwdep->ops = hwdep_ops;
|
||||
hwdep->private_data = ff;
|
||||
|
||||
@@ -27,9 +27,9 @@ static void name_card(struct snd_ff *ff)
|
||||
|
||||
name = names[ff->unit_version];
|
||||
|
||||
strcpy(ff->card->driver, "Fireface");
|
||||
strcpy(ff->card->shortname, name);
|
||||
strcpy(ff->card->mixername, name);
|
||||
strscpy(ff->card->driver, "Fireface");
|
||||
strscpy(ff->card->shortname, name);
|
||||
strscpy(ff->card->mixername, name);
|
||||
snprintf(ff->card->longname, sizeof(ff->card->longname),
|
||||
"RME %s, GUID %08x%08x at %s, S%d", name,
|
||||
fw_dev->config_rom[3], fw_dev->config_rom[4],
|
||||
|
||||
@@ -90,9 +90,9 @@ get_hardware_info(struct snd_efw *efw)
|
||||
(hwinfo->arm_version >> 16) & 0xff);
|
||||
efw->firmware_version = hwinfo->arm_version;
|
||||
|
||||
strcpy(efw->card->driver, "Fireworks");
|
||||
strcpy(efw->card->shortname, hwinfo->model_name);
|
||||
strcpy(efw->card->mixername, hwinfo->model_name);
|
||||
strscpy(efw->card->driver, "Fireworks");
|
||||
strscpy(efw->card->shortname, hwinfo->model_name);
|
||||
strscpy(efw->card->mixername, hwinfo->model_name);
|
||||
scnprintf(efw->card->longname, sizeof(efw->card->longname),
|
||||
"%s %s v%s, GUID %08x%08x at %s, S%d",
|
||||
hwinfo->vendor_name, hwinfo->model_name, version,
|
||||
|
||||
@@ -319,7 +319,7 @@ int snd_efw_create_hwdep_device(struct snd_efw *efw)
|
||||
err = snd_hwdep_new(efw->card, "Fireworks", 0, &hwdep);
|
||||
if (err < 0)
|
||||
goto end;
|
||||
strcpy(hwdep->name, "Fireworks");
|
||||
strscpy(hwdep->name, "Fireworks");
|
||||
hwdep->iface = SNDRV_HWDEP_IFACE_FW_FIREWORKS;
|
||||
hwdep->ops = ops;
|
||||
hwdep->private_data = efw;
|
||||
|
||||
@@ -455,7 +455,7 @@ static int isight_create_pcm(struct isight *isight)
|
||||
return err;
|
||||
pcm->private_data = isight;
|
||||
pcm->nonatomic = true;
|
||||
strcpy(pcm->name, "iSight");
|
||||
strscpy(pcm->name, "iSight");
|
||||
isight->pcm = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
|
||||
isight->pcm->ops = &ops;
|
||||
snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0);
|
||||
@@ -638,13 +638,13 @@ static int isight_probe(struct fw_unit *unit,
|
||||
|
||||
card->private_free = isight_card_free;
|
||||
|
||||
strcpy(card->driver, "iSight");
|
||||
strcpy(card->shortname, "Apple iSight");
|
||||
strscpy(card->driver, "iSight");
|
||||
strscpy(card->shortname, "Apple iSight");
|
||||
snprintf(card->longname, sizeof(card->longname),
|
||||
"Apple iSight (GUID %08x%08x) at %s, S%d",
|
||||
fw_dev->config_rom[3], fw_dev->config_rom[4],
|
||||
dev_name(&unit->device), 100 << fw_dev->max_speed);
|
||||
strcpy(card->mixername, "iSight");
|
||||
strscpy(card->mixername, "iSight");
|
||||
|
||||
err = isight_create_pcm(isight);
|
||||
if (err < 0)
|
||||
|
||||
@@ -290,7 +290,7 @@ int snd_motu_create_hwdep_device(struct snd_motu *motu)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
strcpy(hwdep->name, "MOTU");
|
||||
strscpy(hwdep->name, "MOTU");
|
||||
hwdep->iface = SNDRV_HWDEP_IFACE_FW_MOTU;
|
||||
hwdep->ops = ops;
|
||||
hwdep->private_data = motu;
|
||||
|
||||
@@ -361,7 +361,7 @@ int snd_motu_create_pcm_devices(struct snd_motu *motu)
|
||||
return err;
|
||||
pcm->private_data = motu;
|
||||
pcm->nonatomic = true;
|
||||
strcpy(pcm->name, motu->card->shortname);
|
||||
strscpy(pcm->name, motu->card->shortname);
|
||||
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
|
||||
|
||||
@@ -41,9 +41,9 @@ static void name_card(struct snd_motu *motu)
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(motu->card->driver, "FW-MOTU");
|
||||
strcpy(motu->card->shortname, motu->spec->name);
|
||||
strcpy(motu->card->mixername, motu->spec->name);
|
||||
strscpy(motu->card->driver, "FW-MOTU");
|
||||
strscpy(motu->card->shortname, motu->spec->name);
|
||||
strscpy(motu->card->mixername, motu->spec->name);
|
||||
snprintf(motu->card->longname, sizeof(motu->card->longname),
|
||||
"MOTU %s (version:%06x), GUID %08x%08x at %s, S%d",
|
||||
motu->spec->name, version,
|
||||
|
||||
@@ -177,7 +177,7 @@ int snd_oxfw_create_hwdep(struct snd_oxfw *oxfw)
|
||||
err = snd_hwdep_new(oxfw->card, oxfw->card->driver, 0, &hwdep);
|
||||
if (err < 0)
|
||||
goto end;
|
||||
strcpy(hwdep->name, oxfw->card->driver);
|
||||
strscpy(hwdep->name, oxfw->card->driver);
|
||||
hwdep->iface = SNDRV_HWDEP_IFACE_FW_OXFW;
|
||||
hwdep->ops = hwdep_ops;
|
||||
hwdep->private_data = oxfw;
|
||||
|
||||
@@ -441,7 +441,7 @@ int snd_oxfw_create_pcm(struct snd_oxfw *oxfw)
|
||||
|
||||
pcm->private_data = oxfw;
|
||||
pcm->nonatomic = true;
|
||||
strcpy(pcm->name, oxfw->card->shortname);
|
||||
strscpy(pcm->name, oxfw->card->shortname);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops);
|
||||
if (cap > 0)
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops);
|
||||
|
||||
@@ -105,9 +105,9 @@ static int name_card(struct snd_oxfw *oxfw, const struct ieee1394_device_id *ent
|
||||
m = model;
|
||||
}
|
||||
|
||||
strcpy(oxfw->card->driver, d);
|
||||
strcpy(oxfw->card->mixername, m);
|
||||
strcpy(oxfw->card->shortname, m);
|
||||
strscpy(oxfw->card->driver, d);
|
||||
strscpy(oxfw->card->mixername, m);
|
||||
strscpy(oxfw->card->shortname, m);
|
||||
|
||||
scnprintf(oxfw->card->longname, sizeof(oxfw->card->longname),
|
||||
"%s %s (OXFW%x %04x), GUID %08x%08x at %s, S%d",
|
||||
|
||||
@@ -265,7 +265,7 @@ int snd_tscm_create_hwdep_device(struct snd_tscm *tscm)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
strcpy(hwdep->name, "Tascam");
|
||||
strscpy(hwdep->name, "Tascam");
|
||||
hwdep->iface = SNDRV_HWDEP_IFACE_FW_TASCAM;
|
||||
hwdep->ops = ops;
|
||||
hwdep->private_data = tscm;
|
||||
|
||||
@@ -73,9 +73,9 @@ static int identify_model(struct snd_tscm *tscm)
|
||||
if (tscm->spec == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
strcpy(tscm->card->driver, "FW-TASCAM");
|
||||
strcpy(tscm->card->shortname, model);
|
||||
strcpy(tscm->card->mixername, model);
|
||||
strscpy(tscm->card->driver, "FW-TASCAM");
|
||||
strscpy(tscm->card->shortname, model);
|
||||
strscpy(tscm->card->mixername, model);
|
||||
snprintf(tscm->card->longname, sizeof(tscm->card->longname),
|
||||
"TASCAM %s, GUID %08x%08x at %s, S%d", model,
|
||||
fw_dev->config_rom[3], fw_dev->config_rom[4],
|
||||
|
||||
+6
-64
@@ -1,67 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config SND_HDA_CORE
|
||||
tristate
|
||||
select REGMAP
|
||||
menu "HD-Audio"
|
||||
|
||||
config SND_HDA_DSP_LOADER
|
||||
bool
|
||||
source "sound/hda/common/Kconfig"
|
||||
source "sound/hda/controllers/Kconfig"
|
||||
source "sound/hda/codecs/Kconfig"
|
||||
source "sound/hda/core/Kconfig"
|
||||
|
||||
config SND_HDA_ALIGNED_MMIO
|
||||
bool
|
||||
|
||||
config SND_HDA_COMPONENT
|
||||
bool
|
||||
|
||||
config SND_HDA_I915
|
||||
bool
|
||||
select SND_HDA_COMPONENT
|
||||
|
||||
config SND_HDA_EXT_CORE
|
||||
tristate
|
||||
select SND_HDA_CORE
|
||||
|
||||
config SND_HDA_PREALLOC_SIZE
|
||||
int "Pre-allocated buffer size for HD-audio driver"
|
||||
range 0 32768
|
||||
default 0 if SND_DMA_SGBUF
|
||||
default 64 if !SND_DMA_SGBUF
|
||||
help
|
||||
Specifies the default pre-allocated buffer-size in kB for the
|
||||
HD-audio driver. A larger buffer (e.g. 2048) is preferred
|
||||
for systems using PulseAudio. The default 64 is chosen just
|
||||
for compatibility reasons.
|
||||
On x86 systems, the default is zero as S/G allocation works
|
||||
and no preallocation is needed in most cases.
|
||||
|
||||
Note that the pre-allocation size can be changed dynamically
|
||||
via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too.
|
||||
|
||||
config SND_INTEL_NHLT
|
||||
bool
|
||||
# this config should be selected only for Intel ACPI platforms.
|
||||
# A fallback is provided so that the code compiles in all cases.
|
||||
|
||||
config SND_INTEL_DSP_CONFIG
|
||||
tristate
|
||||
select ACPI_NHLT if ACPI
|
||||
select SND_INTEL_NHLT if ACPI
|
||||
select SND_INTEL_SOUNDWIRE_ACPI if ACPI
|
||||
# this config should be selected only for Intel DSP platforms.
|
||||
# A fallback is provided so that the code compiles in all cases.
|
||||
|
||||
config SND_INTEL_SOUNDWIRE_ACPI
|
||||
tristate
|
||||
|
||||
config SND_INTEL_BYT_PREFER_SOF
|
||||
bool "Prefer SOF driver over SST on BY/CHT platforms"
|
||||
depends on SND_SST_ATOM_HIFI2_PLATFORM_ACPI && SND_SOC_SOF_BAYTRAIL
|
||||
default n
|
||||
help
|
||||
The kernel has 2 drivers for the Low Power Engine audio-block on
|
||||
Bay- and Cherry-Trail SoCs. The old SST driver and the new SOF
|
||||
driver. If both drivers are enabled then the kernel will default
|
||||
to using the old SST driver, unless told otherwise through the
|
||||
snd_intel_dspcfg.dsp_driver module-parameter.
|
||||
|
||||
Set this option to Y to make the kernel default to the new SOF
|
||||
driver instead.
|
||||
endmenu
|
||||
|
||||
+7
-21
@@ -1,22 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
snd-hda-core-y := hda_bus_type.o hdac_bus.o hdac_device.o hdac_sysfs.o \
|
||||
hdac_regmap.o hdac_controller.o hdac_stream.o array.o hdmi_chmap.o
|
||||
|
||||
snd-hda-core-y += trace.o
|
||||
CFLAGS_trace.o := -I$(src)
|
||||
|
||||
# for sync with i915 gfx driver
|
||||
snd-hda-core-$(CONFIG_SND_HDA_COMPONENT) += hdac_component.o
|
||||
snd-hda-core-$(CONFIG_SND_HDA_I915) += hdac_i915.o
|
||||
|
||||
obj-$(CONFIG_SND_HDA_CORE) += snd-hda-core.o
|
||||
|
||||
#extended hda
|
||||
obj-$(CONFIG_SND_HDA_EXT_CORE) += ext/
|
||||
|
||||
snd-intel-dspcfg-y := intel-dsp-config.o
|
||||
snd-intel-dspcfg-$(CONFIG_SND_INTEL_NHLT) += intel-nhlt.o
|
||||
obj-$(CONFIG_SND_INTEL_DSP_CONFIG) += snd-intel-dspcfg.o
|
||||
|
||||
snd-intel-sdw-acpi-y := intel-sdw-acpi.o
|
||||
obj-$(CONFIG_SND_INTEL_SOUNDWIRE_ACPI) += snd-intel-sdw-acpi.o
|
||||
obj-y += core/
|
||||
obj-$(CONFIG_SND_HDA) += common/
|
||||
obj-$(CONFIG_SND_HDA) += codecs/
|
||||
# this must be the last entry after codec drivers;
|
||||
# otherwise the codec drivers won't be hooked before the PCI probe
|
||||
# when built in kernel
|
||||
obj-$(CONFIG_SND_HDA) += controllers/
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
if SND_HDA
|
||||
|
||||
config SND_HDA_GENERIC_LEDS
|
||||
bool
|
||||
|
||||
config SND_HDA_CODEC_ANALOG
|
||||
tristate "Build Analog Devices HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y or M here to include Analog Devices HD-audio codec support in
|
||||
snd-hda-intel driver, such as AD1986A.
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_ANALOG=m
|
||||
|
||||
config SND_HDA_CODEC_SIGMATEL
|
||||
tristate "Build IDT/Sigmatel HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
select SND_HDA_GENERIC_LEDS
|
||||
help
|
||||
Say Y or M here to include IDT (Sigmatel) HD-audio codec support in
|
||||
snd-hda-intel driver, such as STAC9200.
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_SIGMATEL=m
|
||||
|
||||
config SND_HDA_CODEC_VIA
|
||||
tristate "Build VIA HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y or M here to include VIA HD-audio codec support in
|
||||
snd-hda-intel driver, such as VT1708.
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_VIA=m
|
||||
|
||||
config SND_HDA_CODEC_CONEXANT
|
||||
tristate "Build Conexant HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
select SND_HDA_GENERIC_LEDS
|
||||
help
|
||||
Say Y or M here to include Conexant HD-audio codec support in
|
||||
snd-hda-intel driver, such as CX20549.
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_CONEXANT=m
|
||||
|
||||
config SND_HDA_CODEC_SENARYTECH
|
||||
tristate "Build Senarytech HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
select SND_HDA_GENERIC_LEDS
|
||||
help
|
||||
Say Y or M here to include Senarytech HD-audio codec support in
|
||||
snd-hda-intel driver, such as SN6186.
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_SENARYTECH=m
|
||||
|
||||
config SND_HDA_CODEC_CA0110
|
||||
tristate "Build Creative CA0110-IBG codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y or M here to include Creative CA0110-IBG codec support in
|
||||
snd-hda-intel driver, found on some Creative X-Fi cards.
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_CA0110=m
|
||||
|
||||
config SND_HDA_CODEC_CA0132
|
||||
tristate "Build Creative CA0132 codec support"
|
||||
help
|
||||
Say Y or M here to include Creative CA0132 codec support in
|
||||
snd-hda-intel driver.
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_CA0132=m
|
||||
|
||||
config SND_HDA_CODEC_CA0132_DSP
|
||||
bool "Support new DSP code for CA0132 codec"
|
||||
depends on SND_HDA_CODEC_CA0132
|
||||
default y
|
||||
select SND_HDA_DSP_LOADER
|
||||
select FW_LOADER
|
||||
help
|
||||
Say Y here to enable the DSP for Creative CA0132 for extended
|
||||
features like equalizer or echo cancellation.
|
||||
|
||||
Note that this option requires the external firmware file
|
||||
(ctefx.bin).
|
||||
|
||||
config SND_HDA_CODEC_CMEDIA
|
||||
tristate "Build C-Media HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y or M here to include C-Media HD-audio codec support in
|
||||
snd-hda-intel driver, such as CMI9880.
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_CMEDIA=m
|
||||
|
||||
config SND_HDA_CODEC_CM9825
|
||||
tristate "Build C-Media CM9825 HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y or M here to include C-Media CM9825 HD-audio codec support in
|
||||
snd-hda-intel driver
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_CM9825=m
|
||||
|
||||
config SND_HDA_CODEC_SI3054
|
||||
tristate "Build Silicon Labs 3054 HD-modem codec support"
|
||||
help
|
||||
Say Y or M here to include Silicon Labs 3054 HD-modem codec
|
||||
(and compatibles) support in snd-hda-intel driver.
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_SI3054=m
|
||||
|
||||
config SND_HDA_GENERIC
|
||||
tristate "Enable generic HD-audio codec parser"
|
||||
select SND_CTL_LED if SND_HDA_GENERIC_LEDS
|
||||
select LEDS_CLASS if SND_HDA_GENERIC_LEDS
|
||||
help
|
||||
Say Y or M here to enable the generic HD-audio codec parser
|
||||
in snd-hda-intel driver.
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_GENERIC=m
|
||||
|
||||
source "sound/hda/codecs/realtek/Kconfig"
|
||||
source "sound/hda/codecs/cirrus/Kconfig"
|
||||
source "sound/hda/codecs/hdmi/Kconfig"
|
||||
source "sound/hda/codecs/side-codecs/Kconfig"
|
||||
|
||||
endif # SND_HDA
|
||||
@@ -0,0 +1,34 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
subdir-ccflags-y += -I$(src)/../common
|
||||
|
||||
snd-hda-codec-generic-y := generic.o
|
||||
snd-hda-codec-cmedia-y := cmedia.o
|
||||
snd-hda-codec-cm9825-y := cm9825.o
|
||||
snd-hda-codec-analog-y := analog.o
|
||||
snd-hda-codec-ca0110-y := ca0110.o
|
||||
snd-hda-codec-ca0132-y := ca0132.o
|
||||
snd-hda-codec-cmedia-y := cmedia.o
|
||||
snd-hda-codec-conexant-y := conexant.o
|
||||
snd-hda-codec-idt-y := sigmatel.o
|
||||
snd-hda-codec-senarytech-y := senarytech.o
|
||||
snd-hda-codec-si3054-y := si3054.o
|
||||
snd-hda-codec-via-y := via.o
|
||||
|
||||
obj-y += cirrus/
|
||||
obj-y += hdmi/
|
||||
obj-y += realtek/
|
||||
obj-y += side-codecs/
|
||||
|
||||
# codec drivers
|
||||
obj-$(CONFIG_SND_HDA_GENERIC) += snd-hda-codec-generic.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_CMEDIA) += snd-hda-codec-cmedia.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_CM9825) += snd-hda-codec-cm9825.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_ANALOG) += snd-hda-codec-analog.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_CA0110) += snd-hda-codec-ca0110.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_CA0132) += snd-hda-codec-ca0132.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_CMEDIA) += snd-hda-codec-cmedia.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_CONEXANT) += snd-hda-codec-conexant.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_SIGMATEL) += snd-hda-codec-idt.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_SENARYTECH) += snd-hda-codec-senarytech.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_SI3054) += snd-hda-codec-si3054.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_VIA) += snd-hda-codec-via.o
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984,
|
||||
* HD audio codec driver for AD1882, AD1884, AD1981HD, AD1983, AD1984,
|
||||
* AD1986A, AD1988
|
||||
*
|
||||
* Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de>
|
||||
@@ -16,11 +16,20 @@
|
||||
#include "hda_auto_parser.h"
|
||||
#include "hda_beep.h"
|
||||
#include "hda_jack.h"
|
||||
#include "hda_generic.h"
|
||||
#include "generic.h"
|
||||
|
||||
enum {
|
||||
MODEL_AD1882,
|
||||
MODEL_AD1884,
|
||||
MODEL_AD1981,
|
||||
MODEL_AD1983,
|
||||
MODEL_AD1986A,
|
||||
MODEL_AD1988,
|
||||
};
|
||||
|
||||
struct ad198x_spec {
|
||||
struct hda_gen_spec gen;
|
||||
int model;
|
||||
|
||||
/* for auto parser */
|
||||
int smux_paths[4];
|
||||
@@ -111,7 +120,7 @@ static void ad198x_power_eapd(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
static int ad198x_suspend(struct hda_codec *codec)
|
||||
static int ad_codec_suspend(struct hda_codec *codec)
|
||||
{
|
||||
snd_hda_shutup_pins(codec);
|
||||
ad198x_power_eapd(codec);
|
||||
@@ -137,7 +146,7 @@ static void ad_vmaster_eapd_hook(void *private_data, int enabled)
|
||||
* Automatic parse of I/O pins from the BIOS configuration
|
||||
*/
|
||||
|
||||
static int ad198x_auto_build_controls(struct hda_codec *codec)
|
||||
static int ad_codec_build_controls(struct hda_codec *codec)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -150,17 +159,6 @@ static int ad198x_auto_build_controls(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hda_codec_ops ad198x_auto_patch_ops = {
|
||||
.build_controls = ad198x_auto_build_controls,
|
||||
.build_pcms = snd_hda_gen_build_pcms,
|
||||
.init = snd_hda_gen_init,
|
||||
.free = snd_hda_gen_free,
|
||||
.unsol_event = snd_hda_jack_unsol_event,
|
||||
.check_power_status = snd_hda_gen_check_power_status,
|
||||
.suspend = ad198x_suspend,
|
||||
};
|
||||
|
||||
|
||||
static int ad198x_parse_auto_config(struct hda_codec *codec, bool indep_hp)
|
||||
{
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
@@ -198,7 +196,6 @@ static int alloc_ad_spec(struct hda_codec *codec)
|
||||
return -ENOMEM;
|
||||
codec->spec = spec;
|
||||
snd_hda_gen_spec_init(&spec->gen);
|
||||
codec->patch_ops = ad198x_auto_patch_ops;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -375,10 +372,10 @@ static const struct hda_model_fixup ad1986a_fixup_models[] = {
|
||||
|
||||
/*
|
||||
*/
|
||||
static int patch_ad1986a(struct hda_codec *codec)
|
||||
static int ad1986a_probe(struct hda_codec *codec)
|
||||
{
|
||||
int err;
|
||||
struct ad198x_spec *spec;
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
static const hda_nid_t preferred_pairs[] = {
|
||||
0x1a, 0x03,
|
||||
0x1b, 0x03,
|
||||
@@ -388,11 +385,6 @@ static int patch_ad1986a(struct hda_codec *codec)
|
||||
0
|
||||
};
|
||||
|
||||
err = alloc_ad_spec(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
spec = codec->spec;
|
||||
|
||||
/* AD1986A has the inverted EAPD implementation */
|
||||
codec->inv_eapd = 1;
|
||||
|
||||
@@ -418,10 +410,8 @@ static int patch_ad1986a(struct hda_codec *codec)
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
|
||||
|
||||
err = ad198x_parse_auto_config(codec, false);
|
||||
if (err < 0) {
|
||||
snd_hda_gen_free(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
|
||||
|
||||
@@ -507,18 +497,13 @@ static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int patch_ad1983(struct hda_codec *codec)
|
||||
static int ad1983_probe(struct hda_codec *codec)
|
||||
{
|
||||
static const hda_nid_t conn_0c[] = { 0x08 };
|
||||
static const hda_nid_t conn_0d[] = { 0x09 };
|
||||
struct ad198x_spec *spec;
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
int err;
|
||||
|
||||
err = alloc_ad_spec(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
spec = codec->spec;
|
||||
|
||||
spec->gen.mixer_nid = 0x0e;
|
||||
spec->gen.beep_nid = 0x10;
|
||||
set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
|
||||
@@ -529,15 +514,11 @@ static int patch_ad1983(struct hda_codec *codec)
|
||||
|
||||
err = ad198x_parse_auto_config(codec, false);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return err;
|
||||
err = ad1983_add_spdif_mux_ctl(codec);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return err;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
snd_hda_gen_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -597,16 +578,11 @@ static const struct hda_quirk ad1981_fixup_tbl[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static int patch_ad1981(struct hda_codec *codec)
|
||||
static int ad1981_probe(struct hda_codec *codec)
|
||||
{
|
||||
struct ad198x_spec *spec;
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
int err;
|
||||
|
||||
err = alloc_ad_spec(codec);
|
||||
if (err < 0)
|
||||
return -ENOMEM;
|
||||
spec = codec->spec;
|
||||
|
||||
spec->gen.mixer_nid = 0x0e;
|
||||
spec->gen.beep_nid = 0x10;
|
||||
set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
|
||||
@@ -616,18 +592,14 @@ static int patch_ad1981(struct hda_codec *codec)
|
||||
|
||||
err = ad198x_parse_auto_config(codec, false);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return err;
|
||||
err = ad1983_add_spdif_mux_ctl(codec);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return err;
|
||||
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
snd_hda_gen_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -776,7 +748,7 @@ static const struct snd_kcontrol_new ad1988_auto_smux_mixer = {
|
||||
.put = ad1988_auto_smux_enum_put,
|
||||
};
|
||||
|
||||
static int ad1988_auto_init(struct hda_codec *codec)
|
||||
static int ad_codec_init(struct hda_codec *codec)
|
||||
{
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
int i, err;
|
||||
@@ -784,6 +756,8 @@ static int ad1988_auto_init(struct hda_codec *codec)
|
||||
err = snd_hda_gen_init(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (spec->model != MODEL_AD1988)
|
||||
return 0;
|
||||
if (!spec->gen.autocfg.dig_outs)
|
||||
return 0;
|
||||
|
||||
@@ -854,8 +828,6 @@ static int ad1988_add_spdif_mux_ctl(struct hda_codec *codec)
|
||||
if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1988_auto_smux_mixer))
|
||||
return -ENOMEM;
|
||||
|
||||
codec->patch_ops.init = ad1988_auto_init;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -889,16 +861,11 @@ static const struct hda_model_fixup ad1988_fixup_models[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static int patch_ad1988(struct hda_codec *codec)
|
||||
static int ad1988_probe(struct hda_codec *codec)
|
||||
{
|
||||
struct ad198x_spec *spec;
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
int err;
|
||||
|
||||
err = alloc_ad_spec(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
spec = codec->spec;
|
||||
|
||||
spec->gen.mixer_nid = 0x20;
|
||||
spec->gen.mixer_merge_nid = 0x21;
|
||||
spec->gen.beep_nid = 0x10;
|
||||
@@ -909,18 +876,14 @@ static int patch_ad1988(struct hda_codec *codec)
|
||||
|
||||
err = ad198x_parse_auto_config(codec, true);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return err;
|
||||
err = ad1988_add_spdif_mux_ctl(codec);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return err;
|
||||
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
snd_hda_gen_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -1069,16 +1032,11 @@ static const struct hda_quirk ad1884_fixup_tbl[] = {
|
||||
};
|
||||
|
||||
|
||||
static int patch_ad1884(struct hda_codec *codec)
|
||||
static int ad1884_probe(struct hda_codec *codec)
|
||||
{
|
||||
struct ad198x_spec *spec;
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
int err;
|
||||
|
||||
err = alloc_ad_spec(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
spec = codec->spec;
|
||||
|
||||
spec->gen.mixer_nid = 0x20;
|
||||
spec->gen.mixer_merge_nid = 0x21;
|
||||
spec->gen.beep_nid = 0x10;
|
||||
@@ -1089,18 +1047,14 @@ static int patch_ad1884(struct hda_codec *codec)
|
||||
|
||||
err = ad198x_parse_auto_config(codec, true);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return err;
|
||||
err = ad1983_add_spdif_mux_ctl(codec);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return err;
|
||||
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
snd_hda_gen_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1115,53 +1069,99 @@ static int patch_ad1884(struct hda_codec *codec)
|
||||
* port-G - rear clfe-out (6stack)
|
||||
*/
|
||||
|
||||
static int patch_ad1882(struct hda_codec *codec)
|
||||
static int ad1882_probe(struct hda_codec *codec)
|
||||
{
|
||||
struct ad198x_spec *spec;
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
int err;
|
||||
|
||||
err = alloc_ad_spec(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
spec = codec->spec;
|
||||
|
||||
spec->gen.mixer_nid = 0x20;
|
||||
spec->gen.mixer_merge_nid = 0x21;
|
||||
spec->gen.beep_nid = 0x10;
|
||||
set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
|
||||
err = ad198x_parse_auto_config(codec, true);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return err;
|
||||
err = ad1988_add_spdif_mux_ctl(codec);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return err;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
snd_hda_gen_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* patch entries
|
||||
* driver entries
|
||||
*/
|
||||
static int ad_codec_probe(struct hda_codec *codec,
|
||||
const struct hda_device_id *id)
|
||||
{
|
||||
struct ad198x_spec *spec;
|
||||
int err;
|
||||
|
||||
err = alloc_ad_spec(codec);
|
||||
if (err < 0)
|
||||
return -ENOMEM;
|
||||
spec = codec->spec;
|
||||
spec->model = id->driver_data;
|
||||
|
||||
switch (spec->model) {
|
||||
case MODEL_AD1882:
|
||||
err = ad1882_probe(codec);
|
||||
break;
|
||||
case MODEL_AD1884:
|
||||
err = ad1884_probe(codec);
|
||||
break;
|
||||
case MODEL_AD1981:
|
||||
err = ad1981_probe(codec);
|
||||
break;
|
||||
case MODEL_AD1983:
|
||||
err = ad1983_probe(codec);
|
||||
break;
|
||||
case MODEL_AD1986A:
|
||||
err = ad1986a_probe(codec);
|
||||
break;
|
||||
case MODEL_AD1988:
|
||||
err = ad1988_probe(codec);
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (err < 0) {
|
||||
snd_hda_gen_remove(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hda_codec_ops ad_codec_ops = {
|
||||
.probe = ad_codec_probe,
|
||||
.remove = snd_hda_gen_remove,
|
||||
.build_controls = ad_codec_build_controls,
|
||||
.build_pcms = snd_hda_gen_build_pcms,
|
||||
.init = ad_codec_init,
|
||||
.unsol_event = snd_hda_jack_unsol_event,
|
||||
.suspend = ad_codec_suspend,
|
||||
.check_power_status = snd_hda_gen_check_power_status,
|
||||
.stream_pm = snd_hda_gen_stream_pm,
|
||||
};
|
||||
|
||||
static const struct hda_device_id snd_hda_id_analog[] = {
|
||||
HDA_CODEC_ENTRY(0x11d4184a, "AD1884A", patch_ad1884),
|
||||
HDA_CODEC_ENTRY(0x11d41882, "AD1882", patch_ad1882),
|
||||
HDA_CODEC_ENTRY(0x11d41883, "AD1883", patch_ad1884),
|
||||
HDA_CODEC_ENTRY(0x11d41884, "AD1884", patch_ad1884),
|
||||
HDA_CODEC_ENTRY(0x11d4194a, "AD1984A", patch_ad1884),
|
||||
HDA_CODEC_ENTRY(0x11d4194b, "AD1984B", patch_ad1884),
|
||||
HDA_CODEC_ENTRY(0x11d41981, "AD1981", patch_ad1981),
|
||||
HDA_CODEC_ENTRY(0x11d41983, "AD1983", patch_ad1983),
|
||||
HDA_CODEC_ENTRY(0x11d41984, "AD1984", patch_ad1884),
|
||||
HDA_CODEC_ENTRY(0x11d41986, "AD1986A", patch_ad1986a),
|
||||
HDA_CODEC_ENTRY(0x11d41988, "AD1988", patch_ad1988),
|
||||
HDA_CODEC_ENTRY(0x11d4198b, "AD1988B", patch_ad1988),
|
||||
HDA_CODEC_ENTRY(0x11d4882a, "AD1882A", patch_ad1882),
|
||||
HDA_CODEC_ENTRY(0x11d4989a, "AD1989A", patch_ad1988),
|
||||
HDA_CODEC_ENTRY(0x11d4989b, "AD1989B", patch_ad1988),
|
||||
HDA_CODEC_ID_MODEL(0x11d4184a, "AD1884A", MODEL_AD1884),
|
||||
HDA_CODEC_ID_MODEL(0x11d41882, "AD1882", MODEL_AD1882),
|
||||
HDA_CODEC_ID_MODEL(0x11d41883, "AD1883", MODEL_AD1884),
|
||||
HDA_CODEC_ID_MODEL(0x11d41884, "AD1884", MODEL_AD1884),
|
||||
HDA_CODEC_ID_MODEL(0x11d4194a, "AD1984A", MODEL_AD1884),
|
||||
HDA_CODEC_ID_MODEL(0x11d4194b, "AD1984B", MODEL_AD1884),
|
||||
HDA_CODEC_ID_MODEL(0x11d41981, "AD1981", MODEL_AD1981),
|
||||
HDA_CODEC_ID_MODEL(0x11d41983, "AD1983", MODEL_AD1983),
|
||||
HDA_CODEC_ID_MODEL(0x11d41984, "AD1984", MODEL_AD1884),
|
||||
HDA_CODEC_ID_MODEL(0x11d41986, "AD1986A", MODEL_AD1986A),
|
||||
HDA_CODEC_ID_MODEL(0x11d41988, "AD1988", MODEL_AD1988),
|
||||
HDA_CODEC_ID_MODEL(0x11d4198b, "AD1988B", MODEL_AD1988),
|
||||
HDA_CODEC_ID_MODEL(0x11d4882a, "AD1882A", MODEL_AD1882),
|
||||
HDA_CODEC_ID_MODEL(0x11d4989a, "AD1989A", MODEL_AD1988),
|
||||
HDA_CODEC_ID_MODEL(0x11d4989b, "AD1989B", MODEL_AD1988),
|
||||
{} /* terminator */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_analog);
|
||||
@@ -1171,6 +1171,7 @@ MODULE_DESCRIPTION("Analog Devices HD-audio codec");
|
||||
|
||||
static struct hda_codec_driver analog_driver = {
|
||||
.id = snd_hda_id_analog,
|
||||
.ops = &ad_codec_ops,
|
||||
};
|
||||
|
||||
module_hda_codec_driver(analog_driver);
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* HD audio interface patch for Creative X-Fi CA0110-IBG chip
|
||||
* HD audio codec driver for Creative X-Fi CA0110-IBG chip
|
||||
*
|
||||
* Copyright (c) 2008 Takashi Iwai <tiwai@suse.de>
|
||||
*/
|
||||
@@ -13,16 +13,7 @@
|
||||
#include "hda_local.h"
|
||||
#include "hda_auto_parser.h"
|
||||
#include "hda_jack.h"
|
||||
#include "hda_generic.h"
|
||||
|
||||
|
||||
static const struct hda_codec_ops ca0110_patch_ops = {
|
||||
.build_controls = snd_hda_gen_build_controls,
|
||||
.build_pcms = snd_hda_gen_build_pcms,
|
||||
.init = snd_hda_gen_init,
|
||||
.free = snd_hda_gen_free,
|
||||
.unsol_event = snd_hda_jack_unsol_event,
|
||||
};
|
||||
#include "generic.h"
|
||||
|
||||
static int ca0110_parse_auto_config(struct hda_codec *codec)
|
||||
{
|
||||
@@ -39,8 +30,7 @@ static int ca0110_parse_auto_config(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int patch_ca0110(struct hda_codec *codec)
|
||||
static int ca0110_probe(struct hda_codec *codec, const struct hda_device_id *id)
|
||||
{
|
||||
struct hda_gen_spec *spec;
|
||||
int err;
|
||||
@@ -50,7 +40,6 @@ static int patch_ca0110(struct hda_codec *codec)
|
||||
return -ENOMEM;
|
||||
snd_hda_gen_spec_init(spec);
|
||||
codec->spec = spec;
|
||||
codec->patch_ops = ca0110_patch_ops;
|
||||
|
||||
spec->multi_cap_vol = 1;
|
||||
codec->bus->core.needs_damn_long_delay = 1;
|
||||
@@ -62,18 +51,27 @@ static int patch_ca0110(struct hda_codec *codec)
|
||||
return 0;
|
||||
|
||||
error:
|
||||
snd_hda_gen_free(codec);
|
||||
snd_hda_gen_remove(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static const struct hda_codec_ops ca0110_codec_ops = {
|
||||
.probe = ca0110_probe,
|
||||
.remove = snd_hda_gen_remove,
|
||||
.build_controls = snd_hda_gen_build_controls,
|
||||
.build_pcms = snd_hda_gen_build_pcms,
|
||||
.init = snd_hda_gen_init,
|
||||
.unsol_event = snd_hda_jack_unsol_event,
|
||||
};
|
||||
|
||||
/*
|
||||
* patch entries
|
||||
* driver entries
|
||||
*/
|
||||
static const struct hda_device_id snd_hda_id_ca0110[] = {
|
||||
HDA_CODEC_ENTRY(0x1102000a, "CA0110-IBG", patch_ca0110),
|
||||
HDA_CODEC_ENTRY(0x1102000b, "CA0110-IBG", patch_ca0110),
|
||||
HDA_CODEC_ENTRY(0x1102000d, "SB0880 X-Fi", patch_ca0110),
|
||||
HDA_CODEC_ID(0x1102000a, "CA0110-IBG"),
|
||||
HDA_CODEC_ID(0x1102000b, "CA0110-IBG"),
|
||||
HDA_CODEC_ID(0x1102000d, "SB0880 X-Fi"),
|
||||
{} /* terminator */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_ca0110);
|
||||
@@ -83,6 +81,7 @@ MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec");
|
||||
|
||||
static struct hda_codec_driver ca0110_driver = {
|
||||
.id = snd_hda_id_ca0110,
|
||||
.ops = &ca0110_codec_ops,
|
||||
};
|
||||
|
||||
module_hda_codec_driver(ca0110_driver);
|
||||
@@ -1,10 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* HD audio interface patch for Creative CA0132 chip
|
||||
* HD audio codec driver for Creative CA0132 chip
|
||||
*
|
||||
* Copyright (c) 2011, Creative Technology Ltd.
|
||||
*
|
||||
* Based on patch_ca0110.c
|
||||
* Based on ca0110.c
|
||||
* Copyright (c) 2008 Takashi Iwai <tiwai@suse.de>
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "ca0132_regs.h"
|
||||
|
||||
/* Enable this to see controls for tuning purpose. */
|
||||
/*#define ENABLE_TUNING_CONTROLS*/
|
||||
#define ENABLE_TUNING_CONTROLS
|
||||
|
||||
#ifdef ENABLE_TUNING_CONTROLS
|
||||
#include <sound/tlv.h>
|
||||
@@ -174,7 +174,7 @@ static const unsigned int effect_slider_defaults[] = {67, 65, 50, 74, 50};
|
||||
#define DSP_SPEAKER_OUT_LATENCY 7
|
||||
|
||||
struct ct_effect {
|
||||
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
const char *name;
|
||||
hda_nid_t nid;
|
||||
int mid; /*effect module ID*/
|
||||
int reqs[EFFECT_VALS_MAX_COUNT]; /*effect module request*/
|
||||
@@ -305,7 +305,7 @@ enum {
|
||||
};
|
||||
|
||||
struct ct_tuning_ctl {
|
||||
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
const char *name;
|
||||
hda_nid_t parent_nid;
|
||||
hda_nid_t nid;
|
||||
int mid; /*effect module ID*/
|
||||
@@ -418,14 +418,14 @@ static const struct ct_tuning_ctl ca0132_tuning_ctls[] = {
|
||||
#define VOICEFX_MAX_PARAM_COUNT 9
|
||||
|
||||
struct ct_voicefx {
|
||||
char *name;
|
||||
const char *name;
|
||||
hda_nid_t nid;
|
||||
int mid;
|
||||
int reqs[VOICEFX_MAX_PARAM_COUNT]; /*effect module request*/
|
||||
};
|
||||
|
||||
struct ct_voicefx_preset {
|
||||
char *name; /*preset name*/
|
||||
const char *name; /*preset name*/
|
||||
unsigned int vals[VOICEFX_MAX_PARAM_COUNT];
|
||||
};
|
||||
|
||||
@@ -514,14 +514,14 @@ static const struct ct_voicefx_preset ca0132_voicefx_presets[] = {
|
||||
#define EQ_PRESET_MAX_PARAM_COUNT 11
|
||||
|
||||
struct ct_eq {
|
||||
char *name;
|
||||
const char *name;
|
||||
hda_nid_t nid;
|
||||
int mid;
|
||||
int reqs[EQ_PRESET_MAX_PARAM_COUNT]; /*effect module request*/
|
||||
};
|
||||
|
||||
struct ct_eq_preset {
|
||||
char *name; /*preset name*/
|
||||
const char *name; /*preset name*/
|
||||
unsigned int vals[EQ_PRESET_MAX_PARAM_COUNT];
|
||||
};
|
||||
|
||||
@@ -679,7 +679,7 @@ enum {
|
||||
};
|
||||
|
||||
struct ca0132_alt_speaker_channel_cfg {
|
||||
char *name;
|
||||
const char *name;
|
||||
unsigned int val;
|
||||
};
|
||||
|
||||
@@ -755,7 +755,7 @@ static const struct ae_ca0113_output_set ae7_ca0113_output_presets = {
|
||||
/* ae5 ca0113 command sequences to set headphone gain levels. */
|
||||
#define AE5_HEADPHONE_GAIN_PRESET_MAX_COMMANDS 4
|
||||
struct ae5_headphone_gain_set {
|
||||
char *name;
|
||||
const char *name;
|
||||
unsigned int vals[AE5_HEADPHONE_GAIN_PRESET_MAX_COMMANDS];
|
||||
};
|
||||
|
||||
@@ -772,7 +772,7 @@ static const struct ae5_headphone_gain_set ae5_headphone_gain_presets[] = {
|
||||
};
|
||||
|
||||
struct ae5_filter_set {
|
||||
char *name;
|
||||
const char *name;
|
||||
unsigned int val;
|
||||
};
|
||||
|
||||
@@ -4385,8 +4385,8 @@ static int add_tuning_control(struct hda_codec *codec,
|
||||
|
||||
knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
|
||||
SNDRV_CTL_ELEM_ACCESS_TLV_READ;
|
||||
knew.tlv.c = 0;
|
||||
knew.tlv.p = 0;
|
||||
knew.tlv.c = NULL;
|
||||
knew.tlv.p = NULL;
|
||||
switch (pnid) {
|
||||
case VOICE_FOCUS:
|
||||
knew.info = voice_focus_ctl_info;
|
||||
@@ -4410,7 +4410,7 @@ static int add_tuning_control(struct hda_codec *codec,
|
||||
}
|
||||
knew.private_value =
|
||||
HDA_COMPOSE_AMP_VAL(nid, 1, 0, type);
|
||||
sprintf(namestr, "%s %s Volume", name, dirstr[dir]);
|
||||
snprintf(namestr, sizeof(namestr), "%s %s Volume", name, dirstr[dir]);
|
||||
return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
|
||||
}
|
||||
|
||||
@@ -5787,7 +5787,7 @@ static int ca0132_alt_effect_slider_put(struct snd_kcontrol *kcontrol,
|
||||
static int ca0132_alt_mic_boost_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
char *sfx = "dB";
|
||||
const char *sfx = "dB";
|
||||
char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
|
||||
@@ -5796,7 +5796,7 @@ static int ca0132_alt_mic_boost_info(struct snd_kcontrol *kcontrol,
|
||||
if (uinfo->value.enumerated.item >= MIC_BOOST_NUM_OF_STEPS)
|
||||
uinfo->value.enumerated.item = MIC_BOOST_NUM_OF_STEPS - 1;
|
||||
sprintf(namestr, "%d %s", (uinfo->value.enumerated.item * 10), sfx);
|
||||
strcpy(uinfo->value.enumerated.name, namestr);
|
||||
strscpy(uinfo->value.enumerated.name, namestr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5839,7 +5839,7 @@ static int ca0132_alt_mic_boost_put(struct snd_kcontrol *kcontrol,
|
||||
static int ae5_headphone_gain_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
char *sfx = " Ohms)";
|
||||
const char *sfx = " Ohms)";
|
||||
char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
|
||||
@@ -5850,7 +5850,7 @@ static int ae5_headphone_gain_info(struct snd_kcontrol *kcontrol,
|
||||
sprintf(namestr, "%s %s",
|
||||
ae5_headphone_gain_presets[uinfo->value.enumerated.item].name,
|
||||
sfx);
|
||||
strcpy(uinfo->value.enumerated.name, namestr);
|
||||
strscpy(uinfo->value.enumerated.name, namestr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5903,7 +5903,7 @@ static int ae5_sound_filter_info(struct snd_kcontrol *kcontrol,
|
||||
uinfo->value.enumerated.item = AE5_SOUND_FILTER_MAX - 1;
|
||||
sprintf(namestr, "%s",
|
||||
ae5_filter_presets[uinfo->value.enumerated.item].name);
|
||||
strcpy(uinfo->value.enumerated.name, namestr);
|
||||
strscpy(uinfo->value.enumerated.name, namestr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5952,7 +5952,7 @@ static int ca0132_alt_input_source_info(struct snd_kcontrol *kcontrol,
|
||||
uinfo->value.enumerated.items = IN_SRC_NUM_OF_INPUTS;
|
||||
if (uinfo->value.enumerated.item >= IN_SRC_NUM_OF_INPUTS)
|
||||
uinfo->value.enumerated.item = IN_SRC_NUM_OF_INPUTS - 1;
|
||||
strcpy(uinfo->value.enumerated.name,
|
||||
strscpy(uinfo->value.enumerated.name,
|
||||
in_src_str[uinfo->value.enumerated.item]);
|
||||
return 0;
|
||||
}
|
||||
@@ -6004,7 +6004,7 @@ static int ca0132_alt_output_select_get_info(struct snd_kcontrol *kcontrol,
|
||||
uinfo->value.enumerated.items = NUM_OF_OUTPUTS;
|
||||
if (uinfo->value.enumerated.item >= NUM_OF_OUTPUTS)
|
||||
uinfo->value.enumerated.item = NUM_OF_OUTPUTS - 1;
|
||||
strcpy(uinfo->value.enumerated.name,
|
||||
strscpy(uinfo->value.enumerated.name,
|
||||
out_type_str[uinfo->value.enumerated.item]);
|
||||
return 0;
|
||||
}
|
||||
@@ -6055,7 +6055,7 @@ static int ca0132_alt_speaker_channel_cfg_get_info(struct snd_kcontrol *kcontrol
|
||||
uinfo->value.enumerated.items = items;
|
||||
if (uinfo->value.enumerated.item >= items)
|
||||
uinfo->value.enumerated.item = items - 1;
|
||||
strcpy(uinfo->value.enumerated.name,
|
||||
strscpy(uinfo->value.enumerated.name,
|
||||
speaker_channel_cfgs[uinfo->value.enumerated.item].name);
|
||||
return 0;
|
||||
}
|
||||
@@ -6108,7 +6108,7 @@ static int ca0132_alt_svm_setting_info(struct snd_kcontrol *kcontrol,
|
||||
uinfo->value.enumerated.items = NUM_OF_SVM_SETTINGS;
|
||||
if (uinfo->value.enumerated.item >= NUM_OF_SVM_SETTINGS)
|
||||
uinfo->value.enumerated.item = NUM_OF_SVM_SETTINGS - 1;
|
||||
strcpy(uinfo->value.enumerated.name,
|
||||
strscpy(uinfo->value.enumerated.name,
|
||||
out_svm_set_enum_str[uinfo->value.enumerated.item]);
|
||||
return 0;
|
||||
}
|
||||
@@ -6172,7 +6172,7 @@ static int ca0132_alt_eq_preset_info(struct snd_kcontrol *kcontrol,
|
||||
uinfo->value.enumerated.items = items;
|
||||
if (uinfo->value.enumerated.item >= items)
|
||||
uinfo->value.enumerated.item = items - 1;
|
||||
strcpy(uinfo->value.enumerated.name,
|
||||
strscpy(uinfo->value.enumerated.name,
|
||||
ca0132_alt_eq_presets[uinfo->value.enumerated.item].name);
|
||||
return 0;
|
||||
}
|
||||
@@ -6229,7 +6229,7 @@ static int ca0132_voicefx_info(struct snd_kcontrol *kcontrol,
|
||||
uinfo->value.enumerated.items = items;
|
||||
if (uinfo->value.enumerated.item >= items)
|
||||
uinfo->value.enumerated.item = items - 1;
|
||||
strcpy(uinfo->value.enumerated.name,
|
||||
strscpy(uinfo->value.enumerated.name,
|
||||
ca0132_voicefx_presets[uinfo->value.enumerated.item].name);
|
||||
return 0;
|
||||
}
|
||||
@@ -9118,7 +9118,7 @@ static void sbz_dsp_startup_check(struct hda_codec *codec)
|
||||
codec_info(codec, "Reloading... Tries left: %d", reload);
|
||||
sbz_exit_chip(codec);
|
||||
spec->dsp_state = DSP_DOWNLOAD_INIT;
|
||||
codec->patch_ops.init(codec);
|
||||
snd_hda_codec_init(codec);
|
||||
failure = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
chipio_read(codec, cur_address, &dsp_data_check[i]);
|
||||
@@ -9694,30 +9694,6 @@ static void dbpro_free(struct hda_codec *codec)
|
||||
kfree(codec->spec);
|
||||
}
|
||||
|
||||
static int ca0132_suspend(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
|
||||
cancel_delayed_work_sync(&spec->unsol_hp_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hda_codec_ops ca0132_patch_ops = {
|
||||
.build_controls = ca0132_build_controls,
|
||||
.build_pcms = ca0132_build_pcms,
|
||||
.init = ca0132_init,
|
||||
.free = ca0132_free,
|
||||
.unsol_event = snd_hda_jack_unsol_event,
|
||||
.suspend = ca0132_suspend,
|
||||
};
|
||||
|
||||
static const struct hda_codec_ops dbpro_patch_ops = {
|
||||
.build_controls = dbpro_build_controls,
|
||||
.build_pcms = dbpro_build_pcms,
|
||||
.init = dbpro_init,
|
||||
.free = dbpro_free,
|
||||
};
|
||||
|
||||
static void ca0132_config(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
@@ -9982,12 +9958,23 @@ static void sbz_detect_quirk(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
static int patch_ca0132(struct hda_codec *codec)
|
||||
static void ca0132_codec_remove(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
|
||||
if (ca0132_quirk(spec) == QUIRK_ZXR_DBPRO)
|
||||
return dbpro_free(codec);
|
||||
else
|
||||
return ca0132_free(codec);
|
||||
}
|
||||
|
||||
static int ca0132_codec_probe(struct hda_codec *codec,
|
||||
const struct hda_device_id *id)
|
||||
{
|
||||
struct ca0132_spec *spec;
|
||||
int err;
|
||||
|
||||
codec_dbg(codec, "patch_ca0132\n");
|
||||
codec_dbg(codec, "%s\n", __func__);
|
||||
|
||||
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
||||
if (!spec)
|
||||
@@ -10000,11 +9987,6 @@ static int patch_ca0132(struct hda_codec *codec)
|
||||
if (ca0132_quirk(spec) == QUIRK_SBZ)
|
||||
sbz_detect_quirk(codec);
|
||||
|
||||
if (ca0132_quirk(spec) == QUIRK_ZXR_DBPRO)
|
||||
codec->patch_ops = dbpro_patch_ops;
|
||||
else
|
||||
codec->patch_ops = ca0132_patch_ops;
|
||||
|
||||
codec->pcm_format_first = 1;
|
||||
codec->no_sticky_stream = 1;
|
||||
|
||||
@@ -10100,15 +10082,63 @@ static int patch_ca0132(struct hda_codec *codec)
|
||||
return 0;
|
||||
|
||||
error:
|
||||
ca0132_free(codec);
|
||||
ca0132_codec_remove(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ca0132_codec_build_controls(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
|
||||
if (ca0132_quirk(spec) == QUIRK_ZXR_DBPRO)
|
||||
return dbpro_build_controls(codec);
|
||||
else
|
||||
return ca0132_build_controls(codec);
|
||||
}
|
||||
|
||||
static int ca0132_codec_build_pcms(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
|
||||
if (ca0132_quirk(spec) == QUIRK_ZXR_DBPRO)
|
||||
return dbpro_build_pcms(codec);
|
||||
else
|
||||
return ca0132_build_pcms(codec);
|
||||
}
|
||||
|
||||
static int ca0132_codec_init(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
|
||||
if (ca0132_quirk(spec) == QUIRK_ZXR_DBPRO)
|
||||
return dbpro_init(codec);
|
||||
else
|
||||
return ca0132_init(codec);
|
||||
}
|
||||
|
||||
static int ca0132_codec_suspend(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
|
||||
cancel_delayed_work_sync(&spec->unsol_hp_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hda_codec_ops ca0132_codec_ops = {
|
||||
.probe = ca0132_codec_probe,
|
||||
.remove = ca0132_codec_remove,
|
||||
.build_controls = ca0132_codec_build_controls,
|
||||
.build_pcms = ca0132_codec_build_pcms,
|
||||
.init = ca0132_codec_init,
|
||||
.unsol_event = snd_hda_jack_unsol_event,
|
||||
.suspend = ca0132_codec_suspend,
|
||||
};
|
||||
|
||||
/*
|
||||
* patch entries
|
||||
* driver entries
|
||||
*/
|
||||
static const struct hda_device_id snd_hda_id_ca0132[] = {
|
||||
HDA_CODEC_ENTRY(0x11020011, "CA0132", patch_ca0132),
|
||||
HDA_CODEC_ID(0x11020011, "CA0132"),
|
||||
{} /* terminator */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_ca0132);
|
||||
@@ -10118,6 +10148,7 @@ MODULE_DESCRIPTION("Creative Sound Core3D codec");
|
||||
|
||||
static struct hda_codec_driver ca0132_driver = {
|
||||
.id = snd_hda_id_ca0132,
|
||||
.ops = &ca0132_codec_ops,
|
||||
};
|
||||
|
||||
module_hda_codec_driver(ca0132_driver);
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* HD audio interface patch for Creative CA0132 chip.
|
||||
* HD audio codec driver for Creative CA0132 chip.
|
||||
* CA0132 registers defines.
|
||||
*
|
||||
* Copyright (c) 2011, Creative Technology Ltd.
|
||||
@@ -0,0 +1,31 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
config SND_HDA_CODEC_CS420X
|
||||
tristate "Build Cirrus Logic CS420x codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y or M here to include Cirrus Logic CS420x codec support in
|
||||
snd-hda-intel driver
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_CS420X=m
|
||||
|
||||
config SND_HDA_CODEC_CS421X
|
||||
tristate "Build Cirrus Logic CS421x codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y or M here to include Cirrus Logic CS421x codec support in
|
||||
snd-hda-intel driver
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_CS421X=m
|
||||
|
||||
config SND_HDA_CODEC_CS8409
|
||||
tristate "Build Cirrus Logic HDA bridge support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y or M here to include Cirrus Logic HDA bridge support in
|
||||
snd-hda-intel driver, such as CS8409.
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA=y && SND_HDA_CODEC_CS8409=m
|
||||
@@ -0,0 +1,10 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
subdir-ccflags-y += -I$(src)/../../common
|
||||
|
||||
snd-hda-codec-cs420x-y := cs420x.o
|
||||
snd-hda-codec-cs421x-y := cs421x.o
|
||||
snd-hda-codec-cs8409-y := cs8409.o cs8409-tables.o
|
||||
|
||||
obj-$(CONFIG_SND_HDA_CODEC_CS420X) += snd-hda-codec-cs420x.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_CS421X) += snd-hda-codec-cs421x.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_CS8409) += snd-hda-codec-cs8409.o
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* HD audio interface patch for Cirrus Logic CS420x chip
|
||||
* Cirrus Logic CS420x HD-audio codec
|
||||
*
|
||||
* Copyright (c) 2009 Takashi Iwai <tiwai@suse.de>
|
||||
*/
|
||||
@@ -15,10 +15,7 @@
|
||||
#include "hda_local.h"
|
||||
#include "hda_auto_parser.h"
|
||||
#include "hda_jack.h"
|
||||
#include "hda_generic.h"
|
||||
|
||||
/*
|
||||
*/
|
||||
#include "../generic.h"
|
||||
|
||||
struct cs_spec {
|
||||
struct hda_gen_spec gen;
|
||||
@@ -29,10 +26,6 @@ struct cs_spec {
|
||||
unsigned int gpio_eapd_hp; /* EAPD GPIO bit for headphones */
|
||||
unsigned int gpio_eapd_speaker; /* EAPD GPIO bit for speakers */
|
||||
|
||||
/* CS421x */
|
||||
unsigned int spdif_detect:1;
|
||||
unsigned int spdif_present:1;
|
||||
unsigned int sense_b:1;
|
||||
hda_nid_t vendor_nid;
|
||||
|
||||
/* for MBP SPDIF control */
|
||||
@@ -56,13 +49,6 @@ enum {
|
||||
CS420X_APPLE = CS420X_GPIO_13,
|
||||
};
|
||||
|
||||
/* CS421x boards */
|
||||
enum {
|
||||
CS421X_CDB4210,
|
||||
CS421X_SENSE_B,
|
||||
CS421X_STUMPY,
|
||||
};
|
||||
|
||||
/* Vendor-specific processing widget */
|
||||
#define CS420X_VENDOR_NID 0x11
|
||||
#define CS_DIG_OUT1_PIN_NID 0x10
|
||||
@@ -105,28 +91,6 @@ enum {
|
||||
/* Cirrus Logic CS4208 */
|
||||
#define CS4208_VENDOR_NID 0x24
|
||||
|
||||
/*
|
||||
* Cirrus Logic CS4210
|
||||
*
|
||||
* 1 DAC => HP(sense) / Speakers,
|
||||
* 1 ADC <= LineIn(sense) / MicIn / DMicIn,
|
||||
* 1 SPDIF OUT => SPDIF Trasmitter(sense)
|
||||
*/
|
||||
#define CS4210_DAC_NID 0x02
|
||||
#define CS4210_ADC_NID 0x03
|
||||
#define CS4210_VENDOR_NID 0x0B
|
||||
#define CS421X_DMIC_PIN_NID 0x09 /* Port E */
|
||||
#define CS421X_SPDIF_PIN_NID 0x0A /* Port H */
|
||||
|
||||
#define CS421X_IDX_DEV_CFG 0x01
|
||||
#define CS421X_IDX_ADC_CFG 0x02
|
||||
#define CS421X_IDX_DAC_CFG 0x03
|
||||
#define CS421X_IDX_SPK_CTL 0x04
|
||||
|
||||
/* Cirrus Logic CS4213 is like CS4210 but does not have SPDIF input/output */
|
||||
#define CS4213_VENDOR_NID 0x09
|
||||
|
||||
|
||||
static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
|
||||
{
|
||||
struct cs_spec *spec = codec->spec;
|
||||
@@ -158,9 +122,6 @@ static void cs_automute(struct hda_codec *codec)
|
||||
{
|
||||
struct cs_spec *spec = codec->spec;
|
||||
|
||||
/* mute HPs if spdif jack (SENSE_B) is present */
|
||||
spec->gen.master_mute = !!(spec->spdif_present && spec->sense_b);
|
||||
|
||||
snd_hda_gen_update_outputs(codec);
|
||||
|
||||
if (spec->gpio_eapd_hp || spec->gpio_eapd_speaker) {
|
||||
@@ -331,16 +292,6 @@ static int cs_build_controls(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define cs_free snd_hda_gen_free
|
||||
|
||||
static const struct hda_codec_ops cs_patch_ops = {
|
||||
.build_controls = cs_build_controls,
|
||||
.build_pcms = snd_hda_gen_build_pcms,
|
||||
.init = cs_init,
|
||||
.free = cs_free,
|
||||
.unsol_event = snd_hda_jack_unsol_event,
|
||||
};
|
||||
|
||||
static int cs_parse_auto_config(struct hda_codec *codec)
|
||||
{
|
||||
struct cs_spec *spec = codec->spec;
|
||||
@@ -584,17 +535,10 @@ static struct cs_spec *cs_alloc_spec(struct hda_codec *codec, int vendor_nid)
|
||||
return spec;
|
||||
}
|
||||
|
||||
static int patch_cs420x(struct hda_codec *codec)
|
||||
static int cs420x_probe(struct hda_codec *codec)
|
||||
{
|
||||
struct cs_spec *spec;
|
||||
int err;
|
||||
|
||||
spec = cs_alloc_spec(codec, CS420X_VENDOR_NID);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
|
||||
codec->patch_ops = cs_patch_ops;
|
||||
spec->gen.automute_hook = cs_automute;
|
||||
codec->single_adc_amp = 1;
|
||||
|
||||
snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl,
|
||||
@@ -603,15 +547,11 @@ static int patch_cs420x(struct hda_codec *codec)
|
||||
|
||||
err = cs_parse_auto_config(codec);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return err;
|
||||
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
cs_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -766,17 +706,11 @@ static void cs4208_fix_amp_caps(struct hda_codec *codec, hda_nid_t adc)
|
||||
snd_hda_override_amp_caps(codec, adc, HDA_INPUT, caps);
|
||||
}
|
||||
|
||||
static int patch_cs4208(struct hda_codec *codec)
|
||||
static int cs4208_probe(struct hda_codec *codec)
|
||||
{
|
||||
struct cs_spec *spec;
|
||||
struct cs_spec *spec = codec->spec;
|
||||
int err;
|
||||
|
||||
spec = cs_alloc_spec(codec, CS4208_VENDOR_NID);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
|
||||
codec->patch_ops = cs_patch_ops;
|
||||
spec->gen.automute_hook = cs_automute;
|
||||
/* exclude NID 0x10 (HP) from output volumes due to different steps */
|
||||
spec->gen.out_vol_mask = 1ULL << 0x10;
|
||||
|
||||
@@ -792,452 +726,60 @@ static int patch_cs4208(struct hda_codec *codec)
|
||||
|
||||
err = cs_parse_auto_config(codec);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
return err;
|
||||
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
cs_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cirrus Logic CS4210
|
||||
*
|
||||
* 1 DAC => HP(sense) / Speakers,
|
||||
* 1 ADC <= LineIn(sense) / MicIn / DMicIn,
|
||||
* 1 SPDIF OUT => SPDIF Trasmitter(sense)
|
||||
*/
|
||||
|
||||
/* CS4210 board names */
|
||||
static const struct hda_model_fixup cs421x_models[] = {
|
||||
{ .id = CS421X_CDB4210, .name = "cdb4210" },
|
||||
{ .id = CS421X_STUMPY, .name = "stumpy" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct hda_quirk cs421x_fixup_tbl[] = {
|
||||
/* Test Intel board + CDB2410 */
|
||||
SND_PCI_QUIRK(0x8086, 0x5001, "DP45SG/CDB4210", CS421X_CDB4210),
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
/* CS4210 board pinconfigs */
|
||||
/* Default CS4210 (CDB4210)*/
|
||||
static const struct hda_pintbl cdb4210_pincfgs[] = {
|
||||
{ 0x05, 0x0321401f },
|
||||
{ 0x06, 0x90170010 },
|
||||
{ 0x07, 0x03813031 },
|
||||
{ 0x08, 0xb7a70037 },
|
||||
{ 0x09, 0xb7a6003e },
|
||||
{ 0x0a, 0x034510f0 },
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
/* Stumpy ChromeBox */
|
||||
static const struct hda_pintbl stumpy_pincfgs[] = {
|
||||
{ 0x05, 0x022120f0 },
|
||||
{ 0x06, 0x901700f0 },
|
||||
{ 0x07, 0x02a120f0 },
|
||||
{ 0x08, 0x77a70037 },
|
||||
{ 0x09, 0x77a6003e },
|
||||
{ 0x0a, 0x434510f0 },
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
/* Setup GPIO/SENSE for each board (if used) */
|
||||
static void cs421x_fixup_sense_b(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
struct cs_spec *spec = codec->spec;
|
||||
|
||||
if (action == HDA_FIXUP_ACT_PRE_PROBE)
|
||||
spec->sense_b = 1;
|
||||
}
|
||||
|
||||
static const struct hda_fixup cs421x_fixups[] = {
|
||||
[CS421X_CDB4210] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = cdb4210_pincfgs,
|
||||
.chained = true,
|
||||
.chain_id = CS421X_SENSE_B,
|
||||
},
|
||||
[CS421X_SENSE_B] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = cs421x_fixup_sense_b,
|
||||
},
|
||||
[CS421X_STUMPY] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = stumpy_pincfgs,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hda_verb cs421x_coef_init_verbs[] = {
|
||||
{0x0B, AC_VERB_SET_PROC_STATE, 1},
|
||||
{0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DEV_CFG},
|
||||
/*
|
||||
* Disable Coefficient Index Auto-Increment(DAI)=1,
|
||||
* PDREF=0
|
||||
*/
|
||||
{0x0B, AC_VERB_SET_PROC_COEF, 0x0001 },
|
||||
|
||||
{0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_ADC_CFG},
|
||||
/* ADC SZCMode = Digital Soft Ramp */
|
||||
{0x0B, AC_VERB_SET_PROC_COEF, 0x0002 },
|
||||
|
||||
{0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DAC_CFG},
|
||||
{0x0B, AC_VERB_SET_PROC_COEF,
|
||||
(0x0002 /* DAC SZCMode = Digital Soft Ramp */
|
||||
| 0x0004 /* Mute DAC on FIFO error */
|
||||
| 0x0008 /* Enable DAC High Pass Filter */
|
||||
)},
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
/* Errata: CS4210 rev A1 Silicon
|
||||
*
|
||||
* http://www.cirrus.com/en/pubs/errata/
|
||||
*
|
||||
* Description:
|
||||
* 1. Performance degredation is present in the ADC.
|
||||
* 2. Speaker output is not completely muted upon HP detect.
|
||||
* 3. Noise is present when clipping occurs on the amplified
|
||||
* speaker outputs.
|
||||
*
|
||||
* Workaround:
|
||||
* The following verb sequence written to the registers during
|
||||
* initialization will correct the issues listed above.
|
||||
*/
|
||||
|
||||
static const struct hda_verb cs421x_coef_init_verbs_A1_silicon_fixes[] = {
|
||||
{0x0B, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */
|
||||
|
||||
{0x0B, AC_VERB_SET_COEF_INDEX, 0x0006},
|
||||
{0x0B, AC_VERB_SET_PROC_COEF, 0x9999}, /* Test mode: on */
|
||||
|
||||
{0x0B, AC_VERB_SET_COEF_INDEX, 0x000A},
|
||||
{0x0B, AC_VERB_SET_PROC_COEF, 0x14CB}, /* Chop double */
|
||||
|
||||
{0x0B, AC_VERB_SET_COEF_INDEX, 0x0011},
|
||||
{0x0B, AC_VERB_SET_PROC_COEF, 0xA2D0}, /* Increase ADC current */
|
||||
|
||||
{0x0B, AC_VERB_SET_COEF_INDEX, 0x001A},
|
||||
{0x0B, AC_VERB_SET_PROC_COEF, 0x02A9}, /* Mute speaker */
|
||||
|
||||
{0x0B, AC_VERB_SET_COEF_INDEX, 0x001B},
|
||||
{0x0B, AC_VERB_SET_PROC_COEF, 0X1006}, /* Remove noise */
|
||||
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
/* Speaker Amp Gain is controlled by the vendor widget's coef 4 */
|
||||
static const DECLARE_TLV_DB_SCALE(cs421x_speaker_boost_db_scale, 900, 300, 0);
|
||||
|
||||
static int cs421x_boost_vol_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.integer.min = 0;
|
||||
uinfo->value.integer.max = 3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs421x_boost_vol_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
ucontrol->value.integer.value[0] =
|
||||
cs_vendor_coef_get(codec, CS421X_IDX_SPK_CTL) & 0x0003;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs421x_boost_vol_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
unsigned int vol = ucontrol->value.integer.value[0];
|
||||
unsigned int coef =
|
||||
cs_vendor_coef_get(codec, CS421X_IDX_SPK_CTL);
|
||||
unsigned int original_coef = coef;
|
||||
|
||||
coef &= ~0x0003;
|
||||
coef |= (vol & 0x0003);
|
||||
if (original_coef != coef) {
|
||||
cs_vendor_coef_set(codec, CS421X_IDX_SPK_CTL, coef);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new cs421x_speaker_boost_ctl = {
|
||||
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
|
||||
SNDRV_CTL_ELEM_ACCESS_TLV_READ),
|
||||
.name = "Speaker Boost Playback Volume",
|
||||
.info = cs421x_boost_vol_info,
|
||||
.get = cs421x_boost_vol_get,
|
||||
.put = cs421x_boost_vol_put,
|
||||
.tlv = { .p = cs421x_speaker_boost_db_scale },
|
||||
};
|
||||
|
||||
static void cs4210_pinmux_init(struct hda_codec *codec)
|
||||
{
|
||||
struct cs_spec *spec = codec->spec;
|
||||
unsigned int def_conf, coef;
|
||||
|
||||
/* GPIO, DMIC_SCL, DMIC_SDA and SENSE_B are multiplexed */
|
||||
coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
|
||||
|
||||
if (spec->gpio_mask)
|
||||
coef |= 0x0008; /* B1,B2 are GPIOs */
|
||||
else
|
||||
coef &= ~0x0008;
|
||||
|
||||
if (spec->sense_b)
|
||||
coef |= 0x0010; /* B2 is SENSE_B, not inverted */
|
||||
else
|
||||
coef &= ~0x0010;
|
||||
|
||||
cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
|
||||
|
||||
if ((spec->gpio_mask || spec->sense_b) &&
|
||||
is_active_pin(codec, CS421X_DMIC_PIN_NID)) {
|
||||
|
||||
/*
|
||||
* GPIO or SENSE_B forced - disconnect the DMIC pin.
|
||||
*/
|
||||
def_conf = snd_hda_codec_get_pincfg(codec, CS421X_DMIC_PIN_NID);
|
||||
def_conf &= ~AC_DEFCFG_PORT_CONN;
|
||||
def_conf |= (AC_JACK_PORT_NONE << AC_DEFCFG_PORT_CONN_SHIFT);
|
||||
snd_hda_codec_set_pincfg(codec, CS421X_DMIC_PIN_NID, def_conf);
|
||||
}
|
||||
}
|
||||
|
||||
static void cs4210_spdif_automute(struct hda_codec *codec,
|
||||
struct hda_jack_callback *tbl)
|
||||
{
|
||||
struct cs_spec *spec = codec->spec;
|
||||
bool spdif_present = false;
|
||||
hda_nid_t spdif_pin = spec->gen.autocfg.dig_out_pins[0];
|
||||
|
||||
/* detect on spdif is specific to CS4210 */
|
||||
if (!spec->spdif_detect ||
|
||||
spec->vendor_nid != CS4210_VENDOR_NID)
|
||||
return;
|
||||
|
||||
spdif_present = snd_hda_jack_detect(codec, spdif_pin);
|
||||
if (spdif_present == spec->spdif_present)
|
||||
return;
|
||||
|
||||
spec->spdif_present = spdif_present;
|
||||
/* SPDIF TX on/off */
|
||||
snd_hda_set_pin_ctl(codec, spdif_pin, spdif_present ? PIN_OUT : 0);
|
||||
|
||||
cs_automute(codec);
|
||||
}
|
||||
|
||||
static void parse_cs421x_digital(struct hda_codec *codec)
|
||||
{
|
||||
struct cs_spec *spec = codec->spec;
|
||||
struct auto_pin_cfg *cfg = &spec->gen.autocfg;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cfg->dig_outs; i++) {
|
||||
hda_nid_t nid = cfg->dig_out_pins[i];
|
||||
|
||||
if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
|
||||
spec->spdif_detect = 1;
|
||||
snd_hda_jack_detect_enable_callback(codec, nid,
|
||||
cs4210_spdif_automute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int cs421x_init(struct hda_codec *codec)
|
||||
{
|
||||
struct cs_spec *spec = codec->spec;
|
||||
|
||||
if (spec->vendor_nid == CS4210_VENDOR_NID) {
|
||||
snd_hda_sequence_write(codec, cs421x_coef_init_verbs);
|
||||
snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes);
|
||||
cs4210_pinmux_init(codec);
|
||||
}
|
||||
|
||||
snd_hda_gen_init(codec);
|
||||
|
||||
if (spec->gpio_mask) {
|
||||
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
|
||||
spec->gpio_mask);
|
||||
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION,
|
||||
spec->gpio_dir);
|
||||
snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
|
||||
spec->gpio_data);
|
||||
}
|
||||
|
||||
init_input_coef(codec);
|
||||
|
||||
cs4210_spdif_automute(codec, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac)
|
||||
{
|
||||
unsigned int caps;
|
||||
|
||||
/* set the upper-limit for mixer amp to 0dB */
|
||||
caps = query_amp_caps(codec, dac, HDA_OUTPUT);
|
||||
caps &= ~(0x7f << AC_AMPCAP_NUM_STEPS_SHIFT);
|
||||
caps |= ((caps >> AC_AMPCAP_OFFSET_SHIFT) & 0x7f)
|
||||
<< AC_AMPCAP_NUM_STEPS_SHIFT;
|
||||
snd_hda_override_amp_caps(codec, dac, HDA_OUTPUT, caps);
|
||||
}
|
||||
|
||||
static int cs421x_parse_auto_config(struct hda_codec *codec)
|
||||
{
|
||||
struct cs_spec *spec = codec->spec;
|
||||
hda_nid_t dac = CS4210_DAC_NID;
|
||||
int err;
|
||||
|
||||
fix_volume_caps(codec, dac);
|
||||
|
||||
err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
parse_cs421x_digital(codec);
|
||||
|
||||
if (spec->gen.autocfg.speaker_outs &&
|
||||
spec->vendor_nid == CS4210_VENDOR_NID) {
|
||||
if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
|
||||
&cs421x_speaker_boost_ctl))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Manage PDREF, when transitioning to D3hot
|
||||
* (DAC,ADC) -> D3, PDREF=1, AFG->D3
|
||||
*/
|
||||
static int cs421x_suspend(struct hda_codec *codec)
|
||||
{
|
||||
struct cs_spec *spec = codec->spec;
|
||||
unsigned int coef;
|
||||
|
||||
snd_hda_shutup_pins(codec);
|
||||
|
||||
snd_hda_codec_write(codec, CS4210_DAC_NID, 0,
|
||||
AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
|
||||
snd_hda_codec_write(codec, CS4210_ADC_NID, 0,
|
||||
AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
|
||||
|
||||
if (spec->vendor_nid == CS4210_VENDOR_NID) {
|
||||
coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
|
||||
coef |= 0x0004; /* PDREF */
|
||||
cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hda_codec_ops cs421x_patch_ops = {
|
||||
.build_controls = snd_hda_gen_build_controls,
|
||||
.build_pcms = snd_hda_gen_build_pcms,
|
||||
.init = cs421x_init,
|
||||
.free = cs_free,
|
||||
.unsol_event = snd_hda_jack_unsol_event,
|
||||
.suspend = cs421x_suspend,
|
||||
};
|
||||
|
||||
static int patch_cs4210(struct hda_codec *codec)
|
||||
static int cs_codec_probe(struct hda_codec *codec,
|
||||
const struct hda_device_id *id)
|
||||
{
|
||||
struct cs_spec *spec;
|
||||
int err;
|
||||
|
||||
spec = cs_alloc_spec(codec, CS4210_VENDOR_NID);
|
||||
spec = cs_alloc_spec(codec, id->driver_data);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
|
||||
codec->patch_ops = cs421x_patch_ops;
|
||||
spec->gen.automute_hook = cs_automute;
|
||||
|
||||
snd_hda_pick_fixup(codec, cs421x_models, cs421x_fixup_tbl,
|
||||
cs421x_fixups);
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
|
||||
|
||||
/*
|
||||
* Update the GPIO/DMIC/SENSE_B pinmux before the configuration
|
||||
* is auto-parsed. If GPIO or SENSE_B is forced, DMIC input
|
||||
* is disabled.
|
||||
*/
|
||||
cs4210_pinmux_init(codec);
|
||||
|
||||
err = cs421x_parse_auto_config(codec);
|
||||
if (spec->vendor_nid == CS4208_VENDOR_NID)
|
||||
err = cs4208_probe(codec);
|
||||
else
|
||||
err = cs420x_probe(codec);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
cs_free(codec);
|
||||
snd_hda_gen_remove(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int patch_cs4213(struct hda_codec *codec)
|
||||
{
|
||||
struct cs_spec *spec;
|
||||
int err;
|
||||
|
||||
spec = cs_alloc_spec(codec, CS4213_VENDOR_NID);
|
||||
if (!spec)
|
||||
return -ENOMEM;
|
||||
|
||||
codec->patch_ops = cs421x_patch_ops;
|
||||
|
||||
err = cs421x_parse_auto_config(codec);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
cs_free(codec);
|
||||
return err;
|
||||
}
|
||||
static const struct hda_codec_ops cs_codec_ops = {
|
||||
.probe = cs_codec_probe,
|
||||
.remove = snd_hda_gen_remove,
|
||||
.build_controls = cs_build_controls,
|
||||
.build_pcms = snd_hda_gen_build_pcms,
|
||||
.init = cs_init,
|
||||
.unsol_event = snd_hda_jack_unsol_event,
|
||||
.stream_pm = snd_hda_gen_stream_pm,
|
||||
};
|
||||
|
||||
/*
|
||||
* patch entries
|
||||
* driver entries
|
||||
*/
|
||||
static const struct hda_device_id snd_hda_id_cirrus[] = {
|
||||
HDA_CODEC_ENTRY(0x10134206, "CS4206", patch_cs420x),
|
||||
HDA_CODEC_ENTRY(0x10134207, "CS4207", patch_cs420x),
|
||||
HDA_CODEC_ENTRY(0x10134208, "CS4208", patch_cs4208),
|
||||
HDA_CODEC_ENTRY(0x10134210, "CS4210", patch_cs4210),
|
||||
HDA_CODEC_ENTRY(0x10134213, "CS4213", patch_cs4213),
|
||||
static const struct hda_device_id snd_hda_id_cs420x[] = {
|
||||
HDA_CODEC_ID_MODEL(0x10134206, "CS4206", CS420X_VENDOR_NID),
|
||||
HDA_CODEC_ID_MODEL(0x10134207, "CS4207", CS420X_VENDOR_NID),
|
||||
HDA_CODEC_ID_MODEL(0x10134208, "CS4208", CS4208_VENDOR_NID),
|
||||
{} /* terminator */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_cirrus);
|
||||
MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_cs420x);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Cirrus Logic HD-audio codec");
|
||||
MODULE_DESCRIPTION("Cirrus Logic CS420x HD-audio codec");
|
||||
|
||||
static struct hda_codec_driver cirrus_driver = {
|
||||
.id = snd_hda_id_cirrus,
|
||||
static struct hda_codec_driver cs420x_driver = {
|
||||
.id = snd_hda_id_cs420x,
|
||||
.ops = &cs_codec_ops,
|
||||
};
|
||||
|
||||
module_hda_codec_driver(cirrus_driver);
|
||||
module_hda_codec_driver(cs420x_driver);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user