mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-30 03:56:44 +07:00
Merge remote-tracking branches 'asoc/fix/arizona', 'asoc/fix/fsl', 'asoc/fix/omap', 'asoc/fix/samsung', 'asoc/fix/simple', 'asoc/fix/tlv320aic32x4' and 'asoc/fix/wm5100' into asoc-linus
This commit is contained in:
commit
e65523ca79
31
Documentation/devicetree/bindings/sound/adi,axi-i2s.txt
Normal file
31
Documentation/devicetree/bindings/sound/adi,axi-i2s.txt
Normal file
@ -0,0 +1,31 @@
|
||||
ADI AXI-I2S controller
|
||||
|
||||
Required properties:
|
||||
- compatible : Must be "adi,axi-i2s-1.00.a"
|
||||
- reg : Must contain I2S core's registers location and length
|
||||
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
|
||||
The controller expects two clocks, the clock used for the AXI interface and
|
||||
the clock used as the sampling rate reference clock sample.
|
||||
- clock-names : "axi" for the clock to the AXI interface, "ref" for the sample
|
||||
rate reference clock.
|
||||
- dmas: Pairs of phandle and specifier for the DMA channels that are used by
|
||||
the core. The core expects two dma channels, one for transmit and one for
|
||||
receive.
|
||||
- dma-names : "tx" for the transmit channel, "rx" for the receive channel.
|
||||
|
||||
For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties
|
||||
please check:
|
||||
* resource-names.txt
|
||||
* clock/clock-bindings.txt
|
||||
* dma/dma.txt
|
||||
|
||||
Example:
|
||||
|
||||
i2s: i2s@0x77600000 {
|
||||
compatible = "adi,axi-i2s-1.00.a";
|
||||
reg = <0x77600000 0x1000>;
|
||||
clocks = <&clk 15>, <&audio_clock>;
|
||||
clock-names = "axi", "ref";
|
||||
dmas = <&ps7_dma 0>, <&ps7_dma 1>;
|
||||
dma-names = "tx", "rx";
|
||||
};
|
30
Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt
Normal file
30
Documentation/devicetree/bindings/sound/adi,axi-spdif-tx.txt
Normal file
@ -0,0 +1,30 @@
|
||||
ADI AXI-SPDIF controller
|
||||
|
||||
Required properties:
|
||||
- compatible : Must be "adi,axi-spdif-1.00.a"
|
||||
- reg : Must contain SPDIF core's registers location and length
|
||||
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
|
||||
The controller expects two clocks, the clock used for the AXI interface and
|
||||
the clock used as the sampling rate reference clock sample.
|
||||
- clock-names: "axi" for the clock to the AXI interface, "ref" for the sample
|
||||
rate reference clock.
|
||||
- dmas: Pairs of phandle and specifier for the DMA channel that is used by
|
||||
the core. The core expects one dma channel for transmit.
|
||||
- dma-names : Must be "tx"
|
||||
|
||||
For more details on the 'dma', 'dma-names', 'clock' and 'clock-names' properties
|
||||
please check:
|
||||
* resource-names.txt
|
||||
* clock/clock-bindings.txt
|
||||
* dma/dma.txt
|
||||
|
||||
Example:
|
||||
|
||||
spdif: spdif@0x77400000 {
|
||||
compatible = "adi,axi-spdif-tx-1.00.a";
|
||||
reg = <0x77600000 0x1000>;
|
||||
clocks = <&clk 15>, <&audio_clock>;
|
||||
clock-names = "axi", "ref";
|
||||
dmas = <&ps7_dma 0>;
|
||||
dma-names = "tx";
|
||||
};
|
25
Documentation/devicetree/bindings/sound/bcm2835-i2s.txt
Normal file
25
Documentation/devicetree/bindings/sound/bcm2835-i2s.txt
Normal file
@ -0,0 +1,25 @@
|
||||
* Broadcom BCM2835 SoC I2S/PCM module
|
||||
|
||||
Required properties:
|
||||
- compatible: "brcm,bcm2835-i2s"
|
||||
- reg: A list of base address and size entries:
|
||||
* The first entry should cover the PCM registers
|
||||
* The second entry should cover the PCM clock registers
|
||||
- dmas: List of DMA controller phandle and DMA request line ordered pairs.
|
||||
- dma-names: Identifier string for each DMA request line in the dmas property.
|
||||
These strings correspond 1:1 with the ordered pairs in dmas.
|
||||
|
||||
One of the DMA channels will be responsible for transmission (should be
|
||||
named "tx") and one for reception (should be named "rx").
|
||||
|
||||
Example:
|
||||
|
||||
bcm2835_i2s: i2s@7e203000 {
|
||||
compatible = "brcm,bcm2835-i2s";
|
||||
reg = <0x7e203000 0x20>,
|
||||
<0x7e101098 0x02>;
|
||||
|
||||
dmas = <&dma 2>,
|
||||
<&dma 3>;
|
||||
dma-names = "tx", "rx";
|
||||
};
|
46
Documentation/devicetree/bindings/sound/cs42l52.txt
Normal file
46
Documentation/devicetree/bindings/sound/cs42l52.txt
Normal file
@ -0,0 +1,46 @@
|
||||
CS42L52 audio CODEC
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "cirrus,cs42l52"
|
||||
|
||||
- reg : the I2C address of the device for I2C
|
||||
|
||||
Optional properties:
|
||||
|
||||
- cirrus,reset-gpio : GPIO controller's phandle and the number
|
||||
of the GPIO used to reset the codec.
|
||||
|
||||
- cirrus,chgfreq-divisor : Values used to set the Charge Pump Frequency.
|
||||
Allowable values of 0x00 through 0x0F. These are raw values written to the
|
||||
register, not the actual frequency. The frequency is determined by the following.
|
||||
Frequency = (64xFs)/(N+2)
|
||||
N = chgfreq_val
|
||||
Fs = Sample Rate (variable)
|
||||
|
||||
- cirrus,mica-differential-cfg : boolean, If present, then the MICA input is configured
|
||||
as a differential input. If not present then the MICA input is configured as
|
||||
Single-ended input. Single-ended mode allows for MIC1 or MIC2 muxing for input.
|
||||
|
||||
- cirrus,micb-differential-cfg : boolean, If present, then the MICB input is configured
|
||||
as a differential input. If not present then the MICB input is configured as
|
||||
Single-ended input. Single-ended mode allows for MIC1 or MIC2 muxing for input.
|
||||
|
||||
- cirrus,micbias-lvl: Set the output voltage level on the MICBIAS Pin
|
||||
0 = 0.5 x VA
|
||||
1 = 0.6 x VA
|
||||
2 = 0.7 x VA
|
||||
3 = 0.8 x VA
|
||||
4 = 0.83 x VA
|
||||
5 = 0.91 x VA
|
||||
|
||||
Example:
|
||||
|
||||
codec: codec@4a {
|
||||
compatible = "cirrus,cs42l52";
|
||||
reg = <0x4a>;
|
||||
reset-gpio = <&gpio 10 0>;
|
||||
cirrus,chgfreq-divisor = <0x05>;
|
||||
cirrus.mica-differential-cfg;
|
||||
cirrus,micbias-lvl = <5>;
|
||||
};
|
@ -4,7 +4,8 @@ Required properties:
|
||||
- compatible :
|
||||
"ti,dm646x-mcasp-audio" : for DM646x platforms
|
||||
"ti,da830-mcasp-audio" : for both DA830 & DA850 platforms
|
||||
"ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, TI81xx)
|
||||
"ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx)
|
||||
"ti,dra7-mcasp-audio" : for DRA7xx platforms
|
||||
|
||||
- reg : Should contain reg specifiers for the entries in the reg-names property.
|
||||
- reg-names : Should contain:
|
||||
@ -36,7 +37,8 @@ Optional properties:
|
||||
- pinctrl-0: Should specify pin control group used for this controller.
|
||||
- pinctrl-names: Should contain only one value - "default", for more details
|
||||
please refer to pinctrl-bindings.txt
|
||||
|
||||
- fck_parent : Should contain a valid clock name which will be used as parent
|
||||
for the McASP fck
|
||||
|
||||
Example:
|
||||
|
||||
|
50
Documentation/devicetree/bindings/sound/fsl,esai.txt
Normal file
50
Documentation/devicetree/bindings/sound/fsl,esai.txt
Normal file
@ -0,0 +1,50 @@
|
||||
Freescale Enhanced Serial Audio Interface (ESAI) Controller
|
||||
|
||||
The Enhanced Serial Audio Interface (ESAI) provides a full-duplex serial port
|
||||
for serial communication with a variety of serial devices, including industry
|
||||
standard codecs, Sony/Phillips Digital Interface (S/PDIF) transceivers, and
|
||||
other DSPs. It has up to six transmitters and four receivers.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : Compatible list, must contain "fsl,imx35-esai".
|
||||
|
||||
- reg : Offset and length of the register set for the device.
|
||||
|
||||
- interrupts : Contains the spdif interrupt.
|
||||
|
||||
- dmas : Generic dma devicetree binding as described in
|
||||
Documentation/devicetree/bindings/dma/dma.txt.
|
||||
|
||||
- dma-names : Two dmas have to be defined, "tx" and "rx".
|
||||
|
||||
- clocks: Contains an entry for each entry in clock-names.
|
||||
|
||||
- clock-names : Includes the following entries:
|
||||
"core" The core clock used to access registers
|
||||
"extal" The esai baud clock for esai controller used to derive
|
||||
HCK, SCK and FS.
|
||||
"fsys" The system clock derived from ahb clock used to derive
|
||||
HCK, SCK and FS.
|
||||
|
||||
- fsl,fifo-depth: The number of elements in the transmit and receive FIFOs.
|
||||
This number is the maximum allowed value for TFCR[TFWM] or RFCR[RFWM].
|
||||
|
||||
- fsl,esai-synchronous: This is a boolean property. If present, indicating
|
||||
that ESAI would work in the synchronous mode, which means all the settings
|
||||
for Receiving would be duplicated from Transmition related registers.
|
||||
|
||||
Example:
|
||||
|
||||
esai: esai@02024000 {
|
||||
compatible = "fsl,imx35-esai";
|
||||
reg = <0x02024000 0x4000>;
|
||||
interrupts = <0 51 0x04>;
|
||||
clocks = <&clks 208>, <&clks 118>, <&clks 208>;
|
||||
clock-names = "core", "extal", "fsys";
|
||||
dmas = <&sdma 23 21 0>, <&sdma 24 21 0>;
|
||||
dma-names = "rx", "tx";
|
||||
fsl,fifo-depth = <128>;
|
||||
fsl,esai-synchronous;
|
||||
status = "disabled";
|
||||
};
|
@ -4,7 +4,12 @@ The SSI is a serial device that communicates with audio codecs. It can
|
||||
be programmed in AC97, I2S, left-justified, or right-justified modes.
|
||||
|
||||
Required properties:
|
||||
- compatible: Compatible list, contains "fsl,ssi".
|
||||
- compatible: Compatible list, should contain one of the following
|
||||
compatibles:
|
||||
fsl,mpc8610-ssi
|
||||
fsl,imx51-ssi
|
||||
fsl,imx35-ssi
|
||||
fsl,imx21-ssi
|
||||
- cell-index: The SSI, <0> = SSI1, <1> = SSI2, and so on.
|
||||
- reg: Offset and length of the register set for the device.
|
||||
- interrupts: <a b> where a is the interrupt number and b is a
|
||||
|
40
Documentation/devicetree/bindings/sound/fsl-sai.txt
Normal file
40
Documentation/devicetree/bindings/sound/fsl-sai.txt
Normal file
@ -0,0 +1,40 @@
|
||||
Freescale Synchronous Audio Interface (SAI).
|
||||
|
||||
The SAI is based on I2S module that used communicating with audio codecs,
|
||||
which provides a synchronous audio interface that supports fullduplex
|
||||
serial interfaces with frame synchronization such as I2S, AC97, TDM, and
|
||||
codec/DSP interfaces.
|
||||
|
||||
|
||||
Required properties:
|
||||
- compatible: Compatible list, contains "fsl,vf610-sai".
|
||||
- reg: Offset and length of the register set for the device.
|
||||
- clocks: Must contain an entry for each entry in clock-names.
|
||||
- clock-names : Must include the "sai" entry.
|
||||
- dmas : Generic dma devicetree binding as described in
|
||||
Documentation/devicetree/bindings/dma/dma.txt.
|
||||
- dma-names : Two dmas have to be defined, "tx" and "rx".
|
||||
- pinctrl-names: Must contain a "default" entry.
|
||||
- pinctrl-NNN: One property must exist for each entry in pinctrl-names.
|
||||
See ../pinctrl/pinctrl-bindings.txt for details of the property values.
|
||||
- big-endian-regs: If this property is absent, the little endian mode will
|
||||
be in use as default, or the big endian mode will be in use for all the
|
||||
device registers.
|
||||
- big-endian-data: If this property is absent, the little endian mode will
|
||||
be in use as default, or the big endian mode will be in use for all the
|
||||
fifo data.
|
||||
|
||||
Example:
|
||||
sai2: sai@40031000 {
|
||||
compatible = "fsl,vf610-sai";
|
||||
reg = <0x40031000 0x1000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_sai2_1>;
|
||||
clocks = <&clks VF610_CLK_SAI2>;
|
||||
clock-names = "sai";
|
||||
dma-names = "tx", "rx";
|
||||
dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>,
|
||||
<&edma0 0 VF610_EDMA_MUXID0_SAI2_RX>;
|
||||
big-endian-regs;
|
||||
big-endian-data;
|
||||
};
|
17
Documentation/devicetree/bindings/sound/hdmi.txt
Normal file
17
Documentation/devicetree/bindings/sound/hdmi.txt
Normal file
@ -0,0 +1,17 @@
|
||||
Device-Tree bindings for dummy HDMI codec
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "linux,hdmi-audio".
|
||||
|
||||
CODEC output pins:
|
||||
* TX
|
||||
|
||||
CODEC input pins:
|
||||
* RX
|
||||
|
||||
Example node:
|
||||
|
||||
hdmi_audio: hdmi_audio@0 {
|
||||
compatible = "linux,hdmi-audio";
|
||||
status = "okay";
|
||||
};
|
43
Documentation/devicetree/bindings/sound/max98090.txt
Normal file
43
Documentation/devicetree/bindings/sound/max98090.txt
Normal file
@ -0,0 +1,43 @@
|
||||
MAX98090 audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "maxim,max98090".
|
||||
|
||||
- reg : The I2C address of the device.
|
||||
|
||||
- interrupts : The CODEC's interrupt output.
|
||||
|
||||
Pins on the device (for linking into audio routes):
|
||||
|
||||
* MIC1
|
||||
* MIC2
|
||||
* DMICL
|
||||
* DMICR
|
||||
* IN1
|
||||
* IN2
|
||||
* IN3
|
||||
* IN4
|
||||
* IN5
|
||||
* IN6
|
||||
* IN12
|
||||
* IN34
|
||||
* IN56
|
||||
* HPL
|
||||
* HPR
|
||||
* SPKL
|
||||
* SPKR
|
||||
* RCVL
|
||||
* RCVR
|
||||
* MICBIAS
|
||||
|
||||
Example:
|
||||
|
||||
audio-codec@10 {
|
||||
compatible = "maxim,max98090";
|
||||
reg = <0x10>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
|
||||
};
|
@ -0,0 +1,51 @@
|
||||
NVIDIA Tegra audio complex, with MAX98090 CODEC
|
||||
|
||||
Required properties:
|
||||
- compatible : "nvidia,tegra-audio-max98090"
|
||||
- clocks : Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names : Must include the following entries:
|
||||
- pll_a
|
||||
- pll_a_out0
|
||||
- mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
|
||||
- nvidia,model : The user-visible name of this sound complex.
|
||||
- nvidia,audio-routing : A list of the connections between audio components.
|
||||
Each entry is a pair of strings, the first being the connection's sink,
|
||||
the second being the connection's source. Valid names for sources and
|
||||
sinks are the MAX98090's pins (as documented in its binding), and the jacks
|
||||
on the board:
|
||||
|
||||
* Headphones
|
||||
* Speakers
|
||||
* Mic Jack
|
||||
|
||||
- nvidia,i2s-controller : The phandle of the Tegra I2S controller that's
|
||||
connected to the CODEC.
|
||||
- nvidia,audio-codec : The phandle of the MAX98090 audio codec.
|
||||
|
||||
Optional properties:
|
||||
- nvidia,hp-det-gpios : The GPIO that detect headphones are plugged in
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "nvidia,tegra-audio-max98090-venice2",
|
||||
"nvidia,tegra-audio-max98090";
|
||||
nvidia,model = "NVIDIA Tegra Venice2";
|
||||
|
||||
nvidia,audio-routing =
|
||||
"Headphones", "HPR",
|
||||
"Headphones", "HPL",
|
||||
"Speakers", "SPKR",
|
||||
"Speakers", "SPKL",
|
||||
"Mic Jack", "MICBIAS",
|
||||
"IN34", "Mic Jack";
|
||||
|
||||
nvidia,i2s-controller = <&tegra_i2s1>;
|
||||
nvidia,audio-codec = <&acodec>;
|
||||
|
||||
clocks = <&tegra_car TEGRA124_CLK_PLL_A>,
|
||||
<&tegra_car TEGRA124_CLK_PLL_A_OUT0>,
|
||||
<&tegra_car TEGRA124_CLK_EXTERN1>;
|
||||
clock-names = "pll_a", "pll_a_out0", "mclk";
|
||||
};
|
77
Documentation/devicetree/bindings/sound/simple-card.txt
Normal file
77
Documentation/devicetree/bindings/sound/simple-card.txt
Normal file
@ -0,0 +1,77 @@
|
||||
Simple-Card:
|
||||
|
||||
Simple-Card specifies audio DAI connection of SoC <-> codec.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "simple-audio-card"
|
||||
|
||||
Optional properties:
|
||||
|
||||
- simple-audio-card,format : CPU/CODEC common audio format.
|
||||
"i2s", "right_j", "left_j" , "dsp_a"
|
||||
"dsp_b", "ac97", "pdm", "msb", "lsb"
|
||||
- simple-audio-card,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.
|
||||
|
||||
Required subnodes:
|
||||
|
||||
- simple-audio-card,cpu : CPU sub-node
|
||||
- simple-audio-card,codec : CODEC sub-node
|
||||
|
||||
Required CPU/CODEC subnodes properties:
|
||||
|
||||
- sound-dai : phandle and port of CPU/CODEC
|
||||
|
||||
Optional CPU/CODEC subnodes properties:
|
||||
|
||||
- format : CPU/CODEC specific audio format if needed.
|
||||
see simple-audio-card,format
|
||||
- frame-master : bool property. add this if subnode is frame master
|
||||
- bitclock-master : bool property. add this if subnode is bitclock master
|
||||
- bitclock-inversion : bool property. add this if subnode has clock inversion
|
||||
- frame-inversion : bool property. add this if subnode has frame inversion
|
||||
- clocks / system-clock-frequency : specify subnode's clock if needed.
|
||||
it can be specified via "clocks" if system has
|
||||
clock node (= common clock), or "system-clock-frequency"
|
||||
(if system doens't support common clock)
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "simple-audio-card";
|
||||
simple-audio-card,format = "left_j";
|
||||
simple-audio-card,routing =
|
||||
"MIC_IN", "Mic Jack",
|
||||
"Headphone Jack", "HP_OUT",
|
||||
"Ext Spk", "LINE_OUT";
|
||||
|
||||
simple-audio-card,cpu {
|
||||
sound-dai = <&sh_fsi2 0>;
|
||||
};
|
||||
|
||||
simple-audio-card,codec {
|
||||
sound-dai = <&ak4648>;
|
||||
bitclock-master;
|
||||
frame-master;
|
||||
clocks = <&osc>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
ak4648: ak4648@12 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "asahi-kasei,ak4648";
|
||||
reg = <0x12>;
|
||||
};
|
||||
};
|
||||
|
||||
sh_fsi2: sh_fsi2@ec230000 {
|
||||
#sound-dai-cells = <1>;
|
||||
compatible = "renesas,sh_fsi2";
|
||||
reg = <0xec230000 0x400>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <0 146 0x4>;
|
||||
};
|
@ -6,6 +6,7 @@ Required properties:
|
||||
|
||||
- compatible - "string" - One of:
|
||||
"ti,tlv320aic3x" - Generic TLV320AIC3x device
|
||||
"ti,tlv320aic32x4" - TLV320AIC32x4
|
||||
"ti,tlv320aic33" - TLV320AIC33
|
||||
"ti,tlv320aic3007" - TLV320AIC3007
|
||||
"ti,tlv320aic3106" - TLV320AIC3106
|
||||
|
@ -49,18 +49,23 @@ features :-
|
||||
* Machine specific controls: Allow machines to add controls to the sound card
|
||||
(e.g. volume control for speaker amplifier).
|
||||
|
||||
To achieve all this, ASoC basically splits an embedded audio system into 3
|
||||
components :-
|
||||
To achieve all this, ASoC basically splits an embedded audio system into
|
||||
multiple re-usable component drivers :-
|
||||
|
||||
* Codec driver: The codec driver is platform independent and contains audio
|
||||
controls, audio interface capabilities, codec DAPM definition and codec IO
|
||||
functions.
|
||||
* Codec class drivers: The codec class driver is platform independent and
|
||||
contains audio controls, audio interface capabilities, codec DAPM
|
||||
definition and codec IO functions. This class extends to BT, FM and MODEM
|
||||
ICs if required. Codec class drivers should be generic code that can run
|
||||
on any architecture and machine.
|
||||
|
||||
* Platform driver: The platform driver contains the audio DMA engine and audio
|
||||
interface drivers (e.g. I2S, AC97, PCM) for that platform.
|
||||
* Platform class drivers: The platform class driver includes the audio DMA
|
||||
engine driver, digital audio interface (DAI) drivers (e.g. I2S, AC97, PCM)
|
||||
and any audio DSP drivers for that platform.
|
||||
|
||||
* Machine driver: The machine driver handles any machine specific controls and
|
||||
audio events (e.g. turning on an amp at start of playback).
|
||||
* Machine class driver: The machine driver class acts as the glue that
|
||||
decribes and binds the other component drivers together to form an ALSA
|
||||
"sound card device". It handles any machine specific controls and
|
||||
machine level audio events (e.g. turning on an amp at start of playback).
|
||||
|
||||
|
||||
Documentation
|
||||
@ -84,3 +89,7 @@ machine.txt: Machine driver internals.
|
||||
pop_clicks.txt: How to minimise audio artifacts.
|
||||
|
||||
clocking.txt: ASoC clocking for best power performance.
|
||||
|
||||
jack.txt: ASoC jack detection.
|
||||
|
||||
DPCM.txt: Dynamic PCM - Describes DPCM with DSP examples.
|
||||
|
@ -723,6 +723,7 @@ config ARCH_S3C64XX
|
||||
bool "Samsung S3C64XX"
|
||||
select ARCH_HAS_CPUFREQ
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select ARM_AMBA
|
||||
select ARM_VIC
|
||||
select CLKDEV_LOOKUP
|
||||
select CLKSRC_SAMSUNG_PWM
|
||||
|
@ -17,9 +17,10 @@ config CPU_S3C6410
|
||||
help
|
||||
Enable S3C6410 CPU support
|
||||
|
||||
config S3C64XX_DMA
|
||||
bool "S3C64XX DMA"
|
||||
select S3C_DMA
|
||||
config S3C64XX_PL080
|
||||
bool "S3C64XX DMA using generic PL08x driver"
|
||||
select AMBA_PL08X
|
||||
select SAMSUNG_DMADEV
|
||||
|
||||
config S3C64XX_SETUP_SDHCI
|
||||
bool
|
||||
|
@ -26,7 +26,7 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
|
||||
# DMA support
|
||||
|
||||
obj-$(CONFIG_S3C64XX_DMA) += dma.o
|
||||
obj-$(CONFIG_S3C64XX_PL080) += pl080.o
|
||||
|
||||
# Device support
|
||||
|
||||
|
@ -58,4 +58,9 @@ int __init s3c64xx_pm_late_initcall(void);
|
||||
static inline int s3c64xx_pm_late_initcall(void) { return 0; }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_S3C64XX_PL080
|
||||
extern struct pl08x_platform_data s3c64xx_dma0_plat_data;
|
||||
extern struct pl08x_platform_data s3c64xx_dma1_plat_data;
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */
|
||||
|
@ -1,762 +0,0 @@
|
||||
/* linux/arch/arm/plat-s3c64xx/dma.c
|
||||
*
|
||||
* Copyright 2009 Openmoko, Inc.
|
||||
* Copyright 2009 Simtec Electronics
|
||||
* Ben Dooks <ben@simtec.co.uk>
|
||||
* http://armlinux.simtec.co.uk/
|
||||
*
|
||||
* S3C64XX DMA core
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: Code in this file is not used when booting with Device Tree support.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/dmapool.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/amba/pl080.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <mach/dma.h>
|
||||
#include <mach/map.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include "regs-sys.h"
|
||||
|
||||
/* dma channel state information */
|
||||
|
||||
struct s3c64xx_dmac {
|
||||
struct device dev;
|
||||
struct clk *clk;
|
||||
void __iomem *regs;
|
||||
struct s3c2410_dma_chan *channels;
|
||||
enum dma_ch chanbase;
|
||||
};
|
||||
|
||||
/* pool to provide LLI buffers */
|
||||
static struct dma_pool *dma_pool;
|
||||
|
||||
/* Debug configuration and code */
|
||||
|
||||
static unsigned char debug_show_buffs = 0;
|
||||
|
||||
static void dbg_showchan(struct s3c2410_dma_chan *chan)
|
||||
{
|
||||
pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n",
|
||||
chan->number,
|
||||
readl(chan->regs + PL080_CH_SRC_ADDR),
|
||||
readl(chan->regs + PL080_CH_DST_ADDR),
|
||||
readl(chan->regs + PL080_CH_LLI),
|
||||
readl(chan->regs + PL080_CH_CONTROL),
|
||||
readl(chan->regs + PL080S_CH_CONTROL2),
|
||||
readl(chan->regs + PL080S_CH_CONFIG));
|
||||
}
|
||||
|
||||
static void show_lli(struct pl080s_lli *lli)
|
||||
{
|
||||
pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n",
|
||||
lli, lli->src_addr, lli->dst_addr, lli->next_lli,
|
||||
lli->control0, lli->control1);
|
||||
}
|
||||
|
||||
static void dbg_showbuffs(struct s3c2410_dma_chan *chan)
|
||||
{
|
||||
struct s3c64xx_dma_buff *ptr;
|
||||
struct s3c64xx_dma_buff *end;
|
||||
|
||||
pr_debug("DMA%d: buffs next %p, curr %p, end %p\n",
|
||||
chan->number, chan->next, chan->curr, chan->end);
|
||||
|
||||
ptr = chan->next;
|
||||
end = chan->end;
|
||||
|
||||
if (debug_show_buffs) {
|
||||
for (; ptr != NULL; ptr = ptr->next) {
|
||||
pr_debug("DMA%d: %08x ",
|
||||
chan->number, ptr->lli_dma);
|
||||
show_lli(ptr->lli);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* End of Debug */
|
||||
|
||||
static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel)
|
||||
{
|
||||
struct s3c2410_dma_chan *chan;
|
||||
unsigned int start, offs;
|
||||
|
||||
start = 0;
|
||||
|
||||
if (channel >= DMACH_PCM1_TX)
|
||||
start = 8;
|
||||
|
||||
for (offs = 0; offs < 8; offs++) {
|
||||
chan = &s3c2410_chans[start + offs];
|
||||
if (!chan->in_use)
|
||||
goto found;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
found:
|
||||
s3c_dma_chan_map[channel] = chan;
|
||||
return chan;
|
||||
}
|
||||
|
||||
int s3c2410_dma_config(enum dma_ch channel, int xferunit)
|
||||
{
|
||||
struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
|
||||
|
||||
if (chan == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
switch (xferunit) {
|
||||
case 1:
|
||||
chan->hw_width = 0;
|
||||
break;
|
||||
case 2:
|
||||
chan->hw_width = 1;
|
||||
break;
|
||||
case 4:
|
||||
chan->hw_width = 2;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(s3c2410_dma_config);
|
||||
|
||||
static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
|
||||
struct pl080s_lli *lli,
|
||||
dma_addr_t data, int size)
|
||||
{
|
||||
dma_addr_t src, dst;
|
||||
u32 control0, control1;
|
||||
|
||||
switch (chan->source) {
|
||||
case DMA_FROM_DEVICE:
|
||||
src = chan->dev_addr;
|
||||
dst = data;
|
||||
control0 = PL080_CONTROL_SRC_AHB2;
|
||||
control0 |= PL080_CONTROL_DST_INCR;
|
||||
break;
|
||||
|
||||
case DMA_TO_DEVICE:
|
||||
src = data;
|
||||
dst = chan->dev_addr;
|
||||
control0 = PL080_CONTROL_DST_AHB2;
|
||||
control0 |= PL080_CONTROL_SRC_INCR;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* note, we do not currently setup any of the burst controls */
|
||||
|
||||
control1 = size >> chan->hw_width; /* size in no of xfers */
|
||||
control0 |= PL080_CONTROL_PROT_SYS; /* always in priv. mode */
|
||||
control0 |= PL080_CONTROL_TC_IRQ_EN; /* always fire IRQ */
|
||||
control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
|
||||
control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
|
||||
|
||||
lli->src_addr = src;
|
||||
lli->dst_addr = dst;
|
||||
lli->next_lli = 0;
|
||||
lli->control0 = control0;
|
||||
lli->control1 = control1;
|
||||
}
|
||||
|
||||
static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan,
|
||||
struct pl080s_lli *lli)
|
||||
{
|
||||
void __iomem *regs = chan->regs;
|
||||
|
||||
pr_debug("%s: LLI %p => regs\n", __func__, lli);
|
||||
show_lli(lli);
|
||||
|
||||
writel(lli->src_addr, regs + PL080_CH_SRC_ADDR);
|
||||
writel(lli->dst_addr, regs + PL080_CH_DST_ADDR);
|
||||
writel(lli->next_lli, regs + PL080_CH_LLI);
|
||||
writel(lli->control0, regs + PL080_CH_CONTROL);
|
||||
writel(lli->control1, regs + PL080S_CH_CONTROL2);
|
||||
}
|
||||
|
||||
static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)
|
||||
{
|
||||
struct s3c64xx_dmac *dmac = chan->dmac;
|
||||
u32 config;
|
||||
u32 bit = chan->bit;
|
||||
|
||||
dbg_showchan(chan);
|
||||
|
||||
pr_debug("%s: clearing interrupts\n", __func__);
|
||||
|
||||
/* clear interrupts */
|
||||
writel(bit, dmac->regs + PL080_TC_CLEAR);
|
||||
writel(bit, dmac->regs + PL080_ERR_CLEAR);
|
||||
|
||||
pr_debug("%s: starting channel\n", __func__);
|
||||
|
||||
config = readl(chan->regs + PL080S_CH_CONFIG);
|
||||
config |= PL080_CONFIG_ENABLE;
|
||||
config &= ~PL080_CONFIG_HALT;
|
||||
|
||||
pr_debug("%s: writing config %08x\n", __func__, config);
|
||||
writel(config, chan->regs + PL080S_CH_CONFIG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan)
|
||||
{
|
||||
u32 config;
|
||||
int timeout;
|
||||
|
||||
pr_debug("%s: stopping channel\n", __func__);
|
||||
|
||||
dbg_showchan(chan);
|
||||
|
||||
config = readl(chan->regs + PL080S_CH_CONFIG);
|
||||
config |= PL080_CONFIG_HALT;
|
||||
writel(config, chan->regs + PL080S_CH_CONFIG);
|
||||
|
||||
timeout = 1000;
|
||||
do {
|
||||
config = readl(chan->regs + PL080S_CH_CONFIG);
|
||||
pr_debug("%s: %d - config %08x\n", __func__, timeout, config);
|
||||
if (config & PL080_CONFIG_ACTIVE)
|
||||
udelay(10);
|
||||
else
|
||||
break;
|
||||
} while (--timeout > 0);
|
||||
|
||||
if (config & PL080_CONFIG_ACTIVE) {
|
||||
printk(KERN_ERR "%s: channel still active\n", __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
config = readl(chan->regs + PL080S_CH_CONFIG);
|
||||
config &= ~PL080_CONFIG_ENABLE;
|
||||
writel(config, chan->regs + PL080S_CH_CONFIG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan,
|
||||
struct s3c64xx_dma_buff *buf,
|
||||
enum s3c2410_dma_buffresult result)
|
||||
{
|
||||
if (chan->callback_fn != NULL)
|
||||
(chan->callback_fn)(chan, buf->pw, 0, result);
|
||||
}
|
||||
|
||||
static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff)
|
||||
{
|
||||
dma_pool_free(dma_pool, buff->lli, buff->lli_dma);
|
||||
kfree(buff);
|
||||
}
|
||||
|
||||
static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan)
|
||||
{
|
||||
struct s3c64xx_dma_buff *buff, *next;
|
||||
u32 config;
|
||||
|
||||
dbg_showchan(chan);
|
||||
|
||||
pr_debug("%s: flushing channel\n", __func__);
|
||||
|
||||
config = readl(chan->regs + PL080S_CH_CONFIG);
|
||||
config &= ~PL080_CONFIG_ENABLE;
|
||||
writel(config, chan->regs + PL080S_CH_CONFIG);
|
||||
|
||||
/* dump all the buffers associated with this channel */
|
||||
|
||||
for (buff = chan->curr; buff != NULL; buff = next) {
|
||||
next = buff->next;
|
||||
pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next);
|
||||
|
||||
s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT);
|
||||
s3c64xx_dma_freebuff(buff);
|
||||
}
|
||||
|
||||
chan->curr = chan->next = chan->end = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op)
|
||||
{
|
||||
struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
|
||||
|
||||
WARN_ON(!chan);
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
|
||||
switch (op) {
|
||||
case S3C2410_DMAOP_START:
|
||||
return s3c64xx_dma_start(chan);
|
||||
|
||||
case S3C2410_DMAOP_STOP:
|
||||
return s3c64xx_dma_stop(chan);
|
||||
|
||||
case S3C2410_DMAOP_FLUSH:
|
||||
return s3c64xx_dma_flush(chan);
|
||||
|
||||
/* believe PAUSE/RESUME are no-ops */
|
||||
case S3C2410_DMAOP_PAUSE:
|
||||
case S3C2410_DMAOP_RESUME:
|
||||
case S3C2410_DMAOP_STARTED:
|
||||
case S3C2410_DMAOP_TIMEOUT:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
EXPORT_SYMBOL(s3c2410_dma_ctrl);
|
||||
|
||||
/* s3c2410_dma_enque
|
||||
*
|
||||
*/
|
||||
|
||||
int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
|
||||
dma_addr_t data, int size)
|
||||
{
|
||||
struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
|
||||
struct s3c64xx_dma_buff *next;
|
||||
struct s3c64xx_dma_buff *buff;
|
||||
struct pl080s_lli *lli;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
WARN_ON(!chan);
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
|
||||
buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_ATOMIC);
|
||||
if (!buff) {
|
||||
printk(KERN_ERR "%s: no memory for buffer\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
lli = dma_pool_alloc(dma_pool, GFP_ATOMIC, &buff->lli_dma);
|
||||
if (!lli) {
|
||||
printk(KERN_ERR "%s: no memory for lli\n", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto err_buff;
|
||||
}
|
||||
|
||||
pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n",
|
||||
__func__, buff, data, lli, (u32)buff->lli_dma, size);
|
||||
|
||||
buff->lli = lli;
|
||||
buff->pw = id;
|
||||
|
||||
s3c64xx_dma_fill_lli(chan, lli, data, size);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
if ((next = chan->next) != NULL) {
|
||||
struct s3c64xx_dma_buff *end = chan->end;
|
||||
struct pl080s_lli *endlli = end->lli;
|
||||
|
||||
pr_debug("enquing onto channel\n");
|
||||
|
||||
end->next = buff;
|
||||
endlli->next_lli = buff->lli_dma;
|
||||
|
||||
if (chan->flags & S3C2410_DMAF_CIRCULAR) {
|
||||
struct s3c64xx_dma_buff *curr = chan->curr;
|
||||
lli->next_lli = curr->lli_dma;
|
||||
}
|
||||
|
||||
if (next == chan->curr) {
|
||||
writel(buff->lli_dma, chan->regs + PL080_CH_LLI);
|
||||
chan->next = buff;
|
||||
}
|
||||
|
||||
show_lli(endlli);
|
||||
chan->end = buff;
|
||||
} else {
|
||||
pr_debug("enquing onto empty channel\n");
|
||||
|
||||
chan->curr = buff;
|
||||
chan->next = buff;
|
||||
chan->end = buff;
|
||||
|
||||
s3c64xx_lli_to_regs(chan, lli);
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
show_lli(lli);
|
||||
|
||||
dbg_showchan(chan);
|
||||
dbg_showbuffs(chan);
|
||||
return 0;
|
||||
|
||||
err_buff:
|
||||
kfree(buff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(s3c2410_dma_enqueue);
|
||||
|
||||
|
||||
int s3c2410_dma_devconfig(enum dma_ch channel,
|
||||
enum dma_data_direction source,
|
||||
unsigned long devaddr)
|
||||
{
|
||||
struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
|
||||
u32 peripheral;
|
||||
u32 config = 0;
|
||||
|
||||
pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n",
|
||||
__func__, channel, source, devaddr, chan);
|
||||
|
||||
WARN_ON(!chan);
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
|
||||
peripheral = (chan->peripheral & 0xf);
|
||||
chan->source = source;
|
||||
chan->dev_addr = devaddr;
|
||||
|
||||
pr_debug("%s: peripheral %d\n", __func__, peripheral);
|
||||
|
||||
switch (source) {
|
||||
case DMA_FROM_DEVICE:
|
||||
config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
|
||||
config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT;
|
||||
break;
|
||||
case DMA_TO_DEVICE:
|
||||
config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
|
||||
config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "%s: bad source\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* allow TC and ERR interrupts */
|
||||
config |= PL080_CONFIG_TC_IRQ_MASK;
|
||||
config |= PL080_CONFIG_ERR_IRQ_MASK;
|
||||
|
||||
pr_debug("%s: config %08x\n", __func__, config);
|
||||
|
||||
writel(config, chan->regs + PL080S_CH_CONFIG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(s3c2410_dma_devconfig);
|
||||
|
||||
|
||||
int s3c2410_dma_getposition(enum dma_ch channel,
|
||||
dma_addr_t *src, dma_addr_t *dst)
|
||||
{
|
||||
struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
|
||||
|
||||
WARN_ON(!chan);
|
||||
if (!chan)
|
||||
return -EINVAL;
|
||||
|
||||
if (src != NULL)
|
||||
*src = readl(chan->regs + PL080_CH_SRC_ADDR);
|
||||
|
||||
if (dst != NULL)
|
||||
*dst = readl(chan->regs + PL080_CH_DST_ADDR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(s3c2410_dma_getposition);
|
||||
|
||||
/* s3c2410_request_dma
|
||||
*
|
||||
* get control of an dma channel
|
||||
*/
|
||||
|
||||
int s3c2410_dma_request(enum dma_ch channel,
|
||||
struct s3c2410_dma_client *client,
|
||||
void *dev)
|
||||
{
|
||||
struct s3c2410_dma_chan *chan;
|
||||
unsigned long flags;
|
||||
|
||||
pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
|
||||
channel, client->name, dev);
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
chan = s3c64xx_dma_map_channel(channel);
|
||||
if (chan == NULL) {
|
||||
local_irq_restore(flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
dbg_showchan(chan);
|
||||
|
||||
chan->client = client;
|
||||
chan->in_use = 1;
|
||||
chan->peripheral = channel;
|
||||
chan->flags = 0;
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
/* need to setup */
|
||||
|
||||
pr_debug("%s: channel initialised, %p\n", __func__, chan);
|
||||
|
||||
return chan->number | DMACH_LOW_LEVEL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(s3c2410_dma_request);
|
||||
|
||||
/* s3c2410_dma_free
|
||||
*
|
||||
* release the given channel back to the system, will stop and flush
|
||||
* any outstanding transfers, and ensure the channel is ready for the
|
||||
* next claimant.
|
||||
*
|
||||
* Note, although a warning is currently printed if the freeing client
|
||||
* info is not the same as the registrant's client info, the free is still
|
||||
* allowed to go through.
|
||||
*/
|
||||
|
||||
int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *client)
|
||||
{
|
||||
struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
|
||||
unsigned long flags;
|
||||
|
||||
if (chan == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
if (chan->client != client) {
|
||||
printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
|
||||
channel, chan->client, client);
|
||||
}
|
||||
|
||||
/* sort out stopping and freeing the channel */
|
||||
|
||||
|
||||
chan->client = NULL;
|
||||
chan->in_use = 0;
|
||||
|
||||
if (!(channel & DMACH_LOW_LEVEL))
|
||||
s3c_dma_chan_map[channel] = NULL;
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(s3c2410_dma_free);
|
||||
|
||||
static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
|
||||
{
|
||||
struct s3c64xx_dmac *dmac = pw;
|
||||
struct s3c2410_dma_chan *chan;
|
||||
enum s3c2410_dma_buffresult res;
|
||||
u32 tcstat, errstat;
|
||||
u32 bit;
|
||||
int offs;
|
||||
|
||||
tcstat = readl(dmac->regs + PL080_TC_STATUS);
|
||||
errstat = readl(dmac->regs + PL080_ERR_STATUS);
|
||||
|
||||
for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
|
||||
struct s3c64xx_dma_buff *buff;
|
||||
|
||||
if (!(errstat & bit) && !(tcstat & bit))
|
||||
continue;
|
||||
|
||||
chan = dmac->channels + offs;
|
||||
res = S3C2410_RES_ERR;
|
||||
|
||||
if (tcstat & bit) {
|
||||
writel(bit, dmac->regs + PL080_TC_CLEAR);
|
||||
res = S3C2410_RES_OK;
|
||||
}
|
||||
|
||||
if (errstat & bit)
|
||||
writel(bit, dmac->regs + PL080_ERR_CLEAR);
|
||||
|
||||
/* 'next' points to the buffer that is next to the
|
||||
* currently active buffer.
|
||||
* For CIRCULAR queues, 'next' will be same as 'curr'
|
||||
* when 'end' is the active buffer.
|
||||
*/
|
||||
buff = chan->curr;
|
||||
while (buff && buff != chan->next
|
||||
&& buff->next != chan->next)
|
||||
buff = buff->next;
|
||||
|
||||
if (!buff)
|
||||
BUG();
|
||||
|
||||
if (buff == chan->next)
|
||||
buff = chan->end;
|
||||
|
||||
s3c64xx_dma_bufffdone(chan, buff, res);
|
||||
|
||||
/* Free the node and update curr, if non-circular queue */
|
||||
if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
|
||||
chan->curr = buff->next;
|
||||
s3c64xx_dma_freebuff(buff);
|
||||
}
|
||||
|
||||
/* Update 'next' */
|
||||
buff = chan->next;
|
||||
if (chan->next == chan->end) {
|
||||
chan->next = chan->curr;
|
||||
if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
|
||||
chan->end = NULL;
|
||||
} else {
|
||||
chan->next = buff->next;
|
||||
}
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct bus_type dma_subsys = {
|
||||
.name = "s3c64xx-dma",
|
||||
.dev_name = "s3c64xx-dma",
|
||||
};
|
||||
|
||||
static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
|
||||
int irq, unsigned int base)
|
||||
{
|
||||
struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno];
|
||||
struct s3c64xx_dmac *dmac;
|
||||
char clkname[16];
|
||||
void __iomem *regs;
|
||||
void __iomem *regptr;
|
||||
int err, ch;
|
||||
|
||||
dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL);
|
||||
if (!dmac) {
|
||||
printk(KERN_ERR "%s: failed to alloc mem\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dmac->dev.id = chno / 8;
|
||||
dmac->dev.bus = &dma_subsys;
|
||||
|
||||
err = device_register(&dmac->dev);
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: failed to register device\n", __func__);
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
regs = ioremap(base, 0x200);
|
||||
if (!regs) {
|
||||
printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
|
||||
err = -ENXIO;
|
||||
goto err_dev;
|
||||
}
|
||||
|
||||
snprintf(clkname, sizeof(clkname), "dma%d", dmac->dev.id);
|
||||
|
||||
dmac->clk = clk_get(NULL, clkname);
|
||||
if (IS_ERR(dmac->clk)) {
|
||||
printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname);
|
||||
err = PTR_ERR(dmac->clk);
|
||||
goto err_map;
|
||||
}
|
||||
|
||||
clk_prepare_enable(dmac->clk);
|
||||
|
||||
dmac->regs = regs;
|
||||
dmac->chanbase = chbase;
|
||||
dmac->channels = chptr;
|
||||
|
||||
err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac);
|
||||
if (err < 0) {
|
||||
printk(KERN_ERR "%s: failed to get irq\n", __func__);
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
regptr = regs + PL080_Cx_BASE(0);
|
||||
|
||||
for (ch = 0; ch < 8; ch++, chptr++) {
|
||||
pr_debug("%s: registering DMA %d (%p)\n",
|
||||
__func__, chno + ch, regptr);
|
||||
|
||||
chptr->bit = 1 << ch;
|
||||
chptr->number = chno + ch;
|
||||
chptr->dmac = dmac;
|
||||
chptr->regs = regptr;
|
||||
regptr += PL080_Cx_STRIDE;
|
||||
}
|
||||
|
||||
/* for the moment, permanently enable the controller */
|
||||
writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG);
|
||||
|
||||
printk(KERN_INFO "PL080: IRQ %d, at %p, channels %d..%d\n",
|
||||
irq, regs, chno, chno+8);
|
||||
|
||||
return 0;
|
||||
|
||||
err_clk:
|
||||
clk_disable_unprepare(dmac->clk);
|
||||
clk_put(dmac->clk);
|
||||
err_map:
|
||||
iounmap(regs);
|
||||
err_dev:
|
||||
device_unregister(&dmac->dev);
|
||||
err_alloc:
|
||||
kfree(dmac);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __init s3c64xx_dma_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* This driver is not supported when booting with device tree. */
|
||||
if (of_have_populated_dt())
|
||||
return -ENODEV;
|
||||
|
||||
printk(KERN_INFO "%s: Registering DMA channels\n", __func__);
|
||||
|
||||
dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0);
|
||||
if (!dma_pool) {
|
||||
printk(KERN_ERR "%s: failed to create pool\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = subsys_system_register(&dma_subsys, NULL);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s: failed to create subsys\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Set all DMA configuration to be DMA, not SDMA */
|
||||
writel(0xffffff, S3C64XX_SDMA_SEL);
|
||||
|
||||
/* Register standard DMA controllers */
|
||||
s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000);
|
||||
s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(s3c64xx_dma_init);
|
@ -11,51 +11,48 @@
|
||||
#ifndef __ASM_ARCH_DMA_H
|
||||
#define __ASM_ARCH_DMA_H __FILE__
|
||||
|
||||
#define S3C_DMA_CHANNELS (16)
|
||||
#define S3C64XX_DMA_CHAN(name) ((unsigned long)(name))
|
||||
|
||||
/* see mach-s3c2410/dma.h for notes on dma channel numbers */
|
||||
/* DMA0/SDMA0 */
|
||||
#define DMACH_UART0 S3C64XX_DMA_CHAN("uart0_tx")
|
||||
#define DMACH_UART0_SRC2 S3C64XX_DMA_CHAN("uart0_rx")
|
||||
#define DMACH_UART1 S3C64XX_DMA_CHAN("uart1_tx")
|
||||
#define DMACH_UART1_SRC2 S3C64XX_DMA_CHAN("uart1_rx")
|
||||
#define DMACH_UART2 S3C64XX_DMA_CHAN("uart2_tx")
|
||||
#define DMACH_UART2_SRC2 S3C64XX_DMA_CHAN("uart2_rx")
|
||||
#define DMACH_UART3 S3C64XX_DMA_CHAN("uart3_tx")
|
||||
#define DMACH_UART3_SRC2 S3C64XX_DMA_CHAN("uart3_rx")
|
||||
#define DMACH_PCM0_TX S3C64XX_DMA_CHAN("pcm0_tx")
|
||||
#define DMACH_PCM0_RX S3C64XX_DMA_CHAN("pcm0_rx")
|
||||
#define DMACH_I2S0_OUT S3C64XX_DMA_CHAN("i2s0_tx")
|
||||
#define DMACH_I2S0_IN S3C64XX_DMA_CHAN("i2s0_rx")
|
||||
#define DMACH_SPI0_TX S3C64XX_DMA_CHAN("spi0_tx")
|
||||
#define DMACH_SPI0_RX S3C64XX_DMA_CHAN("spi0_rx")
|
||||
#define DMACH_HSI_I2SV40_TX S3C64XX_DMA_CHAN("i2s2_tx")
|
||||
#define DMACH_HSI_I2SV40_RX S3C64XX_DMA_CHAN("i2s2_rx")
|
||||
|
||||
/* DMA1/SDMA1 */
|
||||
#define DMACH_PCM1_TX S3C64XX_DMA_CHAN("pcm1_tx")
|
||||
#define DMACH_PCM1_RX S3C64XX_DMA_CHAN("pcm1_rx")
|
||||
#define DMACH_I2S1_OUT S3C64XX_DMA_CHAN("i2s1_tx")
|
||||
#define DMACH_I2S1_IN S3C64XX_DMA_CHAN("i2s1_rx")
|
||||
#define DMACH_SPI1_TX S3C64XX_DMA_CHAN("spi1_tx")
|
||||
#define DMACH_SPI1_RX S3C64XX_DMA_CHAN("spi1_rx")
|
||||
#define DMACH_AC97_PCMOUT S3C64XX_DMA_CHAN("ac97_out")
|
||||
#define DMACH_AC97_PCMIN S3C64XX_DMA_CHAN("ac97_in")
|
||||
#define DMACH_AC97_MICIN S3C64XX_DMA_CHAN("ac97_mic")
|
||||
#define DMACH_PWM S3C64XX_DMA_CHAN("pwm")
|
||||
#define DMACH_IRDA S3C64XX_DMA_CHAN("irda")
|
||||
#define DMACH_EXTERNAL S3C64XX_DMA_CHAN("external")
|
||||
#define DMACH_SECURITY_RX S3C64XX_DMA_CHAN("sec_rx")
|
||||
#define DMACH_SECURITY_TX S3C64XX_DMA_CHAN("sec_tx")
|
||||
|
||||
/* Note, for the S3C64XX architecture we keep the DMACH_
|
||||
* defines in the order they are allocated to [S]DMA0/[S]DMA1
|
||||
* so that is easy to do DHACH_ -> DMA controller conversion
|
||||
*/
|
||||
enum dma_ch {
|
||||
/* DMA0/SDMA0 */
|
||||
DMACH_UART0 = 0,
|
||||
DMACH_UART0_SRC2,
|
||||
DMACH_UART1,
|
||||
DMACH_UART1_SRC2,
|
||||
DMACH_UART2,
|
||||
DMACH_UART2_SRC2,
|
||||
DMACH_UART3,
|
||||
DMACH_UART3_SRC2,
|
||||
DMACH_PCM0_TX,
|
||||
DMACH_PCM0_RX,
|
||||
DMACH_I2S0_OUT,
|
||||
DMACH_I2S0_IN,
|
||||
DMACH_SPI0_TX,
|
||||
DMACH_SPI0_RX,
|
||||
DMACH_HSI_I2SV40_TX,
|
||||
DMACH_HSI_I2SV40_RX,
|
||||
DMACH_MAX = 32
|
||||
};
|
||||
|
||||
/* DMA1/SDMA1 */
|
||||
DMACH_PCM1_TX = 16,
|
||||
DMACH_PCM1_RX,
|
||||
DMACH_I2S1_OUT,
|
||||
DMACH_I2S1_IN,
|
||||
DMACH_SPI1_TX,
|
||||
DMACH_SPI1_RX,
|
||||
DMACH_AC97_PCMOUT,
|
||||
DMACH_AC97_PCMIN,
|
||||
DMACH_AC97_MICIN,
|
||||
DMACH_PWM,
|
||||
DMACH_IRDA,
|
||||
DMACH_EXTERNAL,
|
||||
DMACH_RES1,
|
||||
DMACH_RES2,
|
||||
DMACH_SECURITY_RX, /* SDMA1 only */
|
||||
DMACH_SECURITY_TX, /* SDMA1 only */
|
||||
DMACH_MAX /* the end */
|
||||
struct s3c2410_dma_client {
|
||||
char *name;
|
||||
};
|
||||
|
||||
static inline bool samsung_dma_has_circular(void)
|
||||
@ -65,67 +62,10 @@ static inline bool samsung_dma_has_circular(void)
|
||||
|
||||
static inline bool samsung_dma_is_dmadev(void)
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#define S3C2410_DMAF_CIRCULAR (1 << 0)
|
||||
|
||||
#include <plat/dma.h>
|
||||
|
||||
#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
|
||||
|
||||
struct s3c64xx_dma_buff;
|
||||
|
||||
/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor
|
||||
* @next: Pointer to next buffer in queue or ring.
|
||||
* @pw: Client provided identifier
|
||||
* @lli: Pointer to hardware descriptor this buffer is associated with.
|
||||
* @lli_dma: Hardare address of the descriptor.
|
||||
*/
|
||||
struct s3c64xx_dma_buff {
|
||||
struct s3c64xx_dma_buff *next;
|
||||
|
||||
void *pw;
|
||||
struct pl080s_lli *lli;
|
||||
dma_addr_t lli_dma;
|
||||
};
|
||||
|
||||
struct s3c64xx_dmac;
|
||||
|
||||
struct s3c2410_dma_chan {
|
||||
unsigned char number; /* number of this dma channel */
|
||||
unsigned char in_use; /* channel allocated */
|
||||
unsigned char bit; /* bit for enable/disable/etc */
|
||||
unsigned char hw_width;
|
||||
unsigned char peripheral;
|
||||
|
||||
unsigned int flags;
|
||||
enum dma_data_direction source;
|
||||
|
||||
|
||||
dma_addr_t dev_addr;
|
||||
|
||||
struct s3c2410_dma_client *client;
|
||||
struct s3c64xx_dmac *dmac; /* pointer to controller */
|
||||
|
||||
void __iomem *regs;
|
||||
|
||||
/* cdriver callbacks */
|
||||
s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */
|
||||
s3c2410_dma_opfn_t op_fn; /* channel op callback */
|
||||
|
||||
/* buffer list and information */
|
||||
struct s3c64xx_dma_buff *curr; /* current dma buffer */
|
||||
struct s3c64xx_dma_buff *next; /* next buffer to load */
|
||||
struct s3c64xx_dma_buff *end; /* end of queue */
|
||||
|
||||
/* note, when channel is running in circular mode, curr is the
|
||||
* first buffer enqueued, end is the last and curr is where the
|
||||
* last buffer-done event is set-at. The buffers are not freed
|
||||
* and the last buffer hardware descriptor points back to the
|
||||
* first.
|
||||
*/
|
||||
};
|
||||
|
||||
#include <plat/dma-core.h>
|
||||
#include <linux/amba/pl08x.h>
|
||||
#include <plat/dma-ops.h>
|
||||
|
||||
#endif /* __ASM_ARCH_IRQ_H */
|
||||
|
244
arch/arm/mach-s3c64xx/pl080.c
Normal file
244
arch/arm/mach-s3c64xx/pl080.c
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Samsung's S3C64XX generic DMA support using amba-pl08x driver.
|
||||
*
|
||||
* Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/amba/bus.h>
|
||||
#include <linux/amba/pl080.h>
|
||||
#include <linux/amba/pl08x.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/map.h>
|
||||
|
||||
#include "regs-sys.h"
|
||||
|
||||
static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd)
|
||||
{
|
||||
return cd->min_signal;
|
||||
}
|
||||
|
||||
static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* DMA0
|
||||
*/
|
||||
|
||||
static struct pl08x_channel_data s3c64xx_dma0_info[] = {
|
||||
{
|
||||
.bus_id = "uart0_tx",
|
||||
.min_signal = 0,
|
||||
.max_signal = 0,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "uart0_rx",
|
||||
.min_signal = 1,
|
||||
.max_signal = 1,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "uart1_tx",
|
||||
.min_signal = 2,
|
||||
.max_signal = 2,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "uart1_rx",
|
||||
.min_signal = 3,
|
||||
.max_signal = 3,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "uart2_tx",
|
||||
.min_signal = 4,
|
||||
.max_signal = 4,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "uart2_rx",
|
||||
.min_signal = 5,
|
||||
.max_signal = 5,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "uart3_tx",
|
||||
.min_signal = 6,
|
||||
.max_signal = 6,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "uart3_rx",
|
||||
.min_signal = 7,
|
||||
.max_signal = 7,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "pcm0_tx",
|
||||
.min_signal = 8,
|
||||
.max_signal = 8,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "pcm0_rx",
|
||||
.min_signal = 9,
|
||||
.max_signal = 9,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "i2s0_tx",
|
||||
.min_signal = 10,
|
||||
.max_signal = 10,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "i2s0_rx",
|
||||
.min_signal = 11,
|
||||
.max_signal = 11,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "spi0_tx",
|
||||
.min_signal = 12,
|
||||
.max_signal = 12,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "spi0_rx",
|
||||
.min_signal = 13,
|
||||
.max_signal = 13,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "i2s2_tx",
|
||||
.min_signal = 14,
|
||||
.max_signal = 14,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "i2s2_rx",
|
||||
.min_signal = 15,
|
||||
.max_signal = 15,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}
|
||||
};
|
||||
|
||||
struct pl08x_platform_data s3c64xx_dma0_plat_data = {
|
||||
.memcpy_channel = {
|
||||
.bus_id = "memcpy",
|
||||
.cctl_memcpy =
|
||||
(PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT |
|
||||
PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT |
|
||||
PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT |
|
||||
PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT |
|
||||
PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE |
|
||||
PL080_CONTROL_PROT_SYS),
|
||||
},
|
||||
.lli_buses = PL08X_AHB1,
|
||||
.mem_buses = PL08X_AHB1,
|
||||
.get_xfer_signal = pl08x_get_xfer_signal,
|
||||
.put_xfer_signal = pl08x_put_xfer_signal,
|
||||
.slave_channels = s3c64xx_dma0_info,
|
||||
.num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info),
|
||||
};
|
||||
|
||||
static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0,
|
||||
0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data);
|
||||
|
||||
/*
|
||||
* DMA1
|
||||
*/
|
||||
|
||||
static struct pl08x_channel_data s3c64xx_dma1_info[] = {
|
||||
{
|
||||
.bus_id = "pcm1_tx",
|
||||
.min_signal = 0,
|
||||
.max_signal = 0,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "pcm1_rx",
|
||||
.min_signal = 1,
|
||||
.max_signal = 1,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "i2s1_tx",
|
||||
.min_signal = 2,
|
||||
.max_signal = 2,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "i2s1_rx",
|
||||
.min_signal = 3,
|
||||
.max_signal = 3,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "spi1_tx",
|
||||
.min_signal = 4,
|
||||
.max_signal = 4,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "spi1_rx",
|
||||
.min_signal = 5,
|
||||
.max_signal = 5,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "ac97_out",
|
||||
.min_signal = 6,
|
||||
.max_signal = 6,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "ac97_in",
|
||||
.min_signal = 7,
|
||||
.max_signal = 7,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "ac97_mic",
|
||||
.min_signal = 8,
|
||||
.max_signal = 8,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "pwm",
|
||||
.min_signal = 9,
|
||||
.max_signal = 9,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "irda",
|
||||
.min_signal = 10,
|
||||
.max_signal = 10,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
}, {
|
||||
.bus_id = "external",
|
||||
.min_signal = 11,
|
||||
.max_signal = 11,
|
||||
.periph_buses = PL08X_AHB2,
|
||||
},
|
||||
};
|
||||
|
||||
struct pl08x_platform_data s3c64xx_dma1_plat_data = {
|
||||
.memcpy_channel = {
|
||||
.bus_id = "memcpy",
|
||||
.cctl_memcpy =
|
||||
(PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT |
|
||||
PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT |
|
||||
PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT |
|
||||
PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT |
|
||||
PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE |
|
||||
PL080_CONTROL_PROT_SYS),
|
||||
},
|
||||
.lli_buses = PL08X_AHB1,
|
||||
.mem_buses = PL08X_AHB1,
|
||||
.get_xfer_signal = pl08x_get_xfer_signal,
|
||||
.put_xfer_signal = pl08x_put_xfer_signal,
|
||||
.slave_channels = s3c64xx_dma1_info,
|
||||
.num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info),
|
||||
};
|
||||
|
||||
static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
|
||||
0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data);
|
||||
|
||||
static int __init s3c64xx_pl080_init(void)
|
||||
{
|
||||
/* Set all DMA configuration to be DMA, not SDMA */
|
||||
writel(0xffffff, S3C64XX_SDMA_SEL);
|
||||
|
||||
if (of_have_populated_dt())
|
||||
return 0;
|
||||
|
||||
amba_device_register(&s3c64xx_dma0_device, &iomem_resource);
|
||||
amba_device_register(&s3c64xx_dma1_device, &iomem_resource);
|
||||
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(s3c64xx_pl080_init);
|
@ -31,7 +31,7 @@ static struct stedma40_chan_cfg msp0_dma_tx = {
|
||||
};
|
||||
|
||||
struct msp_i2s_platform_data msp0_platform_data = {
|
||||
.id = MSP_I2S_0,
|
||||
.id = 0,
|
||||
.msp_i2s_dma_rx = &msp0_dma_rx,
|
||||
.msp_i2s_dma_tx = &msp0_dma_tx,
|
||||
};
|
||||
@ -49,7 +49,7 @@ static struct stedma40_chan_cfg msp1_dma_tx = {
|
||||
};
|
||||
|
||||
struct msp_i2s_platform_data msp1_platform_data = {
|
||||
.id = MSP_I2S_1,
|
||||
.id = 1,
|
||||
.msp_i2s_dma_rx = NULL,
|
||||
.msp_i2s_dma_tx = &msp1_dma_tx,
|
||||
};
|
||||
@ -69,13 +69,13 @@ static struct stedma40_chan_cfg msp2_dma_tx = {
|
||||
};
|
||||
|
||||
struct msp_i2s_platform_data msp2_platform_data = {
|
||||
.id = MSP_I2S_2,
|
||||
.id = 2,
|
||||
.msp_i2s_dma_rx = &msp2_dma_rx,
|
||||
.msp_i2s_dma_tx = &msp2_dma_tx,
|
||||
};
|
||||
|
||||
struct msp_i2s_platform_data msp3_platform_data = {
|
||||
.id = MSP_I2S_3,
|
||||
.id = 3,
|
||||
.msp_i2s_dma_rx = &msp1_dma_rx,
|
||||
.msp_i2s_dma_tx = NULL,
|
||||
};
|
||||
|
@ -1468,6 +1468,8 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
|
||||
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
|
||||
#if defined(CONFIG_PL330_DMA)
|
||||
pd.filter = pl330_filter;
|
||||
#elif defined(CONFIG_S3C64XX_PL080)
|
||||
pd.filter = pl08x_filter_id;
|
||||
#elif defined(CONFIG_S3C24XX_DMAC)
|
||||
pd.filter = s3c24xx_dma_filter;
|
||||
#endif
|
||||
@ -1509,8 +1511,10 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
|
||||
pd.num_cs = num_cs;
|
||||
pd.src_clk_nr = src_clk_nr;
|
||||
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio;
|
||||
#ifdef CONFIG_PL330_DMA
|
||||
#if defined(CONFIG_PL330_DMA)
|
||||
pd.filter = pl330_filter;
|
||||
#elif defined(CONFIG_S3C64XX_PL080)
|
||||
pd.filter = pl08x_filter_id;
|
||||
#endif
|
||||
|
||||
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1);
|
||||
@ -1550,8 +1554,10 @@ void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
|
||||
pd.num_cs = num_cs;
|
||||
pd.src_clk_nr = src_clk_nr;
|
||||
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio;
|
||||
#ifdef CONFIG_PL330_DMA
|
||||
#if defined(CONFIG_PL330_DMA)
|
||||
pd.filter = pl330_filter;
|
||||
#elif defined(CONFIG_S3C64XX_PL080)
|
||||
pd.filter = pl08x_filter_id;
|
||||
#endif
|
||||
|
||||
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2);
|
||||
|
@ -18,6 +18,12 @@
|
||||
|
||||
#include <mach/dma.h>
|
||||
|
||||
#if defined(CONFIG_PL330_DMA)
|
||||
#define dma_filter pl330_filter
|
||||
#elif defined(CONFIG_S3C64XX_PL080)
|
||||
#define dma_filter pl08x_filter_id
|
||||
#endif
|
||||
|
||||
static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
|
||||
struct samsung_dma_req *param,
|
||||
struct device *dev, char *ch_name)
|
||||
@ -30,7 +36,7 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
|
||||
if (dev->of_node)
|
||||
return (unsigned)dma_request_slave_channel(dev, ch_name);
|
||||
else
|
||||
return (unsigned)dma_request_channel(mask, pl330_filter,
|
||||
return (unsigned)dma_request_channel(mask, dma_filter,
|
||||
(void *)dma_ch);
|
||||
}
|
||||
|
||||
|
@ -331,8 +331,8 @@ static struct samsung_clock_alias s3c64xx_clock_aliases[] = {
|
||||
ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
|
||||
ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
|
||||
ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
|
||||
ALIAS(HCLK_DMA1, NULL, "dma1"),
|
||||
ALIAS(HCLK_DMA0, NULL, "dma0"),
|
||||
ALIAS(HCLK_DMA1, "dma-pl080s.1", "apb_pclk"),
|
||||
ALIAS(HCLK_DMA0, "dma-pl080s.0", "apb_pclk"),
|
||||
ALIAS(HCLK_CAMIF, "s3c-camif", "camif"),
|
||||
ALIAS(HCLK_LCD, "s3c-fb", "lcd"),
|
||||
ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"),
|
||||
|
@ -540,6 +540,8 @@ EXPORT_SYMBOL_GPL(dma_get_slave_channel);
|
||||
* @mask: capabilities that the channel must satisfy
|
||||
* @fn: optional callback to disposition available channels
|
||||
* @fn_param: opaque parameter to pass to dma_filter_fn
|
||||
*
|
||||
* Returns pointer to appropriate DMA channel on success or NULL.
|
||||
*/
|
||||
struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
|
||||
dma_filter_fn fn, void *fn_param)
|
||||
@ -591,18 +593,43 @@ EXPORT_SYMBOL_GPL(__dma_request_channel);
|
||||
* dma_request_slave_channel - try to allocate an exclusive slave channel
|
||||
* @dev: pointer to client device structure
|
||||
* @name: slave channel name
|
||||
*
|
||||
* Returns pointer to appropriate DMA channel on success or an error pointer.
|
||||
*/
|
||||
struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name)
|
||||
struct dma_chan *dma_request_slave_channel_reason(struct device *dev,
|
||||
const char *name)
|
||||
{
|
||||
struct dma_chan *chan;
|
||||
|
||||
/* If device-tree is present get slave info from here */
|
||||
if (dev->of_node)
|
||||
return of_dma_request_slave_channel(dev->of_node, name);
|
||||
|
||||
/* If device was enumerated by ACPI get slave info from here */
|
||||
if (ACPI_HANDLE(dev))
|
||||
return acpi_dma_request_slave_chan_by_name(dev, name);
|
||||
if (ACPI_HANDLE(dev)) {
|
||||
chan = acpi_dma_request_slave_chan_by_name(dev, name);
|
||||
if (chan)
|
||||
return chan;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dma_request_slave_channel_reason);
|
||||
|
||||
/**
|
||||
* dma_request_slave_channel - try to allocate an exclusive slave channel
|
||||
* @dev: pointer to client device structure
|
||||
* @name: slave channel name
|
||||
*
|
||||
* Returns pointer to appropriate DMA channel on success or NULL.
|
||||
*/
|
||||
struct dma_chan *dma_request_slave_channel(struct device *dev,
|
||||
const char *name)
|
||||
{
|
||||
struct dma_chan *ch = dma_request_slave_channel_reason(dev, name);
|
||||
if (IS_ERR(ch))
|
||||
return NULL;
|
||||
return ch;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dma_request_slave_channel);
|
||||
|
||||
|
@ -143,7 +143,7 @@ static int of_dma_match_channel(struct device_node *np, const char *name,
|
||||
* @np: device node to get DMA request from
|
||||
* @name: name of desired channel
|
||||
*
|
||||
* Returns pointer to appropriate dma channel on success or NULL on error.
|
||||
* Returns pointer to appropriate DMA channel on success or an error pointer.
|
||||
*/
|
||||
struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
|
||||
const char *name)
|
||||
@ -152,17 +152,18 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
|
||||
struct of_dma *ofdma;
|
||||
struct dma_chan *chan;
|
||||
int count, i;
|
||||
int ret_no_channel = -ENODEV;
|
||||
|
||||
if (!np || !name) {
|
||||
pr_err("%s: not enough information provided\n", __func__);
|
||||
return NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
count = of_property_count_strings(np, "dma-names");
|
||||
if (count < 0) {
|
||||
pr_err("%s: dma-names property of node '%s' missing or empty\n",
|
||||
__func__, np->full_name);
|
||||
return NULL;
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
@ -172,10 +173,12 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
|
||||
mutex_lock(&of_dma_lock);
|
||||
ofdma = of_dma_find_controller(&dma_spec);
|
||||
|
||||
if (ofdma)
|
||||
if (ofdma) {
|
||||
chan = ofdma->of_dma_xlate(&dma_spec, ofdma);
|
||||
else
|
||||
} else {
|
||||
ret_no_channel = -EPROBE_DEFER;
|
||||
chan = NULL;
|
||||
}
|
||||
|
||||
mutex_unlock(&of_dma_lock);
|
||||
|
||||
@ -185,7 +188,7 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
|
||||
return chan;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return ERR_PTR(ret_no_channel);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2884,6 +2884,7 @@ static int pl330_dma_device_slave_caps(struct dma_chan *dchan,
|
||||
caps->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
|
||||
caps->cmd_pause = false;
|
||||
caps->cmd_terminate = true;
|
||||
caps->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -47,6 +47,9 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
|
||||
/* Register descriptions for audio */
|
||||
#include <linux/mfd/twl4030-audio.h>
|
||||
|
||||
#include "twl-core.h"
|
||||
|
||||
/*
|
||||
@ -200,6 +203,105 @@ static struct twl_mapping twl4030_map[] = {
|
||||
{ 2, TWL5031_BASEADD_INTERRUPTS },
|
||||
};
|
||||
|
||||
static struct reg_default twl4030_49_defaults[] = {
|
||||
/* Audio Registers */
|
||||
{ 0x01, 0x00}, /* CODEC_MODE */
|
||||
{ 0x02, 0x00}, /* OPTION */
|
||||
/* 0x03 Unused */
|
||||
{ 0x04, 0x00}, /* MICBIAS_CTL */
|
||||
{ 0x05, 0x00}, /* ANAMICL */
|
||||
{ 0x06, 0x00}, /* ANAMICR */
|
||||
{ 0x07, 0x00}, /* AVADC_CTL */
|
||||
{ 0x08, 0x00}, /* ADCMICSEL */
|
||||
{ 0x09, 0x00}, /* DIGMIXING */
|
||||
{ 0x0a, 0x0f}, /* ATXL1PGA */
|
||||
{ 0x0b, 0x0f}, /* ATXR1PGA */
|
||||
{ 0x0c, 0x0f}, /* AVTXL2PGA */
|
||||
{ 0x0d, 0x0f}, /* AVTXR2PGA */
|
||||
{ 0x0e, 0x00}, /* AUDIO_IF */
|
||||
{ 0x0f, 0x00}, /* VOICE_IF */
|
||||
{ 0x10, 0x3f}, /* ARXR1PGA */
|
||||
{ 0x11, 0x3f}, /* ARXL1PGA */
|
||||
{ 0x12, 0x3f}, /* ARXR2PGA */
|
||||
{ 0x13, 0x3f}, /* ARXL2PGA */
|
||||
{ 0x14, 0x25}, /* VRXPGA */
|
||||
{ 0x15, 0x00}, /* VSTPGA */
|
||||
{ 0x16, 0x00}, /* VRX2ARXPGA */
|
||||
{ 0x17, 0x00}, /* AVDAC_CTL */
|
||||
{ 0x18, 0x00}, /* ARX2VTXPGA */
|
||||
{ 0x19, 0x32}, /* ARXL1_APGA_CTL*/
|
||||
{ 0x1a, 0x32}, /* ARXR1_APGA_CTL*/
|
||||
{ 0x1b, 0x32}, /* ARXL2_APGA_CTL*/
|
||||
{ 0x1c, 0x32}, /* ARXR2_APGA_CTL*/
|
||||
{ 0x1d, 0x00}, /* ATX2ARXPGA */
|
||||
{ 0x1e, 0x00}, /* BT_IF */
|
||||
{ 0x1f, 0x55}, /* BTPGA */
|
||||
{ 0x20, 0x00}, /* BTSTPGA */
|
||||
{ 0x21, 0x00}, /* EAR_CTL */
|
||||
{ 0x22, 0x00}, /* HS_SEL */
|
||||
{ 0x23, 0x00}, /* HS_GAIN_SET */
|
||||
{ 0x24, 0x00}, /* HS_POPN_SET */
|
||||
{ 0x25, 0x00}, /* PREDL_CTL */
|
||||
{ 0x26, 0x00}, /* PREDR_CTL */
|
||||
{ 0x27, 0x00}, /* PRECKL_CTL */
|
||||
{ 0x28, 0x00}, /* PRECKR_CTL */
|
||||
{ 0x29, 0x00}, /* HFL_CTL */
|
||||
{ 0x2a, 0x00}, /* HFR_CTL */
|
||||
{ 0x2b, 0x05}, /* ALC_CTL */
|
||||
{ 0x2c, 0x00}, /* ALC_SET1 */
|
||||
{ 0x2d, 0x00}, /* ALC_SET2 */
|
||||
{ 0x2e, 0x00}, /* BOOST_CTL */
|
||||
{ 0x2f, 0x00}, /* SOFTVOL_CTL */
|
||||
{ 0x30, 0x13}, /* DTMF_FREQSEL */
|
||||
{ 0x31, 0x00}, /* DTMF_TONEXT1H */
|
||||
{ 0x32, 0x00}, /* DTMF_TONEXT1L */
|
||||
{ 0x33, 0x00}, /* DTMF_TONEXT2H */
|
||||
{ 0x34, 0x00}, /* DTMF_TONEXT2L */
|
||||
{ 0x35, 0x79}, /* DTMF_TONOFF */
|
||||
{ 0x36, 0x11}, /* DTMF_WANONOFF */
|
||||
{ 0x37, 0x00}, /* I2S_RX_SCRAMBLE_H */
|
||||
{ 0x38, 0x00}, /* I2S_RX_SCRAMBLE_M */
|
||||
{ 0x39, 0x00}, /* I2S_RX_SCRAMBLE_L */
|
||||
{ 0x3a, 0x06}, /* APLL_CTL */
|
||||
{ 0x3b, 0x00}, /* DTMF_CTL */
|
||||
{ 0x3c, 0x44}, /* DTMF_PGA_CTL2 (0x3C) */
|
||||
{ 0x3d, 0x69}, /* DTMF_PGA_CTL1 (0x3D) */
|
||||
{ 0x3e, 0x00}, /* MISC_SET_1 */
|
||||
{ 0x3f, 0x00}, /* PCMBTMUX */
|
||||
/* 0x40 - 0x42 Unused */
|
||||
{ 0x43, 0x00}, /* RX_PATH_SEL */
|
||||
{ 0x44, 0x32}, /* VDL_APGA_CTL */
|
||||
{ 0x45, 0x00}, /* VIBRA_CTL */
|
||||
{ 0x46, 0x00}, /* VIBRA_SET */
|
||||
{ 0x47, 0x00}, /* VIBRA_PWM_SET */
|
||||
{ 0x48, 0x00}, /* ANAMIC_GAIN */
|
||||
{ 0x49, 0x00}, /* MISC_SET_2 */
|
||||
/* End of Audio Registers */
|
||||
};
|
||||
|
||||
static bool twl4030_49_nop_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case 0:
|
||||
case 3:
|
||||
case 40:
|
||||
case 41:
|
||||
case 42:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct regmap_range twl4030_49_volatile_ranges[] = {
|
||||
regmap_reg_range(TWL4030_BASEADD_TEST, 0xff),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table twl4030_49_volatile_table = {
|
||||
.yes_ranges = twl4030_49_volatile_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(twl4030_49_volatile_ranges),
|
||||
};
|
||||
|
||||
static struct regmap_config twl4030_regmap_config[4] = {
|
||||
{
|
||||
/* Address 0x48 */
|
||||
@ -212,6 +314,15 @@ static struct regmap_config twl4030_regmap_config[4] = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = 0xff,
|
||||
|
||||
.readable_reg = twl4030_49_nop_reg,
|
||||
.writeable_reg = twl4030_49_nop_reg,
|
||||
|
||||
.volatile_table = &twl4030_49_volatile_table,
|
||||
|
||||
.reg_defaults = twl4030_49_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(twl4030_49_defaults),
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
},
|
||||
{
|
||||
/* Address 0x4a */
|
||||
@ -301,6 +412,32 @@ unsigned int twl_rev(void)
|
||||
}
|
||||
EXPORT_SYMBOL(twl_rev);
|
||||
|
||||
/**
|
||||
* twl_get_regmap - Get the regmap associated with the given module
|
||||
* @mod_no: module number
|
||||
*
|
||||
* Returns the regmap pointer or NULL in case of failure.
|
||||
*/
|
||||
static struct regmap *twl_get_regmap(u8 mod_no)
|
||||
{
|
||||
int sid;
|
||||
struct twl_client *twl;
|
||||
|
||||
if (unlikely(!twl_priv || !twl_priv->ready)) {
|
||||
pr_err("%s: not initialized\n", DRIVER_NAME);
|
||||
return NULL;
|
||||
}
|
||||
if (unlikely(mod_no >= twl_get_last_module())) {
|
||||
pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sid = twl_priv->twl_map[mod_no].sid;
|
||||
twl = &twl_priv->twl_modules[sid];
|
||||
|
||||
return twl->regmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* twl_i2c_write - Writes a n bit register in TWL4030/TWL5030/TWL60X0
|
||||
* @mod_no: module number
|
||||
@ -312,25 +449,14 @@ EXPORT_SYMBOL(twl_rev);
|
||||
*/
|
||||
int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
|
||||
{
|
||||
struct regmap *regmap = twl_get_regmap(mod_no);
|
||||
int ret;
|
||||
int sid;
|
||||
struct twl_client *twl;
|
||||
|
||||
if (unlikely(!twl_priv || !twl_priv->ready)) {
|
||||
pr_err("%s: not initialized\n", DRIVER_NAME);
|
||||
if (!regmap)
|
||||
return -EPERM;
|
||||
}
|
||||
if (unlikely(mod_no >= twl_get_last_module())) {
|
||||
pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
sid = twl_priv->twl_map[mod_no].sid;
|
||||
twl = &twl_priv->twl_modules[sid];
|
||||
|
||||
ret = regmap_bulk_write(twl->regmap,
|
||||
twl_priv->twl_map[mod_no].base + reg, value,
|
||||
num_bytes);
|
||||
ret = regmap_bulk_write(regmap, twl_priv->twl_map[mod_no].base + reg,
|
||||
value, num_bytes);
|
||||
|
||||
if (ret)
|
||||
pr_err("%s: Write failed (mod %d, reg 0x%02x count %d)\n",
|
||||
@ -351,25 +477,14 @@ EXPORT_SYMBOL(twl_i2c_write);
|
||||
*/
|
||||
int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
|
||||
{
|
||||
struct regmap *regmap = twl_get_regmap(mod_no);
|
||||
int ret;
|
||||
int sid;
|
||||
struct twl_client *twl;
|
||||
|
||||
if (unlikely(!twl_priv || !twl_priv->ready)) {
|
||||
pr_err("%s: not initialized\n", DRIVER_NAME);
|
||||
if (!regmap)
|
||||
return -EPERM;
|
||||
}
|
||||
if (unlikely(mod_no >= twl_get_last_module())) {
|
||||
pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
sid = twl_priv->twl_map[mod_no].sid;
|
||||
twl = &twl_priv->twl_modules[sid];
|
||||
|
||||
ret = regmap_bulk_read(twl->regmap,
|
||||
twl_priv->twl_map[mod_no].base + reg, value,
|
||||
num_bytes);
|
||||
ret = regmap_bulk_read(regmap, twl_priv->twl_map[mod_no].base + reg,
|
||||
value, num_bytes);
|
||||
|
||||
if (ret)
|
||||
pr_err("%s: Read failed (mod %d, reg 0x%02x count %d)\n",
|
||||
@ -379,6 +494,27 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
|
||||
}
|
||||
EXPORT_SYMBOL(twl_i2c_read);
|
||||
|
||||
/**
|
||||
* twl_regcache_bypass - Configure the regcache bypass for the regmap associated
|
||||
* with the module
|
||||
* @mod_no: module number
|
||||
* @enable: Regcache bypass state
|
||||
*
|
||||
* Returns 0 else failure.
|
||||
*/
|
||||
int twl_set_regcache_bypass(u8 mod_no, bool enable)
|
||||
{
|
||||
struct regmap *regmap = twl_get_regmap(mod_no);
|
||||
|
||||
if (!regmap)
|
||||
return -EPERM;
|
||||
|
||||
regcache_cache_bypass(regmap, enable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(twl_set_regcache_bypass);
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
|
@ -44,6 +44,54 @@
|
||||
#define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1)
|
||||
#define TWL6040_NUM_SUPPLIES (2)
|
||||
|
||||
static struct reg_default twl6040_defaults[] = {
|
||||
{ 0x01, 0x4B }, /* REG_ASICID (ro) */
|
||||
{ 0x02, 0x00 }, /* REG_ASICREV (ro) */
|
||||
{ 0x03, 0x00 }, /* REG_INTID */
|
||||
{ 0x04, 0x00 }, /* REG_INTMR */
|
||||
{ 0x05, 0x00 }, /* REG_NCPCTRL */
|
||||
{ 0x06, 0x00 }, /* REG_LDOCTL */
|
||||
{ 0x07, 0x60 }, /* REG_HPPLLCTL */
|
||||
{ 0x08, 0x00 }, /* REG_LPPLLCTL */
|
||||
{ 0x09, 0x4A }, /* REG_LPPLLDIV */
|
||||
{ 0x0A, 0x00 }, /* REG_AMICBCTL */
|
||||
{ 0x0B, 0x00 }, /* REG_DMICBCTL */
|
||||
{ 0x0C, 0x00 }, /* REG_MICLCTL */
|
||||
{ 0x0D, 0x00 }, /* REG_MICRCTL */
|
||||
{ 0x0E, 0x00 }, /* REG_MICGAIN */
|
||||
{ 0x0F, 0x1B }, /* REG_LINEGAIN */
|
||||
{ 0x10, 0x00 }, /* REG_HSLCTL */
|
||||
{ 0x11, 0x00 }, /* REG_HSRCTL */
|
||||
{ 0x12, 0x00 }, /* REG_HSGAIN */
|
||||
{ 0x13, 0x00 }, /* REG_EARCTL */
|
||||
{ 0x14, 0x00 }, /* REG_HFLCTL */
|
||||
{ 0x15, 0x00 }, /* REG_HFLGAIN */
|
||||
{ 0x16, 0x00 }, /* REG_HFRCTL */
|
||||
{ 0x17, 0x00 }, /* REG_HFRGAIN */
|
||||
{ 0x18, 0x00 }, /* REG_VIBCTLL */
|
||||
{ 0x19, 0x00 }, /* REG_VIBDATL */
|
||||
{ 0x1A, 0x00 }, /* REG_VIBCTLR */
|
||||
{ 0x1B, 0x00 }, /* REG_VIBDATR */
|
||||
{ 0x1C, 0x00 }, /* REG_HKCTL1 */
|
||||
{ 0x1D, 0x00 }, /* REG_HKCTL2 */
|
||||
{ 0x1E, 0x00 }, /* REG_GPOCTL */
|
||||
{ 0x1F, 0x00 }, /* REG_ALB */
|
||||
{ 0x20, 0x00 }, /* REG_DLB */
|
||||
/* 0x28, REG_TRIM1 */
|
||||
/* 0x29, REG_TRIM2 */
|
||||
/* 0x2A, REG_TRIM3 */
|
||||
/* 0x2B, REG_HSOTRIM */
|
||||
/* 0x2C, REG_HFOTRIM */
|
||||
{ 0x2D, 0x08 }, /* REG_ACCCTL */
|
||||
{ 0x2E, 0x00 }, /* REG_STATUS (ro) */
|
||||
};
|
||||
|
||||
struct reg_default twl6040_patch[] = {
|
||||
/* Select I2C bus access to dual access registers */
|
||||
{ TWL6040_REG_ACCCTL, 0x09 },
|
||||
};
|
||||
|
||||
|
||||
static bool twl6040_has_vibra(struct device_node *node)
|
||||
{
|
||||
#ifdef CONFIG_OF
|
||||
@ -238,6 +286,9 @@ int twl6040_power(struct twl6040 *twl6040, int on)
|
||||
if (twl6040->power_count++)
|
||||
goto out;
|
||||
|
||||
/* Allow writes to the chip */
|
||||
regcache_cache_only(twl6040->regmap, false);
|
||||
|
||||
if (gpio_is_valid(twl6040->audpwron)) {
|
||||
/* use automatic power-up sequence */
|
||||
ret = twl6040_power_up_automatic(twl6040);
|
||||
@ -253,6 +304,10 @@ int twl6040_power(struct twl6040 *twl6040, int on)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sync with the HW */
|
||||
regcache_sync(twl6040->regmap);
|
||||
|
||||
/* Default PLL configuration after power up */
|
||||
twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;
|
||||
twl6040->sysclk = 19200000;
|
||||
@ -279,6 +334,11 @@ int twl6040_power(struct twl6040 *twl6040, int on)
|
||||
/* use manual power-down sequence */
|
||||
twl6040_power_down_manual(twl6040);
|
||||
}
|
||||
|
||||
/* Set regmap to cache only and mark it as dirty */
|
||||
regcache_cache_only(twl6040->regmap, true);
|
||||
regcache_mark_dirty(twl6040->regmap);
|
||||
|
||||
twl6040->sysclk = 0;
|
||||
twl6040->mclk = 0;
|
||||
}
|
||||
@ -490,9 +550,24 @@ static bool twl6040_readable_reg(struct device *dev, unsigned int reg)
|
||||
static bool twl6040_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case TWL6040_REG_VIBCTLL:
|
||||
case TWL6040_REG_VIBCTLR:
|
||||
case TWL6040_REG_INTMR:
|
||||
case TWL6040_REG_ASICID:
|
||||
case TWL6040_REG_ASICREV:
|
||||
case TWL6040_REG_INTID:
|
||||
case TWL6040_REG_LPPLLCTL:
|
||||
case TWL6040_REG_HPPLLCTL:
|
||||
case TWL6040_REG_STATUS:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool twl6040_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case TWL6040_REG_ASICID:
|
||||
case TWL6040_REG_ASICREV:
|
||||
case TWL6040_REG_STATUS:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
@ -502,10 +577,15 @@ static bool twl6040_volatile_reg(struct device *dev, unsigned int reg)
|
||||
static struct regmap_config twl6040_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.reg_defaults = twl6040_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(twl6040_defaults),
|
||||
|
||||
.max_register = TWL6040_REG_STATUS, /* 0x2e */
|
||||
|
||||
.readable_reg = twl6040_readable_reg,
|
||||
.volatile_reg = twl6040_volatile_reg,
|
||||
.writeable_reg = twl6040_writeable_reg,
|
||||
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
@ -624,6 +704,8 @@ static int twl6040_probe(struct i2c_client *client,
|
||||
|
||||
/* dual-access registers controlled by I2C only */
|
||||
twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL);
|
||||
regmap_register_patch(twl6040->regmap, twl6040_patch,
|
||||
ARRAY_SIZE(twl6040_patch));
|
||||
|
||||
/*
|
||||
* The main functionality of twl6040 to provide audio on OMAP4+ systems.
|
||||
@ -656,6 +738,10 @@ static int twl6040_probe(struct i2c_client *client,
|
||||
cell->name = "twl6040-gpo";
|
||||
children++;
|
||||
|
||||
/* The chip is powered down so mark regmap to cache only and dirty */
|
||||
regcache_cache_only(twl6040->regmap, true);
|
||||
regcache_mark_dirty(twl6040->regmap);
|
||||
|
||||
ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
|
||||
NULL, 0, NULL);
|
||||
if (ret)
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include <linux/mfd/arizona/core.h>
|
||||
#include <linux/mfd/arizona/registers.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
#include "arizona.h"
|
||||
|
||||
@ -524,6 +525,7 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x00000300, 0x0000 }, /* R768 - Input Enables */
|
||||
{ 0x00000308, 0x0000 }, /* R776 - Input Rate */
|
||||
{ 0x00000309, 0x0022 }, /* R777 - Input Volume Ramp */
|
||||
{ 0x0000030C, 0x0002 }, /* R780 - HPF Control */
|
||||
{ 0x00000310, 0x2080 }, /* R784 - IN1L Control */
|
||||
{ 0x00000311, 0x0180 }, /* R785 - ADC Digital Volume 1L */
|
||||
{ 0x00000312, 0x0000 }, /* R786 - DMIC1L Control */
|
||||
@ -545,6 +547,7 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x00000328, 0x2000 }, /* R808 - IN4L Control */
|
||||
{ 0x00000329, 0x0180 }, /* R809 - ADC Digital Volume 4L */
|
||||
{ 0x0000032A, 0x0000 }, /* R810 - DMIC4L Control */
|
||||
{ 0x0000032C, 0x0000 }, /* R812 - IN4R Control */
|
||||
{ 0x0000032D, 0x0180 }, /* R813 - ADC Digital Volume 4R */
|
||||
{ 0x0000032E, 0x0000 }, /* R814 - DMIC4R Control */
|
||||
{ 0x00000400, 0x0000 }, /* R1024 - Output Enables 1 */
|
||||
@ -598,6 +601,7 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x0000043D, 0x0180 }, /* R1085 - DAC Digital Volume 6R */
|
||||
{ 0x0000043E, 0x0080 }, /* R1086 - DAC Volume Limit 6R */
|
||||
{ 0x0000043F, 0x0800 }, /* R1087 - Noise Gate Select 6R */
|
||||
{ 0x00000440, 0x8FFF }, /* R1088 - DRE Enable */
|
||||
{ 0x00000450, 0x0000 }, /* R1104 - DAC AEC Control 1 */
|
||||
{ 0x00000458, 0x0000 }, /* R1112 - Noise Gate Control */
|
||||
{ 0x00000480, 0x0040 }, /* R1152 - Class W ANC Threshold 1 */
|
||||
@ -606,6 +610,9 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x00000491, 0x0000 }, /* R1169 - PDM SPK1 CTRL 2 */
|
||||
{ 0x00000492, 0x0069 }, /* R1170 - PDM SPK2 CTRL 1 */
|
||||
{ 0x00000493, 0x0000 }, /* R1171 - PDM SPK2 CTRL 2 */
|
||||
{ 0x000004A0, 0x3480 }, /* R1184 - HP1 Short Circuit Ctrl */
|
||||
{ 0x000004A1, 0x3480 }, /* R1185 - HP2 Short Circuit Ctrl */
|
||||
{ 0x000004A2, 0x3480 }, /* R1186 - HP3 Short Circuit Ctrl */
|
||||
{ 0x00000500, 0x000C }, /* R1280 - AIF1 BCLK Ctrl */
|
||||
{ 0x00000501, 0x0008 }, /* R1281 - AIF1 Tx Pin Ctrl */
|
||||
{ 0x00000502, 0x0000 }, /* R1282 - AIF1 Rx Pin Ctrl */
|
||||
@ -882,6 +889,38 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x0000074D, 0x0080 }, /* R1869 - AIF2TX2MIX Input 3 Volume */
|
||||
{ 0x0000074E, 0x0000 }, /* R1870 - AIF2TX2MIX Input 4 Source */
|
||||
{ 0x0000074F, 0x0080 }, /* R1871 - AIF2TX2MIX Input 4 Volume */
|
||||
{ 0x00000750, 0x0000 }, /* R1872 - AIF2TX3MIX Input 1 Source */
|
||||
{ 0x00000751, 0x0080 }, /* R1873 - AIF2TX3MIX Input 1 Volume */
|
||||
{ 0x00000752, 0x0000 }, /* R1874 - AIF2TX3MIX Input 2 Source */
|
||||
{ 0x00000753, 0x0080 }, /* R1875 - AIF2TX3MIX Input 2 Volume */
|
||||
{ 0x00000754, 0x0000 }, /* R1876 - AIF2TX3MIX Input 3 Source */
|
||||
{ 0x00000755, 0x0080 }, /* R1877 - AIF2TX3MIX Input 3 Volume */
|
||||
{ 0x00000756, 0x0000 }, /* R1878 - AIF2TX3MIX Input 4 Source */
|
||||
{ 0x00000757, 0x0080 }, /* R1879 - AIF2TX3MIX Input 4 Volume */
|
||||
{ 0x00000758, 0x0000 }, /* R1880 - AIF2TX4MIX Input 1 Source */
|
||||
{ 0x00000759, 0x0080 }, /* R1881 - AIF2TX4MIX Input 1 Volume */
|
||||
{ 0x0000075A, 0x0000 }, /* R1882 - AIF2TX4MIX Input 2 Source */
|
||||
{ 0x0000075B, 0x0080 }, /* R1883 - AIF2TX4MIX Input 2 Volume */
|
||||
{ 0x0000075C, 0x0000 }, /* R1884 - AIF2TX4MIX Input 3 Source */
|
||||
{ 0x0000075D, 0x0080 }, /* R1885 - AIF2TX4MIX Input 3 Volume */
|
||||
{ 0x0000075E, 0x0000 }, /* R1886 - AIF2TX4MIX Input 4 Source */
|
||||
{ 0x0000075F, 0x0080 }, /* R1887 - AIF2TX4MIX Input 4 Volume */
|
||||
{ 0x00000760, 0x0000 }, /* R1888 - AIF2TX5MIX Input 1 Source */
|
||||
{ 0x00000761, 0x0080 }, /* R1889 - AIF2TX5MIX Input 1 Volume */
|
||||
{ 0x00000762, 0x0000 }, /* R1890 - AIF2TX5MIX Input 2 Source */
|
||||
{ 0x00000763, 0x0080 }, /* R1891 - AIF2TX5MIX Input 2 Volume */
|
||||
{ 0x00000764, 0x0000 }, /* R1892 - AIF2TX5MIX Input 3 Source */
|
||||
{ 0x00000765, 0x0080 }, /* R1893 - AIF2TX5MIX Input 3 Volume */
|
||||
{ 0x00000766, 0x0000 }, /* R1894 - AIF2TX5MIX Input 4 Source */
|
||||
{ 0x00000767, 0x0080 }, /* R1895 - AIF2TX5MIX Input 4 Volume */
|
||||
{ 0x00000768, 0x0000 }, /* R1896 - AIF2TX6MIX Input 1 Source */
|
||||
{ 0x00000769, 0x0080 }, /* R1897 - AIF2TX6MIX Input 1 Volume */
|
||||
{ 0x0000076A, 0x0000 }, /* R1898 - AIF2TX6MIX Input 2 Source */
|
||||
{ 0x0000076B, 0x0080 }, /* R1899 - AIF2TX6MIX Input 2 Volume */
|
||||
{ 0x0000076C, 0x0000 }, /* R1900 - AIF2TX6MIX Input 3 Source */
|
||||
{ 0x0000076D, 0x0080 }, /* R1901 - AIF2TX6MIX Input 3 Volume */
|
||||
{ 0x0000076E, 0x0000 }, /* R1902 - AIF2TX6MIX Input 4 Source */
|
||||
{ 0x0000076F, 0x0080 }, /* R1903 - AIF2TX6MIX Input 4 Volume */
|
||||
{ 0x00000780, 0x0000 }, /* R1920 - AIF3TX1MIX Input 1 Source */
|
||||
{ 0x00000781, 0x0080 }, /* R1921 - AIF3TX1MIX Input 1 Volume */
|
||||
{ 0x00000782, 0x0000 }, /* R1922 - AIF3TX1MIX Input 2 Source */
|
||||
@ -1342,6 +1381,64 @@ static const struct reg_default wm5110_reg_default[] = {
|
||||
{ 0x00001404, 0x0000 }, /* R5124 - DSP4 Status 1 */
|
||||
};
|
||||
|
||||
static bool wm5110_is_rev_b_adsp_memory(unsigned int reg)
|
||||
{
|
||||
if ((reg >= 0x100000 && reg < 0x103000) ||
|
||||
(reg >= 0x180000 && reg < 0x181000) ||
|
||||
(reg >= 0x190000 && reg < 0x192000) ||
|
||||
(reg >= 0x1a8000 && reg < 0x1a9000) ||
|
||||
(reg >= 0x200000 && reg < 0x209000) ||
|
||||
(reg >= 0x280000 && reg < 0x281000) ||
|
||||
(reg >= 0x290000 && reg < 0x29a000) ||
|
||||
(reg >= 0x2a8000 && reg < 0x2aa000) ||
|
||||
(reg >= 0x300000 && reg < 0x30f000) ||
|
||||
(reg >= 0x380000 && reg < 0x382000) ||
|
||||
(reg >= 0x390000 && reg < 0x39e000) ||
|
||||
(reg >= 0x3a8000 && reg < 0x3b6000) ||
|
||||
(reg >= 0x400000 && reg < 0x403000) ||
|
||||
(reg >= 0x480000 && reg < 0x481000) ||
|
||||
(reg >= 0x490000 && reg < 0x492000) ||
|
||||
(reg >= 0x4a8000 && reg < 0x4a9000))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool wm5110_is_rev_d_adsp_memory(unsigned int reg)
|
||||
{
|
||||
if ((reg >= 0x100000 && reg < 0x106000) ||
|
||||
(reg >= 0x180000 && reg < 0x182000) ||
|
||||
(reg >= 0x190000 && reg < 0x198000) ||
|
||||
(reg >= 0x1a8000 && reg < 0x1aa000) ||
|
||||
(reg >= 0x200000 && reg < 0x20f000) ||
|
||||
(reg >= 0x280000 && reg < 0x282000) ||
|
||||
(reg >= 0x290000 && reg < 0x29c000) ||
|
||||
(reg >= 0x2a6000 && reg < 0x2b4000) ||
|
||||
(reg >= 0x300000 && reg < 0x30f000) ||
|
||||
(reg >= 0x380000 && reg < 0x382000) ||
|
||||
(reg >= 0x390000 && reg < 0x3a2000) ||
|
||||
(reg >= 0x3a6000 && reg < 0x3b4000) ||
|
||||
(reg >= 0x400000 && reg < 0x406000) ||
|
||||
(reg >= 0x480000 && reg < 0x482000) ||
|
||||
(reg >= 0x490000 && reg < 0x498000) ||
|
||||
(reg >= 0x4a8000 && reg < 0x4aa000))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool wm5110_is_adsp_memory(struct device *dev, unsigned int reg)
|
||||
{
|
||||
struct arizona *arizona = dev_get_drvdata(dev);
|
||||
|
||||
switch (arizona->rev) {
|
||||
case 0 ... 2:
|
||||
return wm5110_is_rev_b_adsp_memory(reg);
|
||||
default:
|
||||
return wm5110_is_rev_d_adsp_memory(reg);
|
||||
}
|
||||
}
|
||||
|
||||
static bool wm5110_readable_register(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
@ -1460,6 +1557,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_INPUT_ENABLES_STATUS:
|
||||
case ARIZONA_INPUT_RATE:
|
||||
case ARIZONA_INPUT_VOLUME_RAMP:
|
||||
case ARIZONA_HPF_CONTROL:
|
||||
case ARIZONA_IN1L_CONTROL:
|
||||
case ARIZONA_ADC_DIGITAL_VOLUME_1L:
|
||||
case ARIZONA_DMIC1L_CONTROL:
|
||||
@ -1481,6 +1579,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_IN4L_CONTROL:
|
||||
case ARIZONA_ADC_DIGITAL_VOLUME_4L:
|
||||
case ARIZONA_DMIC4L_CONTROL:
|
||||
case ARIZONA_IN4R_CONTROL:
|
||||
case ARIZONA_ADC_DIGITAL_VOLUME_4R:
|
||||
case ARIZONA_DMIC4R_CONTROL:
|
||||
case ARIZONA_OUTPUT_ENABLES_1:
|
||||
@ -1536,12 +1635,16 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_DAC_DIGITAL_VOLUME_6R:
|
||||
case ARIZONA_DAC_VOLUME_LIMIT_6R:
|
||||
case ARIZONA_NOISE_GATE_SELECT_6R:
|
||||
case ARIZONA_DRE_ENABLE:
|
||||
case ARIZONA_DAC_AEC_CONTROL_1:
|
||||
case ARIZONA_NOISE_GATE_CONTROL:
|
||||
case ARIZONA_PDM_SPK1_CTRL_1:
|
||||
case ARIZONA_PDM_SPK1_CTRL_2:
|
||||
case ARIZONA_PDM_SPK2_CTRL_1:
|
||||
case ARIZONA_PDM_SPK2_CTRL_2:
|
||||
case ARIZONA_HP1_SHORT_CIRCUIT_CTRL:
|
||||
case ARIZONA_HP2_SHORT_CIRCUIT_CTRL:
|
||||
case ARIZONA_HP3_SHORT_CIRCUIT_CTRL:
|
||||
case ARIZONA_AIF1_BCLK_CTRL:
|
||||
case ARIZONA_AIF1_TX_PIN_CTRL:
|
||||
case ARIZONA_AIF1_RX_PIN_CTRL:
|
||||
@ -1820,6 +1923,38 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_AIF2TX2MIX_INPUT_3_VOLUME:
|
||||
case ARIZONA_AIF2TX2MIX_INPUT_4_SOURCE:
|
||||
case ARIZONA_AIF2TX2MIX_INPUT_4_VOLUME:
|
||||
case ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE:
|
||||
case ARIZONA_AIF2TX3MIX_INPUT_1_VOLUME:
|
||||
case ARIZONA_AIF2TX3MIX_INPUT_2_SOURCE:
|
||||
case ARIZONA_AIF2TX3MIX_INPUT_2_VOLUME:
|
||||
case ARIZONA_AIF2TX3MIX_INPUT_3_SOURCE:
|
||||
case ARIZONA_AIF2TX3MIX_INPUT_3_VOLUME:
|
||||
case ARIZONA_AIF2TX3MIX_INPUT_4_SOURCE:
|
||||
case ARIZONA_AIF2TX3MIX_INPUT_4_VOLUME:
|
||||
case ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE:
|
||||
case ARIZONA_AIF2TX4MIX_INPUT_1_VOLUME:
|
||||
case ARIZONA_AIF2TX4MIX_INPUT_2_SOURCE:
|
||||
case ARIZONA_AIF2TX4MIX_INPUT_2_VOLUME:
|
||||
case ARIZONA_AIF2TX4MIX_INPUT_3_SOURCE:
|
||||
case ARIZONA_AIF2TX4MIX_INPUT_3_VOLUME:
|
||||
case ARIZONA_AIF2TX4MIX_INPUT_4_SOURCE:
|
||||
case ARIZONA_AIF2TX4MIX_INPUT_4_VOLUME:
|
||||
case ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE:
|
||||
case ARIZONA_AIF2TX5MIX_INPUT_1_VOLUME:
|
||||
case ARIZONA_AIF2TX5MIX_INPUT_2_SOURCE:
|
||||
case ARIZONA_AIF2TX5MIX_INPUT_2_VOLUME:
|
||||
case ARIZONA_AIF2TX5MIX_INPUT_3_SOURCE:
|
||||
case ARIZONA_AIF2TX5MIX_INPUT_3_VOLUME:
|
||||
case ARIZONA_AIF2TX5MIX_INPUT_4_SOURCE:
|
||||
case ARIZONA_AIF2TX5MIX_INPUT_4_VOLUME:
|
||||
case ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE:
|
||||
case ARIZONA_AIF2TX6MIX_INPUT_1_VOLUME:
|
||||
case ARIZONA_AIF2TX6MIX_INPUT_2_SOURCE:
|
||||
case ARIZONA_AIF2TX6MIX_INPUT_2_VOLUME:
|
||||
case ARIZONA_AIF2TX6MIX_INPUT_3_SOURCE:
|
||||
case ARIZONA_AIF2TX6MIX_INPUT_3_VOLUME:
|
||||
case ARIZONA_AIF2TX6MIX_INPUT_4_SOURCE:
|
||||
case ARIZONA_AIF2TX6MIX_INPUT_4_VOLUME:
|
||||
case ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE:
|
||||
case ARIZONA_AIF3TX1MIX_INPUT_1_VOLUME:
|
||||
case ARIZONA_AIF3TX1MIX_INPUT_2_SOURCE:
|
||||
@ -2331,7 +2466,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_DSP4_SCRATCH_3:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
return wm5110_is_adsp_memory(dev, reg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2407,16 +2542,18 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
|
||||
case ARIZONA_DSP4_SCRATCH_3:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
return wm5110_is_adsp_memory(dev, reg);
|
||||
}
|
||||
}
|
||||
|
||||
#define WM5110_MAX_REGISTER 0x4a9fff
|
||||
|
||||
const struct regmap_config wm5110_spi_regmap = {
|
||||
.reg_bits = 32,
|
||||
.pad_bits = 16,
|
||||
.val_bits = 16,
|
||||
|
||||
.max_register = ARIZONA_DSP1_STATUS_2,
|
||||
.max_register = WM5110_MAX_REGISTER,
|
||||
.readable_reg = wm5110_readable_register,
|
||||
.volatile_reg = wm5110_volatile_register,
|
||||
|
||||
@ -2430,7 +2567,7 @@ const struct regmap_config wm5110_i2c_regmap = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 16,
|
||||
|
||||
.max_register = ARIZONA_DSP1_STATUS_2,
|
||||
.max_register = WM5110_MAX_REGISTER,
|
||||
.readable_reg = wm5110_readable_register,
|
||||
.volatile_reg = wm5110_volatile_register,
|
||||
|
||||
|
@ -395,7 +395,7 @@ config SPI_S3C24XX_FIQ
|
||||
config SPI_S3C64XX
|
||||
tristate "Samsung S3C64XX series type SPI"
|
||||
depends on PLAT_SAMSUNG
|
||||
select S3C64XX_DMA if ARCH_S3C64XX
|
||||
select S3C64XX_PL080 if ARCH_S3C64XX
|
||||
help
|
||||
SPI driver for Samsung S3C64XX and newer SoCs.
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define LINUX_DMAENGINE_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/scatterlist.h>
|
||||
@ -363,6 +364,32 @@ struct dma_slave_config {
|
||||
unsigned int slave_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dma_residue_granularity - Granularity of the reported transfer residue
|
||||
* @DMA_RESIDUE_GRANULARITY_DESCRIPTOR: Residue reporting is not support. The
|
||||
* DMA channel is only able to tell whether a descriptor has been completed or
|
||||
* not, which means residue reporting is not supported by this channel. The
|
||||
* residue field of the dma_tx_state field will always be 0.
|
||||
* @DMA_RESIDUE_GRANULARITY_SEGMENT: Residue is updated after each successfully
|
||||
* completed segment of the transfer (For cyclic transfers this is after each
|
||||
* period). This is typically implemented by having the hardware generate an
|
||||
* interrupt after each transferred segment and then the drivers updates the
|
||||
* outstanding residue by the size of the segment. Another possibility is if
|
||||
* the hardware supports scatter-gather and the segment descriptor has a field
|
||||
* which gets set after the segment has been completed. The driver then counts
|
||||
* the number of segments without the flag set to compute the residue.
|
||||
* @DMA_RESIDUE_GRANULARITY_BURST: Residue is updated after each transferred
|
||||
* burst. This is typically only supported if the hardware has a progress
|
||||
* register of some sort (E.g. a register with the current read/write address
|
||||
* or a register with the amount of bursts/beats/bytes that have been
|
||||
* transferred or still need to be transferred).
|
||||
*/
|
||||
enum dma_residue_granularity {
|
||||
DMA_RESIDUE_GRANULARITY_DESCRIPTOR = 0,
|
||||
DMA_RESIDUE_GRANULARITY_SEGMENT = 1,
|
||||
DMA_RESIDUE_GRANULARITY_BURST = 2,
|
||||
};
|
||||
|
||||
/* struct dma_slave_caps - expose capabilities of a slave channel only
|
||||
*
|
||||
* @src_addr_widths: bit mask of src addr widths the channel supports
|
||||
@ -373,6 +400,7 @@ struct dma_slave_config {
|
||||
* should be checked by controller as well
|
||||
* @cmd_pause: true, if pause and thereby resume is supported
|
||||
* @cmd_terminate: true, if terminate cmd is supported
|
||||
* @residue_granularity: granularity of the reported transfer residue
|
||||
*/
|
||||
struct dma_slave_caps {
|
||||
u32 src_addr_widths;
|
||||
@ -380,6 +408,7 @@ struct dma_slave_caps {
|
||||
u32 directions;
|
||||
bool cmd_pause;
|
||||
bool cmd_terminate;
|
||||
enum dma_residue_granularity residue_granularity;
|
||||
};
|
||||
|
||||
static inline const char *dma_chan_name(struct dma_chan *chan)
|
||||
@ -1040,6 +1069,8 @@ enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx);
|
||||
void dma_issue_pending_all(void);
|
||||
struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
|
||||
dma_filter_fn fn, void *fn_param);
|
||||
struct dma_chan *dma_request_slave_channel_reason(struct device *dev,
|
||||
const char *name);
|
||||
struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name);
|
||||
void dma_release_channel(struct dma_chan *chan);
|
||||
#else
|
||||
@ -1063,6 +1094,11 @@ static inline struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline struct dma_chan *dma_request_slave_channel_reason(
|
||||
struct device *dev, const char *name)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
static inline struct dma_chan *dma_request_slave_channel(struct device *dev,
|
||||
const char *name)
|
||||
{
|
||||
|
@ -175,6 +175,9 @@ static inline int twl_class_is_ ##class(void) \
|
||||
TWL_CLASS_IS(4030, TWL4030_CLASS_ID)
|
||||
TWL_CLASS_IS(6030, TWL6030_CLASS_ID)
|
||||
|
||||
/* Set the regcache bypass for the regmap associated with the nodule */
|
||||
int twl_set_regcache_bypass(u8 mod_no, bool enable);
|
||||
|
||||
/*
|
||||
* Read and write several 8-bit registers at once.
|
||||
*/
|
||||
@ -667,8 +670,6 @@ struct twl4030_codec_data {
|
||||
unsigned int digimic_delay; /* in ms */
|
||||
unsigned int ramp_delay_value;
|
||||
unsigned int offset_cncl_path;
|
||||
unsigned int check_defaults:1;
|
||||
unsigned int reset_registers:1;
|
||||
unsigned int hs_extmute:1;
|
||||
int hs_extmute_gpio;
|
||||
};
|
||||
|
@ -139,6 +139,7 @@
|
||||
#define ARIZONA_INPUT_ENABLES_STATUS 0x301
|
||||
#define ARIZONA_INPUT_RATE 0x308
|
||||
#define ARIZONA_INPUT_VOLUME_RAMP 0x309
|
||||
#define ARIZONA_HPF_CONTROL 0x30C
|
||||
#define ARIZONA_IN1L_CONTROL 0x310
|
||||
#define ARIZONA_ADC_DIGITAL_VOLUME_1L 0x311
|
||||
#define ARIZONA_DMIC1L_CONTROL 0x312
|
||||
@ -160,6 +161,7 @@
|
||||
#define ARIZONA_IN4L_CONTROL 0x328
|
||||
#define ARIZONA_ADC_DIGITAL_VOLUME_4L 0x329
|
||||
#define ARIZONA_DMIC4L_CONTROL 0x32A
|
||||
#define ARIZONA_IN4R_CONTROL 0x32C
|
||||
#define ARIZONA_ADC_DIGITAL_VOLUME_4R 0x32D
|
||||
#define ARIZONA_DMIC4R_CONTROL 0x32E
|
||||
#define ARIZONA_OUTPUT_ENABLES_1 0x400
|
||||
@ -224,6 +226,9 @@
|
||||
#define ARIZONA_PDM_SPK1_CTRL_2 0x491
|
||||
#define ARIZONA_PDM_SPK2_CTRL_1 0x492
|
||||
#define ARIZONA_PDM_SPK2_CTRL_2 0x493
|
||||
#define ARIZONA_HP1_SHORT_CIRCUIT_CTRL 0x4A0
|
||||
#define ARIZONA_HP2_SHORT_CIRCUIT_CTRL 0x4A1
|
||||
#define ARIZONA_HP3_SHORT_CIRCUIT_CTRL 0x4A2
|
||||
#define ARIZONA_SPK_CTRL_2 0x4B5
|
||||
#define ARIZONA_SPK_CTRL_3 0x4B6
|
||||
#define ARIZONA_DAC_COMP_1 0x4DC
|
||||
@ -511,6 +516,38 @@
|
||||
#define ARIZONA_AIF2TX2MIX_INPUT_3_VOLUME 0x74D
|
||||
#define ARIZONA_AIF2TX2MIX_INPUT_4_SOURCE 0x74E
|
||||
#define ARIZONA_AIF2TX2MIX_INPUT_4_VOLUME 0x74F
|
||||
#define ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE 0x750
|
||||
#define ARIZONA_AIF2TX3MIX_INPUT_1_VOLUME 0x751
|
||||
#define ARIZONA_AIF2TX3MIX_INPUT_2_SOURCE 0x752
|
||||
#define ARIZONA_AIF2TX3MIX_INPUT_2_VOLUME 0x753
|
||||
#define ARIZONA_AIF2TX3MIX_INPUT_3_SOURCE 0x754
|
||||
#define ARIZONA_AIF2TX3MIX_INPUT_3_VOLUME 0x755
|
||||
#define ARIZONA_AIF2TX3MIX_INPUT_4_SOURCE 0x756
|
||||
#define ARIZONA_AIF2TX3MIX_INPUT_4_VOLUME 0x757
|
||||
#define ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE 0x758
|
||||
#define ARIZONA_AIF2TX4MIX_INPUT_1_VOLUME 0x759
|
||||
#define ARIZONA_AIF2TX4MIX_INPUT_2_SOURCE 0x75A
|
||||
#define ARIZONA_AIF2TX4MIX_INPUT_2_VOLUME 0x75B
|
||||
#define ARIZONA_AIF2TX4MIX_INPUT_3_SOURCE 0x75C
|
||||
#define ARIZONA_AIF2TX4MIX_INPUT_3_VOLUME 0x75D
|
||||
#define ARIZONA_AIF2TX4MIX_INPUT_4_SOURCE 0x75E
|
||||
#define ARIZONA_AIF2TX4MIX_INPUT_4_VOLUME 0x75F
|
||||
#define ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE 0x760
|
||||
#define ARIZONA_AIF2TX5MIX_INPUT_1_VOLUME 0x761
|
||||
#define ARIZONA_AIF2TX5MIX_INPUT_2_SOURCE 0x762
|
||||
#define ARIZONA_AIF2TX5MIX_INPUT_2_VOLUME 0x763
|
||||
#define ARIZONA_AIF2TX5MIX_INPUT_3_SOURCE 0x764
|
||||
#define ARIZONA_AIF2TX5MIX_INPUT_3_VOLUME 0x765
|
||||
#define ARIZONA_AIF2TX5MIX_INPUT_4_SOURCE 0x766
|
||||
#define ARIZONA_AIF2TX5MIX_INPUT_4_VOLUME 0x767
|
||||
#define ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE 0x768
|
||||
#define ARIZONA_AIF2TX6MIX_INPUT_1_VOLUME 0x769
|
||||
#define ARIZONA_AIF2TX6MIX_INPUT_2_SOURCE 0x76A
|
||||
#define ARIZONA_AIF2TX6MIX_INPUT_2_VOLUME 0x76B
|
||||
#define ARIZONA_AIF2TX6MIX_INPUT_3_SOURCE 0x76C
|
||||
#define ARIZONA_AIF2TX6MIX_INPUT_3_VOLUME 0x76D
|
||||
#define ARIZONA_AIF2TX6MIX_INPUT_4_SOURCE 0x76E
|
||||
#define ARIZONA_AIF2TX6MIX_INPUT_4_VOLUME 0x76F
|
||||
#define ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE 0x780
|
||||
#define ARIZONA_AIF3TX1MIX_INPUT_1_VOLUME 0x781
|
||||
#define ARIZONA_AIF3TX1MIX_INPUT_2_SOURCE 0x782
|
||||
@ -2292,9 +2329,19 @@
|
||||
#define ARIZONA_IN_VI_RAMP_SHIFT 0 /* IN_VI_RAMP - [2:0] */
|
||||
#define ARIZONA_IN_VI_RAMP_WIDTH 3 /* IN_VI_RAMP - [2:0] */
|
||||
|
||||
/*
|
||||
* R780 (0x30C) - HPF Control
|
||||
*/
|
||||
#define ARIZONA_IN_HPF_CUT_MASK 0x0007 /* IN_HPF_CUT [2:0] */
|
||||
#define ARIZONA_IN_HPF_CUT_SHIFT 0 /* IN_HPF_CUT [2:0] */
|
||||
#define ARIZONA_IN_HPF_CUT_WIDTH 3 /* IN_HPF_CUT [2:0] */
|
||||
|
||||
/*
|
||||
* R784 (0x310) - IN1L Control
|
||||
*/
|
||||
#define ARIZONA_IN1L_HPF_MASK 0x8000 /* IN1L_HPF - [15] */
|
||||
#define ARIZONA_IN1L_HPF_SHIFT 15 /* IN1L_HPF - [15] */
|
||||
#define ARIZONA_IN1L_HPF_WIDTH 1 /* IN1L_HPF - [15] */
|
||||
#define ARIZONA_IN1_OSR_MASK 0x6000 /* IN1_OSR - [14:13] */
|
||||
#define ARIZONA_IN1_OSR_SHIFT 13 /* IN1_OSR - [14:13] */
|
||||
#define ARIZONA_IN1_OSR_WIDTH 2 /* IN1_OSR - [14:13] */
|
||||
@ -2333,6 +2380,9 @@
|
||||
/*
|
||||
* R788 (0x314) - IN1R Control
|
||||
*/
|
||||
#define ARIZONA_IN1R_HPF_MASK 0x8000 /* IN1R_HPF - [15] */
|
||||
#define ARIZONA_IN1R_HPF_SHIFT 15 /* IN1R_HPF - [15] */
|
||||
#define ARIZONA_IN1R_HPF_WIDTH 1 /* IN1R_HPF - [15] */
|
||||
#define ARIZONA_IN1R_PGA_VOL_MASK 0x00FE /* IN1R_PGA_VOL - [7:1] */
|
||||
#define ARIZONA_IN1R_PGA_VOL_SHIFT 1 /* IN1R_PGA_VOL - [7:1] */
|
||||
#define ARIZONA_IN1R_PGA_VOL_WIDTH 7 /* IN1R_PGA_VOL - [7:1] */
|
||||
@ -2362,6 +2412,9 @@
|
||||
/*
|
||||
* R792 (0x318) - IN2L Control
|
||||
*/
|
||||
#define ARIZONA_IN2L_HPF_MASK 0x8000 /* IN2L_HPF - [15] */
|
||||
#define ARIZONA_IN2L_HPF_SHIFT 15 /* IN2L_HPF - [15] */
|
||||
#define ARIZONA_IN2L_HPF_WIDTH 1 /* IN2L_HPF - [15] */
|
||||
#define ARIZONA_IN2_OSR_MASK 0x6000 /* IN2_OSR - [14:13] */
|
||||
#define ARIZONA_IN2_OSR_SHIFT 13 /* IN2_OSR - [14:13] */
|
||||
#define ARIZONA_IN2_OSR_WIDTH 2 /* IN2_OSR - [14:13] */
|
||||
@ -2400,6 +2453,9 @@
|
||||
/*
|
||||
* R796 (0x31C) - IN2R Control
|
||||
*/
|
||||
#define ARIZONA_IN2R_HPF_MASK 0x8000 /* IN2R_HPF - [15] */
|
||||
#define ARIZONA_IN2R_HPF_SHIFT 15 /* IN2R_HPF - [15] */
|
||||
#define ARIZONA_IN2R_HPF_WIDTH 1 /* IN2R_HPF - [15] */
|
||||
#define ARIZONA_IN2R_PGA_VOL_MASK 0x00FE /* IN2R_PGA_VOL - [7:1] */
|
||||
#define ARIZONA_IN2R_PGA_VOL_SHIFT 1 /* IN2R_PGA_VOL - [7:1] */
|
||||
#define ARIZONA_IN2R_PGA_VOL_WIDTH 7 /* IN2R_PGA_VOL - [7:1] */
|
||||
@ -2429,6 +2485,9 @@
|
||||
/*
|
||||
* R800 (0x320) - IN3L Control
|
||||
*/
|
||||
#define ARIZONA_IN3L_HPF_MASK 0x8000 /* IN3L_HPF - [15] */
|
||||
#define ARIZONA_IN3L_HPF_SHIFT 15 /* IN3L_HPF - [15] */
|
||||
#define ARIZONA_IN3L_HPF_WIDTH 1 /* IN3L_HPF - [15] */
|
||||
#define ARIZONA_IN3_OSR_MASK 0x6000 /* IN3_OSR - [14:13] */
|
||||
#define ARIZONA_IN3_OSR_SHIFT 13 /* IN3_OSR - [14:13] */
|
||||
#define ARIZONA_IN3_OSR_WIDTH 2 /* IN3_OSR - [14:13] */
|
||||
@ -2467,6 +2526,9 @@
|
||||
/*
|
||||
* R804 (0x324) - IN3R Control
|
||||
*/
|
||||
#define ARIZONA_IN3R_HPF_MASK 0x8000 /* IN3R_HPF - [15] */
|
||||
#define ARIZONA_IN3R_HPF_SHIFT 15 /* IN3R_HPF - [15] */
|
||||
#define ARIZONA_IN3R_HPF_WIDTH 1 /* IN3R_HPF - [15] */
|
||||
#define ARIZONA_IN3R_PGA_VOL_MASK 0x00FE /* IN3R_PGA_VOL - [7:1] */
|
||||
#define ARIZONA_IN3R_PGA_VOL_SHIFT 1 /* IN3R_PGA_VOL - [7:1] */
|
||||
#define ARIZONA_IN3R_PGA_VOL_WIDTH 7 /* IN3R_PGA_VOL - [7:1] */
|
||||
@ -2496,6 +2558,9 @@
|
||||
/*
|
||||
* R808 (0x328) - IN4 Control
|
||||
*/
|
||||
#define ARIZONA_IN4L_HPF_MASK 0x8000 /* IN4L_HPF - [15] */
|
||||
#define ARIZONA_IN4L_HPF_SHIFT 15 /* IN4L_HPF - [15] */
|
||||
#define ARIZONA_IN4L_HPF_WIDTH 1 /* IN4L_HPF - [15] */
|
||||
#define ARIZONA_IN4_OSR_MASK 0x6000 /* IN4_OSR - [14:13] */
|
||||
#define ARIZONA_IN4_OSR_SHIFT 13 /* IN4_OSR - [14:13] */
|
||||
#define ARIZONA_IN4_OSR_WIDTH 2 /* IN4_OSR - [14:13] */
|
||||
@ -2525,6 +2590,13 @@
|
||||
#define ARIZONA_IN4L_DMIC_DLY_SHIFT 0 /* IN4L_DMIC_DLY - [5:0] */
|
||||
#define ARIZONA_IN4L_DMIC_DLY_WIDTH 6 /* IN4L_DMIC_DLY - [5:0] */
|
||||
|
||||
/*
|
||||
* R812 (0x32C) - IN4R Control
|
||||
*/
|
||||
#define ARIZONA_IN4R_HPF_MASK 0x8000 /* IN4R_HPF - [15] */
|
||||
#define ARIZONA_IN4R_HPF_SHIFT 15 /* IN4R_HPF - [15] */
|
||||
#define ARIZONA_IN4R_HPF_WIDTH 1 /* IN4R_HPF - [15] */
|
||||
|
||||
/*
|
||||
* R813 (0x32D) - ADC Digital Volume 4R
|
||||
*/
|
||||
@ -3138,6 +3210,10 @@
|
||||
/*
|
||||
* R1088 (0x440) - DRE Enable
|
||||
*/
|
||||
#define ARIZONA_DRE3R_ENA 0x0020 /* DRE3R_ENA */
|
||||
#define ARIZONA_DRE3R_ENA_MASK 0x0020 /* DRE3R_ENA */
|
||||
#define ARIZONA_DRE3R_ENA_SHIFT 5 /* DRE3R_ENA */
|
||||
#define ARIZONA_DRE3R_ENA_WIDTH 1 /* DRE3R_ENA */
|
||||
#define ARIZONA_DRE3L_ENA 0x0010 /* DRE3L_ENA */
|
||||
#define ARIZONA_DRE3L_ENA_MASK 0x0010 /* DRE3L_ENA */
|
||||
#define ARIZONA_DRE3L_ENA_SHIFT 4 /* DRE3L_ENA */
|
||||
@ -3259,6 +3335,30 @@
|
||||
#define ARIZONA_SPK2_FMT_SHIFT 0 /* SPK2_FMT */
|
||||
#define ARIZONA_SPK2_FMT_WIDTH 1 /* SPK2_FMT */
|
||||
|
||||
/*
|
||||
* R1184 (0x4A0) - HP1 Short Circuit Ctrl
|
||||
*/
|
||||
#define ARIZONA_HP1_SC_ENA 0x1000 /* HP1_SC_ENA */
|
||||
#define ARIZONA_HP1_SC_ENA_MASK 0x1000 /* HP1_SC_ENA */
|
||||
#define ARIZONA_HP1_SC_ENA_SHIFT 12 /* HP1_SC_ENA */
|
||||
#define ARIZONA_HP1_SC_ENA_WIDTH 1 /* HP1_SC_ENA */
|
||||
|
||||
/*
|
||||
* R1185 (0x4A1) - HP2 Short Circuit Ctrl
|
||||
*/
|
||||
#define ARIZONA_HP2_SC_ENA 0x1000 /* HP2_SC_ENA */
|
||||
#define ARIZONA_HP2_SC_ENA_MASK 0x1000 /* HP2_SC_ENA */
|
||||
#define ARIZONA_HP2_SC_ENA_SHIFT 12 /* HP2_SC_ENA */
|
||||
#define ARIZONA_HP2_SC_ENA_WIDTH 1 /* HP2_SC_ENA */
|
||||
|
||||
/*
|
||||
* R1186 (0x4A2) - HP3 Short Circuit Ctrl
|
||||
*/
|
||||
#define ARIZONA_HP3_SC_ENA 0x1000 /* HP3_SC_ENA */
|
||||
#define ARIZONA_HP3_SC_ENA_MASK 0x1000 /* HP3_SC_ENA */
|
||||
#define ARIZONA_HP3_SC_ENA_SHIFT 12 /* HP3_SC_ENA */
|
||||
#define ARIZONA_HP3_SC_ENA_WIDTH 1 /* HP3_SC_ENA */
|
||||
|
||||
/*
|
||||
* R1244 (0x4DC) - DAC comp 1
|
||||
*/
|
||||
@ -3725,6 +3825,35 @@
|
||||
#define ARIZONA_AIF2TX2_SLOT_SHIFT 0 /* AIF2TX2_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2TX2_SLOT_WIDTH 6 /* AIF2TX2_SLOT - [5:0] */
|
||||
|
||||
/*
|
||||
* R1355 (0x54B) - AIF2 Frame Ctrl 5
|
||||
*/
|
||||
#define ARIZONA_AIF2TX3_SLOT_MASK 0x003F /* AIF2TX3_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2TX3_SLOT_SHIFT 0 /* AIF2TX3_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2TX3_SLOT_WIDTH 6 /* AIF2TX3_SLOT - [5:0] */
|
||||
|
||||
/*
|
||||
* R1356 (0x54C) - AIF2 Frame Ctrl 6
|
||||
*/
|
||||
#define ARIZONA_AIF2TX4_SLOT_MASK 0x003F /* AIF2TX4_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2TX4_SLOT_SHIFT 0 /* AIF2TX4_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2TX4_SLOT_WIDTH 6 /* AIF2TX4_SLOT - [5:0] */
|
||||
|
||||
|
||||
/*
|
||||
* R1357 (0x54D) - AIF2 Frame Ctrl 7
|
||||
*/
|
||||
#define ARIZONA_AIF2TX5_SLOT_MASK 0x003F /* AIF2TX5_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2TX5_SLOT_SHIFT 0 /* AIF2TX5_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2TX5_SLOT_WIDTH 6 /* AIF2TX5_SLOT - [5:0] */
|
||||
|
||||
/*
|
||||
* R1358 (0x54E) - AIF2 Frame Ctrl 8
|
||||
*/
|
||||
#define ARIZONA_AIF2TX6_SLOT_MASK 0x003F /* AIF2TX6_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2TX6_SLOT_SHIFT 0 /* AIF2TX6_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2TX6_SLOT_WIDTH 6 /* AIF2TX6_SLOT - [5:0] */
|
||||
|
||||
/*
|
||||
* R1361 (0x551) - AIF2 Frame Ctrl 11
|
||||
*/
|
||||
@ -3739,9 +3868,53 @@
|
||||
#define ARIZONA_AIF2RX2_SLOT_SHIFT 0 /* AIF2RX2_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2RX2_SLOT_WIDTH 6 /* AIF2RX2_SLOT - [5:0] */
|
||||
|
||||
/*
|
||||
* R1363 (0x553) - AIF2 Frame Ctrl 13
|
||||
*/
|
||||
#define ARIZONA_AIF2RX3_SLOT_MASK 0x003F /* AIF2RX3_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2RX3_SLOT_SHIFT 0 /* AIF2RX3_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2RX3_SLOT_WIDTH 6 /* AIF2RX3_SLOT - [5:0] */
|
||||
|
||||
/*
|
||||
* R1364 (0x554) - AIF2 Frame Ctrl 14
|
||||
*/
|
||||
#define ARIZONA_AIF2RX4_SLOT_MASK 0x003F /* AIF2RX4_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2RX4_SLOT_SHIFT 0 /* AIF2RX4_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2RX4_SLOT_WIDTH 6 /* AIF2RX4_SLOT - [5:0] */
|
||||
|
||||
/*
|
||||
* R1365 (0x555) - AIF2 Frame Ctrl 15
|
||||
*/
|
||||
#define ARIZONA_AIF2RX5_SLOT_MASK 0x003F /* AIF2RX5_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2RX5_SLOT_SHIFT 0 /* AIF2RX5_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2RX5_SLOT_WIDTH 6 /* AIF2RX5_SLOT - [5:0] */
|
||||
|
||||
/*
|
||||
* R1366 (0x556) - AIF2 Frame Ctrl 16
|
||||
*/
|
||||
#define ARIZONA_AIF2RX6_SLOT_MASK 0x003F /* AIF2RX6_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2RX6_SLOT_SHIFT 0 /* AIF2RX6_SLOT - [5:0] */
|
||||
#define ARIZONA_AIF2RX6_SLOT_WIDTH 6 /* AIF2RX6_SLOT - [5:0] */
|
||||
|
||||
/*
|
||||
* R1369 (0x559) - AIF2 Tx Enables
|
||||
*/
|
||||
#define ARIZONA_AIF2TX6_ENA 0x0020 /* AIF2TX6_ENA */
|
||||
#define ARIZONA_AIF2TX6_ENA_MASK 0x0020 /* AIF2TX6_ENA */
|
||||
#define ARIZONA_AIF2TX6_ENA_SHIFT 5 /* AIF2TX6_ENA */
|
||||
#define ARIZONA_AIF2TX6_ENA_WIDTH 1 /* AIF2TX6_ENA */
|
||||
#define ARIZONA_AIF2TX5_ENA 0x0010 /* AIF2TX5_ENA */
|
||||
#define ARIZONA_AIF2TX5_ENA_MASK 0x0010 /* AIF2TX5_ENA */
|
||||
#define ARIZONA_AIF2TX5_ENA_SHIFT 4 /* AIF2TX5_ENA */
|
||||
#define ARIZONA_AIF2TX5_ENA_WIDTH 1 /* AIF2TX5_ENA */
|
||||
#define ARIZONA_AIF2TX4_ENA 0x0008 /* AIF2TX4_ENA */
|
||||
#define ARIZONA_AIF2TX4_ENA_MASK 0x0008 /* AIF2TX4_ENA */
|
||||
#define ARIZONA_AIF2TX4_ENA_SHIFT 3 /* AIF2TX4_ENA */
|
||||
#define ARIZONA_AIF2TX4_ENA_WIDTH 1 /* AIF2TX4_ENA */
|
||||
#define ARIZONA_AIF2TX3_ENA 0x0004 /* AIF2TX3_ENA */
|
||||
#define ARIZONA_AIF2TX3_ENA_MASK 0x0004 /* AIF2TX3_ENA */
|
||||
#define ARIZONA_AIF2TX3_ENA_SHIFT 2 /* AIF2TX3_ENA */
|
||||
#define ARIZONA_AIF2TX3_ENA_WIDTH 1 /* AIF2TX3_ENA */
|
||||
#define ARIZONA_AIF2TX2_ENA 0x0002 /* AIF2TX2_ENA */
|
||||
#define ARIZONA_AIF2TX2_ENA_MASK 0x0002 /* AIF2TX2_ENA */
|
||||
#define ARIZONA_AIF2TX2_ENA_SHIFT 1 /* AIF2TX2_ENA */
|
||||
@ -3754,6 +3927,22 @@
|
||||
/*
|
||||
* R1370 (0x55A) - AIF2 Rx Enables
|
||||
*/
|
||||
#define ARIZONA_AIF2RX6_ENA 0x0020 /* AIF2RX6_ENA */
|
||||
#define ARIZONA_AIF2RX6_ENA_MASK 0x0020 /* AIF2RX6_ENA */
|
||||
#define ARIZONA_AIF2RX6_ENA_SHIFT 5 /* AIF2RX6_ENA */
|
||||
#define ARIZONA_AIF2RX6_ENA_WIDTH 1 /* AIF2RX6_ENA */
|
||||
#define ARIZONA_AIF2RX5_ENA 0x0010 /* AIF2RX5_ENA */
|
||||
#define ARIZONA_AIF2RX5_ENA_MASK 0x0010 /* AIF2RX5_ENA */
|
||||
#define ARIZONA_AIF2RX5_ENA_SHIFT 4 /* AIF2RX5_ENA */
|
||||
#define ARIZONA_AIF2RX5_ENA_WIDTH 1 /* AIF2RX5_ENA */
|
||||
#define ARIZONA_AIF2RX4_ENA 0x0008 /* AIF2RX4_ENA */
|
||||
#define ARIZONA_AIF2RX4_ENA_MASK 0x0008 /* AIF2RX4_ENA */
|
||||
#define ARIZONA_AIF2RX4_ENA_SHIFT 3 /* AIF2RX4_ENA */
|
||||
#define ARIZONA_AIF2RX4_ENA_WIDTH 1 /* AIF2RX4_ENA */
|
||||
#define ARIZONA_AIF2RX3_ENA 0x0004 /* AIF2RX3_ENA */
|
||||
#define ARIZONA_AIF2RX3_ENA_MASK 0x0004 /* AIF2RX3_ENA */
|
||||
#define ARIZONA_AIF2RX3_ENA_SHIFT 2 /* AIF2RX3_ENA */
|
||||
#define ARIZONA_AIF2RX3_ENA_WIDTH 1 /* AIF2RX3_ENA */
|
||||
#define ARIZONA_AIF2RX2_ENA 0x0002 /* AIF2RX2_ENA */
|
||||
#define ARIZONA_AIF2RX2_ENA_MASK 0x0002 /* AIF2RX2_ENA */
|
||||
#define ARIZONA_AIF2RX2_ENA_SHIFT 1 /* AIF2RX2_ENA */
|
||||
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* arch/arm/plat-omap/include/mach/mcbsp.h
|
||||
*
|
||||
* Defines for Multi-Channel Buffered Serial Port
|
||||
*
|
||||
* Copyright (C) 2002 RidgeRun, Inc.
|
||||
@ -21,8 +19,8 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#ifndef __ASM_ARCH_OMAP_MCBSP_H
|
||||
#define __ASM_ARCH_OMAP_MCBSP_H
|
||||
#ifndef __ASOC_TI_MCBSP_H
|
||||
#define __ASOC_TI_MCBSP_H
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/clk.h>
|
||||
|
@ -10,16 +10,9 @@
|
||||
|
||||
#include <linux/platform_data/dma-ste-dma40.h>
|
||||
|
||||
enum msp_i2s_id {
|
||||
MSP_I2S_0 = 0,
|
||||
MSP_I2S_1,
|
||||
MSP_I2S_2,
|
||||
MSP_I2S_3,
|
||||
};
|
||||
|
||||
/* Platform data structure for a MSP I2S-device */
|
||||
struct msp_i2s_platform_data {
|
||||
enum msp_i2s_id id;
|
||||
int id;
|
||||
struct stedma40_chan_cfg *msp_i2s_dma_rx;
|
||||
struct stedma40_chan_cfg *msp_i2s_dma_tx;
|
||||
};
|
||||
|
@ -92,6 +92,7 @@ enum {
|
||||
MCASP_VERSION_1 = 0, /* DM646x */
|
||||
MCASP_VERSION_2, /* DA8xx/OMAPL1x */
|
||||
MCASP_VERSION_3, /* TI81xx/AM33xx */
|
||||
MCASP_VERSION_4, /* DRA7xxx */
|
||||
};
|
||||
|
||||
enum mcbsp_clk_input_pin {
|
||||
|
@ -16,17 +16,11 @@ struct cs42l52_platform_data {
|
||||
/* MICBIAS Level. Check datasheet Pg48 */
|
||||
unsigned int micbias_lvl;
|
||||
|
||||
/* MICA mode selection 0=Single 1=Differential */
|
||||
unsigned int mica_cfg;
|
||||
/* MICA mode selection Differential or Single-ended */
|
||||
bool mica_diff_cfg;
|
||||
|
||||
/* MICB mode selection 0=Single 1=Differential */
|
||||
unsigned int micb_cfg;
|
||||
|
||||
/* MICA Select 0=MIC1A 1=MIC2A */
|
||||
unsigned int mica_sel;
|
||||
|
||||
/* MICB Select 0=MIC2A 1=MIC2B */
|
||||
unsigned int micb_sel;
|
||||
/* MICB mode selection Differential or Single-ended */
|
||||
bool micb_diff_cfg;
|
||||
|
||||
/* Charge Pump Freq. Check datasheet Pg73 */
|
||||
unsigned int chgfreq;
|
||||
|
@ -114,6 +114,10 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
|
||||
* @compat_filter_fn: Will be used as the filter function when requesting a
|
||||
* channel for platforms which do not use devicetree. The filter parameter
|
||||
* will be the DAI's DMA data.
|
||||
* @dma_dev: If set, request DMA channel on this device rather than the DAI
|
||||
* device.
|
||||
* @chan_names: If set, these custom DMA channel names will be requested at
|
||||
* registration time.
|
||||
* @pcm_hardware: snd_pcm_hardware struct to be used for the PCM.
|
||||
* @prealloc_buffer_size: Size of the preallocated audio buffer.
|
||||
*
|
||||
@ -130,6 +134,8 @@ struct snd_dmaengine_pcm_config {
|
||||
struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_pcm_substream *substream);
|
||||
dma_filter_fn compat_filter_fn;
|
||||
struct device *dma_dev;
|
||||
const char *chan_names[SNDRV_PCM_STREAM_LAST + 1];
|
||||
|
||||
const struct snd_pcm_hardware *pcm_hardware;
|
||||
unsigned int prealloc_buffer_size;
|
||||
@ -140,6 +146,10 @@ int snd_dmaengine_pcm_register(struct device *dev,
|
||||
unsigned int flags);
|
||||
void snd_dmaengine_pcm_unregister(struct device *dev);
|
||||
|
||||
int devm_snd_dmaengine_pcm_register(struct device *dev,
|
||||
const struct snd_dmaengine_pcm_config *config,
|
||||
unsigned int flags);
|
||||
|
||||
int snd_dmaengine_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct dma_slave_config *slave_config);
|
||||
|
554
include/sound/hda_verbs.h
Normal file
554
include/sound/hda_verbs.h
Normal file
@ -0,0 +1,554 @@
|
||||
/*
|
||||
* HD-audio codec verbs
|
||||
*/
|
||||
|
||||
#ifndef __SOUND_HDA_VERBS_H
|
||||
#define __SOUND_HDA_VERBS_H
|
||||
|
||||
/*
|
||||
* nodes
|
||||
*/
|
||||
#define AC_NODE_ROOT 0x00
|
||||
|
||||
/*
|
||||
* function group types
|
||||
*/
|
||||
enum {
|
||||
AC_GRP_AUDIO_FUNCTION = 0x01,
|
||||
AC_GRP_MODEM_FUNCTION = 0x02,
|
||||
};
|
||||
|
||||
/*
|
||||
* widget types
|
||||
*/
|
||||
enum {
|
||||
AC_WID_AUD_OUT, /* Audio Out */
|
||||
AC_WID_AUD_IN, /* Audio In */
|
||||
AC_WID_AUD_MIX, /* Audio Mixer */
|
||||
AC_WID_AUD_SEL, /* Audio Selector */
|
||||
AC_WID_PIN, /* Pin Complex */
|
||||
AC_WID_POWER, /* Power */
|
||||
AC_WID_VOL_KNB, /* Volume Knob */
|
||||
AC_WID_BEEP, /* Beep Generator */
|
||||
AC_WID_VENDOR = 0x0f /* Vendor specific */
|
||||
};
|
||||
|
||||
/*
|
||||
* GET verbs
|
||||
*/
|
||||
#define AC_VERB_GET_STREAM_FORMAT 0x0a00
|
||||
#define AC_VERB_GET_AMP_GAIN_MUTE 0x0b00
|
||||
#define AC_VERB_GET_PROC_COEF 0x0c00
|
||||
#define AC_VERB_GET_COEF_INDEX 0x0d00
|
||||
#define AC_VERB_PARAMETERS 0x0f00
|
||||
#define AC_VERB_GET_CONNECT_SEL 0x0f01
|
||||
#define AC_VERB_GET_CONNECT_LIST 0x0f02
|
||||
#define AC_VERB_GET_PROC_STATE 0x0f03
|
||||
#define AC_VERB_GET_SDI_SELECT 0x0f04
|
||||
#define AC_VERB_GET_POWER_STATE 0x0f05
|
||||
#define AC_VERB_GET_CONV 0x0f06
|
||||
#define AC_VERB_GET_PIN_WIDGET_CONTROL 0x0f07
|
||||
#define AC_VERB_GET_UNSOLICITED_RESPONSE 0x0f08
|
||||
#define AC_VERB_GET_PIN_SENSE 0x0f09
|
||||
#define AC_VERB_GET_BEEP_CONTROL 0x0f0a
|
||||
#define AC_VERB_GET_EAPD_BTLENABLE 0x0f0c
|
||||
#define AC_VERB_GET_DIGI_CONVERT_1 0x0f0d
|
||||
#define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e /* unused */
|
||||
#define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f
|
||||
/* f10-f1a: GPIO */
|
||||
#define AC_VERB_GET_GPIO_DATA 0x0f15
|
||||
#define AC_VERB_GET_GPIO_MASK 0x0f16
|
||||
#define AC_VERB_GET_GPIO_DIRECTION 0x0f17
|
||||
#define AC_VERB_GET_GPIO_WAKE_MASK 0x0f18
|
||||
#define AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK 0x0f19
|
||||
#define AC_VERB_GET_GPIO_STICKY_MASK 0x0f1a
|
||||
#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c
|
||||
/* f20: AFG/MFG */
|
||||
#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20
|
||||
#define AC_VERB_GET_CVT_CHAN_COUNT 0x0f2d
|
||||
#define AC_VERB_GET_HDMI_DIP_SIZE 0x0f2e
|
||||
#define AC_VERB_GET_HDMI_ELDD 0x0f2f
|
||||
#define AC_VERB_GET_HDMI_DIP_INDEX 0x0f30
|
||||
#define AC_VERB_GET_HDMI_DIP_DATA 0x0f31
|
||||
#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32
|
||||
#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33
|
||||
#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34
|
||||
#define AC_VERB_GET_DEVICE_SEL 0xf35
|
||||
#define AC_VERB_GET_DEVICE_LIST 0xf36
|
||||
|
||||
/*
|
||||
* SET verbs
|
||||
*/
|
||||
#define AC_VERB_SET_STREAM_FORMAT 0x200
|
||||
#define AC_VERB_SET_AMP_GAIN_MUTE 0x300
|
||||
#define AC_VERB_SET_PROC_COEF 0x400
|
||||
#define AC_VERB_SET_COEF_INDEX 0x500
|
||||
#define AC_VERB_SET_CONNECT_SEL 0x701
|
||||
#define AC_VERB_SET_PROC_STATE 0x703
|
||||
#define AC_VERB_SET_SDI_SELECT 0x704
|
||||
#define AC_VERB_SET_POWER_STATE 0x705
|
||||
#define AC_VERB_SET_CHANNEL_STREAMID 0x706
|
||||
#define AC_VERB_SET_PIN_WIDGET_CONTROL 0x707
|
||||
#define AC_VERB_SET_UNSOLICITED_ENABLE 0x708
|
||||
#define AC_VERB_SET_PIN_SENSE 0x709
|
||||
#define AC_VERB_SET_BEEP_CONTROL 0x70a
|
||||
#define AC_VERB_SET_EAPD_BTLENABLE 0x70c
|
||||
#define AC_VERB_SET_DIGI_CONVERT_1 0x70d
|
||||
#define AC_VERB_SET_DIGI_CONVERT_2 0x70e
|
||||
#define AC_VERB_SET_VOLUME_KNOB_CONTROL 0x70f
|
||||
#define AC_VERB_SET_GPIO_DATA 0x715
|
||||
#define AC_VERB_SET_GPIO_MASK 0x716
|
||||
#define AC_VERB_SET_GPIO_DIRECTION 0x717
|
||||
#define AC_VERB_SET_GPIO_WAKE_MASK 0x718
|
||||
#define AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK 0x719
|
||||
#define AC_VERB_SET_GPIO_STICKY_MASK 0x71a
|
||||
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 0x71c
|
||||
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d
|
||||
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e
|
||||
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3 0x71f
|
||||
#define AC_VERB_SET_EAPD 0x788
|
||||
#define AC_VERB_SET_CODEC_RESET 0x7ff
|
||||
#define AC_VERB_SET_CVT_CHAN_COUNT 0x72d
|
||||
#define AC_VERB_SET_HDMI_DIP_INDEX 0x730
|
||||
#define AC_VERB_SET_HDMI_DIP_DATA 0x731
|
||||
#define AC_VERB_SET_HDMI_DIP_XMIT 0x732
|
||||
#define AC_VERB_SET_HDMI_CP_CTRL 0x733
|
||||
#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734
|
||||
#define AC_VERB_SET_DEVICE_SEL 0x735
|
||||
|
||||
/*
|
||||
* Parameter IDs
|
||||
*/
|
||||
#define AC_PAR_VENDOR_ID 0x00
|
||||
#define AC_PAR_SUBSYSTEM_ID 0x01
|
||||
#define AC_PAR_REV_ID 0x02
|
||||
#define AC_PAR_NODE_COUNT 0x04
|
||||
#define AC_PAR_FUNCTION_TYPE 0x05
|
||||
#define AC_PAR_AUDIO_FG_CAP 0x08
|
||||
#define AC_PAR_AUDIO_WIDGET_CAP 0x09
|
||||
#define AC_PAR_PCM 0x0a
|
||||
#define AC_PAR_STREAM 0x0b
|
||||
#define AC_PAR_PIN_CAP 0x0c
|
||||
#define AC_PAR_AMP_IN_CAP 0x0d
|
||||
#define AC_PAR_CONNLIST_LEN 0x0e
|
||||
#define AC_PAR_POWER_STATE 0x0f
|
||||
#define AC_PAR_PROC_CAP 0x10
|
||||
#define AC_PAR_GPIO_CAP 0x11
|
||||
#define AC_PAR_AMP_OUT_CAP 0x12
|
||||
#define AC_PAR_VOL_KNB_CAP 0x13
|
||||
#define AC_PAR_DEVLIST_LEN 0x15
|
||||
#define AC_PAR_HDMI_LPCM_CAP 0x20
|
||||
|
||||
/*
|
||||
* AC_VERB_PARAMETERS results (32bit)
|
||||
*/
|
||||
|
||||
/* Function Group Type */
|
||||
#define AC_FGT_TYPE (0xff<<0)
|
||||
#define AC_FGT_TYPE_SHIFT 0
|
||||
#define AC_FGT_UNSOL_CAP (1<<8)
|
||||
|
||||
/* Audio Function Group Capabilities */
|
||||
#define AC_AFG_OUT_DELAY (0xf<<0)
|
||||
#define AC_AFG_IN_DELAY (0xf<<8)
|
||||
#define AC_AFG_BEEP_GEN (1<<16)
|
||||
|
||||
/* Audio Widget Capabilities */
|
||||
#define AC_WCAP_STEREO (1<<0) /* stereo I/O */
|
||||
#define AC_WCAP_IN_AMP (1<<1) /* AMP-in present */
|
||||
#define AC_WCAP_OUT_AMP (1<<2) /* AMP-out present */
|
||||
#define AC_WCAP_AMP_OVRD (1<<3) /* AMP-parameter override */
|
||||
#define AC_WCAP_FORMAT_OVRD (1<<4) /* format override */
|
||||
#define AC_WCAP_STRIPE (1<<5) /* stripe */
|
||||
#define AC_WCAP_PROC_WID (1<<6) /* Proc Widget */
|
||||
#define AC_WCAP_UNSOL_CAP (1<<7) /* Unsol capable */
|
||||
#define AC_WCAP_CONN_LIST (1<<8) /* connection list */
|
||||
#define AC_WCAP_DIGITAL (1<<9) /* digital I/O */
|
||||
#define AC_WCAP_POWER (1<<10) /* power control */
|
||||
#define AC_WCAP_LR_SWAP (1<<11) /* L/R swap */
|
||||
#define AC_WCAP_CP_CAPS (1<<12) /* content protection */
|
||||
#define AC_WCAP_CHAN_CNT_EXT (7<<13) /* channel count ext */
|
||||
#define AC_WCAP_DELAY (0xf<<16)
|
||||
#define AC_WCAP_DELAY_SHIFT 16
|
||||
#define AC_WCAP_TYPE (0xf<<20)
|
||||
#define AC_WCAP_TYPE_SHIFT 20
|
||||
|
||||
/* supported PCM rates and bits */
|
||||
#define AC_SUPPCM_RATES (0xfff << 0)
|
||||
#define AC_SUPPCM_BITS_8 (1<<16)
|
||||
#define AC_SUPPCM_BITS_16 (1<<17)
|
||||
#define AC_SUPPCM_BITS_20 (1<<18)
|
||||
#define AC_SUPPCM_BITS_24 (1<<19)
|
||||
#define AC_SUPPCM_BITS_32 (1<<20)
|
||||
|
||||
/* supported PCM stream format */
|
||||
#define AC_SUPFMT_PCM (1<<0)
|
||||
#define AC_SUPFMT_FLOAT32 (1<<1)
|
||||
#define AC_SUPFMT_AC3 (1<<2)
|
||||
|
||||
/* GP I/O count */
|
||||
#define AC_GPIO_IO_COUNT (0xff<<0)
|
||||
#define AC_GPIO_O_COUNT (0xff<<8)
|
||||
#define AC_GPIO_O_COUNT_SHIFT 8
|
||||
#define AC_GPIO_I_COUNT (0xff<<16)
|
||||
#define AC_GPIO_I_COUNT_SHIFT 16
|
||||
#define AC_GPIO_UNSOLICITED (1<<30)
|
||||
#define AC_GPIO_WAKE (1<<31)
|
||||
|
||||
/* Converter stream, channel */
|
||||
#define AC_CONV_CHANNEL (0xf<<0)
|
||||
#define AC_CONV_STREAM (0xf<<4)
|
||||
#define AC_CONV_STREAM_SHIFT 4
|
||||
|
||||
/* Input converter SDI select */
|
||||
#define AC_SDI_SELECT (0xf<<0)
|
||||
|
||||
/* stream format id */
|
||||
#define AC_FMT_CHAN_SHIFT 0
|
||||
#define AC_FMT_CHAN_MASK (0x0f << 0)
|
||||
#define AC_FMT_BITS_SHIFT 4
|
||||
#define AC_FMT_BITS_MASK (7 << 4)
|
||||
#define AC_FMT_BITS_8 (0 << 4)
|
||||
#define AC_FMT_BITS_16 (1 << 4)
|
||||
#define AC_FMT_BITS_20 (2 << 4)
|
||||
#define AC_FMT_BITS_24 (3 << 4)
|
||||
#define AC_FMT_BITS_32 (4 << 4)
|
||||
#define AC_FMT_DIV_SHIFT 8
|
||||
#define AC_FMT_DIV_MASK (7 << 8)
|
||||
#define AC_FMT_MULT_SHIFT 11
|
||||
#define AC_FMT_MULT_MASK (7 << 11)
|
||||
#define AC_FMT_BASE_SHIFT 14
|
||||
#define AC_FMT_BASE_48K (0 << 14)
|
||||
#define AC_FMT_BASE_44K (1 << 14)
|
||||
#define AC_FMT_TYPE_SHIFT 15
|
||||
#define AC_FMT_TYPE_PCM (0 << 15)
|
||||
#define AC_FMT_TYPE_NON_PCM (1 << 15)
|
||||
|
||||
/* Unsolicited response control */
|
||||
#define AC_UNSOL_TAG (0x3f<<0)
|
||||
#define AC_UNSOL_ENABLED (1<<7)
|
||||
#define AC_USRSP_EN AC_UNSOL_ENABLED
|
||||
|
||||
/* Unsolicited responses */
|
||||
#define AC_UNSOL_RES_TAG (0x3f<<26)
|
||||
#define AC_UNSOL_RES_TAG_SHIFT 26
|
||||
#define AC_UNSOL_RES_SUBTAG (0x1f<<21)
|
||||
#define AC_UNSOL_RES_SUBTAG_SHIFT 21
|
||||
#define AC_UNSOL_RES_DE (0x3f<<15) /* Device Entry
|
||||
* (for DP1.2 MST)
|
||||
*/
|
||||
#define AC_UNSOL_RES_DE_SHIFT 15
|
||||
#define AC_UNSOL_RES_IA (1<<2) /* Inactive (for DP1.2 MST) */
|
||||
#define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */
|
||||
#define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */
|
||||
#define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */
|
||||
#define AC_UNSOL_RES_CP_READY (1<<0) /* content protection */
|
||||
|
||||
/* Pin widget capabilies */
|
||||
#define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */
|
||||
#define AC_PINCAP_TRIG_REQ (1<<1) /* trigger required */
|
||||
#define AC_PINCAP_PRES_DETECT (1<<2) /* presence detect capable */
|
||||
#define AC_PINCAP_HP_DRV (1<<3) /* headphone drive capable */
|
||||
#define AC_PINCAP_OUT (1<<4) /* output capable */
|
||||
#define AC_PINCAP_IN (1<<5) /* input capable */
|
||||
#define AC_PINCAP_BALANCE (1<<6) /* balanced I/O capable */
|
||||
/* Note: This LR_SWAP pincap is defined in the Realtek ALC883 specification,
|
||||
* but is marked reserved in the Intel HDA specification.
|
||||
*/
|
||||
#define AC_PINCAP_LR_SWAP (1<<7) /* L/R swap */
|
||||
/* Note: The same bit as LR_SWAP is newly defined as HDMI capability
|
||||
* in HD-audio specification
|
||||
*/
|
||||
#define AC_PINCAP_HDMI (1<<7) /* HDMI pin */
|
||||
#define AC_PINCAP_DP (1<<24) /* DisplayPort pin, can
|
||||
* coexist with AC_PINCAP_HDMI
|
||||
*/
|
||||
#define AC_PINCAP_VREF (0x37<<8)
|
||||
#define AC_PINCAP_VREF_SHIFT 8
|
||||
#define AC_PINCAP_EAPD (1<<16) /* EAPD capable */
|
||||
#define AC_PINCAP_HBR (1<<27) /* High Bit Rate */
|
||||
/* Vref status (used in pin cap) */
|
||||
#define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */
|
||||
#define AC_PINCAP_VREF_50 (1<<1) /* 50% */
|
||||
#define AC_PINCAP_VREF_GRD (1<<2) /* ground */
|
||||
#define AC_PINCAP_VREF_80 (1<<4) /* 80% */
|
||||
#define AC_PINCAP_VREF_100 (1<<5) /* 100% */
|
||||
|
||||
/* Amplifier capabilities */
|
||||
#define AC_AMPCAP_OFFSET (0x7f<<0) /* 0dB offset */
|
||||
#define AC_AMPCAP_OFFSET_SHIFT 0
|
||||
#define AC_AMPCAP_NUM_STEPS (0x7f<<8) /* number of steps */
|
||||
#define AC_AMPCAP_NUM_STEPS_SHIFT 8
|
||||
#define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB
|
||||
* in 0.25dB
|
||||
*/
|
||||
#define AC_AMPCAP_STEP_SIZE_SHIFT 16
|
||||
#define AC_AMPCAP_MUTE (1<<31) /* mute capable */
|
||||
#define AC_AMPCAP_MUTE_SHIFT 31
|
||||
|
||||
/* driver-specific amp-caps: using bits 24-30 */
|
||||
#define AC_AMPCAP_MIN_MUTE (1 << 30) /* min-volume = mute */
|
||||
|
||||
/* Connection list */
|
||||
#define AC_CLIST_LENGTH (0x7f<<0)
|
||||
#define AC_CLIST_LONG (1<<7)
|
||||
|
||||
/* Supported power status */
|
||||
#define AC_PWRST_D0SUP (1<<0)
|
||||
#define AC_PWRST_D1SUP (1<<1)
|
||||
#define AC_PWRST_D2SUP (1<<2)
|
||||
#define AC_PWRST_D3SUP (1<<3)
|
||||
#define AC_PWRST_D3COLDSUP (1<<4)
|
||||
#define AC_PWRST_S3D3COLDSUP (1<<29)
|
||||
#define AC_PWRST_CLKSTOP (1<<30)
|
||||
#define AC_PWRST_EPSS (1U<<31)
|
||||
|
||||
/* Power state values */
|
||||
#define AC_PWRST_SETTING (0xf<<0)
|
||||
#define AC_PWRST_ACTUAL (0xf<<4)
|
||||
#define AC_PWRST_ACTUAL_SHIFT 4
|
||||
#define AC_PWRST_D0 0x00
|
||||
#define AC_PWRST_D1 0x01
|
||||
#define AC_PWRST_D2 0x02
|
||||
#define AC_PWRST_D3 0x03
|
||||
#define AC_PWRST_ERROR (1<<8)
|
||||
#define AC_PWRST_CLK_STOP_OK (1<<9)
|
||||
#define AC_PWRST_SETTING_RESET (1<<10)
|
||||
|
||||
/* Processing capabilies */
|
||||
#define AC_PCAP_BENIGN (1<<0)
|
||||
#define AC_PCAP_NUM_COEF (0xff<<8)
|
||||
#define AC_PCAP_NUM_COEF_SHIFT 8
|
||||
|
||||
/* Volume knobs capabilities */
|
||||
#define AC_KNBCAP_NUM_STEPS (0x7f<<0)
|
||||
#define AC_KNBCAP_DELTA (1<<7)
|
||||
|
||||
/* HDMI LPCM capabilities */
|
||||
#define AC_LPCMCAP_48K_CP_CHNS (0x0f<<0) /* max channels w/ CP-on */
|
||||
#define AC_LPCMCAP_48K_NO_CHNS (0x0f<<4) /* max channels w/o CP-on */
|
||||
#define AC_LPCMCAP_48K_20BIT (1<<8) /* 20b bitrate supported */
|
||||
#define AC_LPCMCAP_48K_24BIT (1<<9) /* 24b bitrate supported */
|
||||
#define AC_LPCMCAP_96K_CP_CHNS (0x0f<<10) /* max channels w/ CP-on */
|
||||
#define AC_LPCMCAP_96K_NO_CHNS (0x0f<<14) /* max channels w/o CP-on */
|
||||
#define AC_LPCMCAP_96K_20BIT (1<<18) /* 20b bitrate supported */
|
||||
#define AC_LPCMCAP_96K_24BIT (1<<19) /* 24b bitrate supported */
|
||||
#define AC_LPCMCAP_192K_CP_CHNS (0x0f<<20) /* max channels w/ CP-on */
|
||||
#define AC_LPCMCAP_192K_NO_CHNS (0x0f<<24) /* max channels w/o CP-on */
|
||||
#define AC_LPCMCAP_192K_20BIT (1<<28) /* 20b bitrate supported */
|
||||
#define AC_LPCMCAP_192K_24BIT (1<<29) /* 24b bitrate supported */
|
||||
#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */
|
||||
#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */
|
||||
|
||||
/* Display pin's device list length */
|
||||
#define AC_DEV_LIST_LEN_MASK 0x3f
|
||||
#define AC_MAX_DEV_LIST_LEN 64
|
||||
|
||||
/*
|
||||
* Control Parameters
|
||||
*/
|
||||
|
||||
/* Amp gain/mute */
|
||||
#define AC_AMP_MUTE (1<<7)
|
||||
#define AC_AMP_GAIN (0x7f)
|
||||
#define AC_AMP_GET_INDEX (0xf<<0)
|
||||
|
||||
#define AC_AMP_GET_LEFT (1<<13)
|
||||
#define AC_AMP_GET_RIGHT (0<<13)
|
||||
#define AC_AMP_GET_OUTPUT (1<<15)
|
||||
#define AC_AMP_GET_INPUT (0<<15)
|
||||
|
||||
#define AC_AMP_SET_INDEX (0xf<<8)
|
||||
#define AC_AMP_SET_INDEX_SHIFT 8
|
||||
#define AC_AMP_SET_RIGHT (1<<12)
|
||||
#define AC_AMP_SET_LEFT (1<<13)
|
||||
#define AC_AMP_SET_INPUT (1<<14)
|
||||
#define AC_AMP_SET_OUTPUT (1<<15)
|
||||
|
||||
/* DIGITAL1 bits */
|
||||
#define AC_DIG1_ENABLE (1<<0)
|
||||
#define AC_DIG1_V (1<<1)
|
||||
#define AC_DIG1_VCFG (1<<2)
|
||||
#define AC_DIG1_EMPHASIS (1<<3)
|
||||
#define AC_DIG1_COPYRIGHT (1<<4)
|
||||
#define AC_DIG1_NONAUDIO (1<<5)
|
||||
#define AC_DIG1_PROFESSIONAL (1<<6)
|
||||
#define AC_DIG1_LEVEL (1<<7)
|
||||
|
||||
/* DIGITAL2 bits */
|
||||
#define AC_DIG2_CC (0x7f<<0)
|
||||
|
||||
/* DIGITAL3 bits */
|
||||
#define AC_DIG3_ICT (0xf<<0)
|
||||
#define AC_DIG3_KAE (1<<7)
|
||||
|
||||
/* Pin widget control - 8bit */
|
||||
#define AC_PINCTL_EPT (0x3<<0)
|
||||
#define AC_PINCTL_EPT_NATIVE 0
|
||||
#define AC_PINCTL_EPT_HBR 3
|
||||
#define AC_PINCTL_VREFEN (0x7<<0)
|
||||
#define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */
|
||||
#define AC_PINCTL_VREF_50 1 /* 50% */
|
||||
#define AC_PINCTL_VREF_GRD 2 /* ground */
|
||||
#define AC_PINCTL_VREF_80 4 /* 80% */
|
||||
#define AC_PINCTL_VREF_100 5 /* 100% */
|
||||
#define AC_PINCTL_IN_EN (1<<5)
|
||||
#define AC_PINCTL_OUT_EN (1<<6)
|
||||
#define AC_PINCTL_HP_EN (1<<7)
|
||||
|
||||
/* Pin sense - 32bit */
|
||||
#define AC_PINSENSE_IMPEDANCE_MASK (0x7fffffff)
|
||||
#define AC_PINSENSE_PRESENCE (1<<31)
|
||||
#define AC_PINSENSE_ELDV (1<<30) /* ELD valid (HDMI) */
|
||||
|
||||
/* EAPD/BTL enable - 32bit */
|
||||
#define AC_EAPDBTL_BALANCED (1<<0)
|
||||
#define AC_EAPDBTL_EAPD (1<<1)
|
||||
#define AC_EAPDBTL_LR_SWAP (1<<2)
|
||||
|
||||
/* HDMI ELD data */
|
||||
#define AC_ELDD_ELD_VALID (1<<31)
|
||||
#define AC_ELDD_ELD_DATA 0xff
|
||||
|
||||
/* HDMI DIP size */
|
||||
#define AC_DIPSIZE_ELD_BUF (1<<3) /* ELD buf size of packet size */
|
||||
#define AC_DIPSIZE_PACK_IDX (0x07<<0) /* packet index */
|
||||
|
||||
/* HDMI DIP index */
|
||||
#define AC_DIPIDX_PACK_IDX (0x07<<5) /* packet idnex */
|
||||
#define AC_DIPIDX_BYTE_IDX (0x1f<<0) /* byte index */
|
||||
|
||||
/* HDMI DIP xmit (transmit) control */
|
||||
#define AC_DIPXMIT_MASK (0x3<<6)
|
||||
#define AC_DIPXMIT_DISABLE (0x0<<6) /* disable xmit */
|
||||
#define AC_DIPXMIT_ONCE (0x2<<6) /* xmit once then disable */
|
||||
#define AC_DIPXMIT_BEST (0x3<<6) /* best effort */
|
||||
|
||||
/* HDMI content protection (CP) control */
|
||||
#define AC_CPCTRL_CES (1<<9) /* current encryption state */
|
||||
#define AC_CPCTRL_READY (1<<8) /* ready bit */
|
||||
#define AC_CPCTRL_SUBTAG (0x1f<<3) /* subtag for unsol-resp */
|
||||
#define AC_CPCTRL_STATE (3<<0) /* current CP request state */
|
||||
|
||||
/* Converter channel <-> HDMI slot mapping */
|
||||
#define AC_CVTMAP_HDMI_SLOT (0xf<<0) /* HDMI slot number */
|
||||
#define AC_CVTMAP_CHAN (0xf<<4) /* converter channel number */
|
||||
|
||||
/* configuration default - 32bit */
|
||||
#define AC_DEFCFG_SEQUENCE (0xf<<0)
|
||||
#define AC_DEFCFG_DEF_ASSOC (0xf<<4)
|
||||
#define AC_DEFCFG_ASSOC_SHIFT 4
|
||||
#define AC_DEFCFG_MISC (0xf<<8)
|
||||
#define AC_DEFCFG_MISC_SHIFT 8
|
||||
#define AC_DEFCFG_MISC_NO_PRESENCE (1<<0)
|
||||
#define AC_DEFCFG_COLOR (0xf<<12)
|
||||
#define AC_DEFCFG_COLOR_SHIFT 12
|
||||
#define AC_DEFCFG_CONN_TYPE (0xf<<16)
|
||||
#define AC_DEFCFG_CONN_TYPE_SHIFT 16
|
||||
#define AC_DEFCFG_DEVICE (0xf<<20)
|
||||
#define AC_DEFCFG_DEVICE_SHIFT 20
|
||||
#define AC_DEFCFG_LOCATION (0x3f<<24)
|
||||
#define AC_DEFCFG_LOCATION_SHIFT 24
|
||||
#define AC_DEFCFG_PORT_CONN (0x3<<30)
|
||||
#define AC_DEFCFG_PORT_CONN_SHIFT 30
|
||||
|
||||
/* Display pin's device list entry */
|
||||
#define AC_DE_PD (1<<0)
|
||||
#define AC_DE_ELDV (1<<1)
|
||||
#define AC_DE_IA (1<<2)
|
||||
|
||||
/* device device types (0x0-0xf) */
|
||||
enum {
|
||||
AC_JACK_LINE_OUT,
|
||||
AC_JACK_SPEAKER,
|
||||
AC_JACK_HP_OUT,
|
||||
AC_JACK_CD,
|
||||
AC_JACK_SPDIF_OUT,
|
||||
AC_JACK_DIG_OTHER_OUT,
|
||||
AC_JACK_MODEM_LINE_SIDE,
|
||||
AC_JACK_MODEM_HAND_SIDE,
|
||||
AC_JACK_LINE_IN,
|
||||
AC_JACK_AUX,
|
||||
AC_JACK_MIC_IN,
|
||||
AC_JACK_TELEPHONY,
|
||||
AC_JACK_SPDIF_IN,
|
||||
AC_JACK_DIG_OTHER_IN,
|
||||
AC_JACK_OTHER = 0xf,
|
||||
};
|
||||
|
||||
/* jack connection types (0x0-0xf) */
|
||||
enum {
|
||||
AC_JACK_CONN_UNKNOWN,
|
||||
AC_JACK_CONN_1_8,
|
||||
AC_JACK_CONN_1_4,
|
||||
AC_JACK_CONN_ATAPI,
|
||||
AC_JACK_CONN_RCA,
|
||||
AC_JACK_CONN_OPTICAL,
|
||||
AC_JACK_CONN_OTHER_DIGITAL,
|
||||
AC_JACK_CONN_OTHER_ANALOG,
|
||||
AC_JACK_CONN_DIN,
|
||||
AC_JACK_CONN_XLR,
|
||||
AC_JACK_CONN_RJ11,
|
||||
AC_JACK_CONN_COMB,
|
||||
AC_JACK_CONN_OTHER = 0xf,
|
||||
};
|
||||
|
||||
/* jack colors (0x0-0xf) */
|
||||
enum {
|
||||
AC_JACK_COLOR_UNKNOWN,
|
||||
AC_JACK_COLOR_BLACK,
|
||||
AC_JACK_COLOR_GREY,
|
||||
AC_JACK_COLOR_BLUE,
|
||||
AC_JACK_COLOR_GREEN,
|
||||
AC_JACK_COLOR_RED,
|
||||
AC_JACK_COLOR_ORANGE,
|
||||
AC_JACK_COLOR_YELLOW,
|
||||
AC_JACK_COLOR_PURPLE,
|
||||
AC_JACK_COLOR_PINK,
|
||||
AC_JACK_COLOR_WHITE = 0xe,
|
||||
AC_JACK_COLOR_OTHER,
|
||||
};
|
||||
|
||||
/* Jack location (0x0-0x3f) */
|
||||
/* common case */
|
||||
enum {
|
||||
AC_JACK_LOC_NONE,
|
||||
AC_JACK_LOC_REAR,
|
||||
AC_JACK_LOC_FRONT,
|
||||
AC_JACK_LOC_LEFT,
|
||||
AC_JACK_LOC_RIGHT,
|
||||
AC_JACK_LOC_TOP,
|
||||
AC_JACK_LOC_BOTTOM,
|
||||
};
|
||||
/* bits 4-5 */
|
||||
enum {
|
||||
AC_JACK_LOC_EXTERNAL = 0x00,
|
||||
AC_JACK_LOC_INTERNAL = 0x10,
|
||||
AC_JACK_LOC_SEPARATE = 0x20,
|
||||
AC_JACK_LOC_OTHER = 0x30,
|
||||
};
|
||||
enum {
|
||||
/* external on primary chasis */
|
||||
AC_JACK_LOC_REAR_PANEL = 0x07,
|
||||
AC_JACK_LOC_DRIVE_BAY,
|
||||
/* internal */
|
||||
AC_JACK_LOC_RISER = 0x17,
|
||||
AC_JACK_LOC_HDMI,
|
||||
AC_JACK_LOC_ATAPI,
|
||||
/* others */
|
||||
AC_JACK_LOC_MOBILE_IN = 0x37,
|
||||
AC_JACK_LOC_MOBILE_OUT,
|
||||
};
|
||||
|
||||
/* Port connectivity (0-3) */
|
||||
enum {
|
||||
AC_JACK_PORT_COMPLEX,
|
||||
AC_JACK_PORT_NONE,
|
||||
AC_JACK_PORT_FIXED,
|
||||
AC_JACK_PORT_BOTH,
|
||||
};
|
||||
|
||||
/* max. codec address */
|
||||
#define HDA_MAX_CODEC_ADDRESS 0x0f
|
||||
|
||||
#endif /* __SOUND_HDA_VERBS_H */
|
@ -149,13 +149,6 @@ int snd_dma_alloc_pages_fallback(int type, struct device *dev, size_t size,
|
||||
struct snd_dma_buffer *dmab);
|
||||
void snd_dma_free_pages(struct snd_dma_buffer *dmab);
|
||||
|
||||
/* buffer-preservation managements */
|
||||
|
||||
#define snd_dma_pci_buf_id(pci) (((unsigned int)(pci)->vendor << 16) | (pci)->device)
|
||||
|
||||
size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id);
|
||||
int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id);
|
||||
|
||||
/* basic memory allocation functions */
|
||||
void *snd_malloc_pages(size_t size, gfp_t gfp_flags);
|
||||
void snd_free_pages(void *ptr, size_t size);
|
||||
|
@ -381,7 +381,6 @@ struct snd_pcm_substream {
|
||||
struct pm_qos_request latency_pm_qos_req; /* pm_qos request */
|
||||
size_t buffer_bytes_max; /* limit ring buffer size */
|
||||
struct snd_dma_buffer dma_buffer;
|
||||
unsigned int dma_buf_id;
|
||||
size_t dma_max;
|
||||
/* -- hardware operations -- */
|
||||
const struct snd_pcm_ops *ops;
|
||||
@ -901,6 +900,8 @@ extern const struct snd_pcm_hw_constraint_list snd_pcm_known_rates;
|
||||
int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime);
|
||||
unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate);
|
||||
unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit);
|
||||
unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a,
|
||||
unsigned int rates_b);
|
||||
|
||||
static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream,
|
||||
struct snd_dma_buffer *bufp)
|
||||
|
@ -354,4 +354,16 @@ params_period_bytes(const struct snd_pcm_hw_params *p)
|
||||
params_channels(p)) / 8;
|
||||
}
|
||||
|
||||
static inline int
|
||||
params_width(const struct snd_pcm_hw_params *p)
|
||||
{
|
||||
return snd_pcm_format_width(params_format(p));
|
||||
}
|
||||
|
||||
static inline int
|
||||
params_physical_width(const struct snd_pcm_hw_params *p)
|
||||
{
|
||||
return snd_pcm_format_physical_width(params_format(p));
|
||||
}
|
||||
|
||||
#endif /* __SOUND_PCM_PARAMS_H */
|
||||
|
@ -18,7 +18,7 @@
|
||||
#define RSND_GEN1_ADG 1
|
||||
#define RSND_GEN1_SSI 2
|
||||
|
||||
#define RSND_GEN2_SRU 0
|
||||
#define RSND_GEN2_SCU 0
|
||||
#define RSND_GEN2_ADG 1
|
||||
#define RSND_GEN2_SSIU 2
|
||||
#define RSND_GEN2_SSI 3
|
||||
@ -58,6 +58,7 @@ struct rsnd_ssi_platform_info {
|
||||
|
||||
struct rsnd_scu_platform_info {
|
||||
u32 flags;
|
||||
u32 convert_rate; /* sampling rate convert */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -123,6 +123,8 @@ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
|
||||
int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
|
||||
int direction);
|
||||
|
||||
int snd_soc_dai_is_dummy(struct snd_soc_dai *dai);
|
||||
|
||||
struct snd_soc_dai_ops {
|
||||
/*
|
||||
* DAI clocking configuration, all optional.
|
||||
@ -220,6 +222,8 @@ struct snd_soc_dai_driver {
|
||||
struct snd_soc_pcm_stream capture;
|
||||
struct snd_soc_pcm_stream playback;
|
||||
unsigned int symmetric_rates:1;
|
||||
unsigned int symmetric_channels:1;
|
||||
unsigned int symmetric_samplebits:1;
|
||||
|
||||
/* probe ordering - for components with runtime dependencies */
|
||||
int probe_order;
|
||||
@ -244,6 +248,8 @@ struct snd_soc_dai {
|
||||
unsigned int capture_active:1; /* stream is in use */
|
||||
unsigned int playback_active:1; /* stream is in use */
|
||||
unsigned int symmetric_rates:1;
|
||||
unsigned int symmetric_channels:1;
|
||||
unsigned int symmetric_samplebits:1;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
unsigned int active;
|
||||
unsigned char probed:1;
|
||||
@ -258,6 +264,8 @@ struct snd_soc_dai {
|
||||
|
||||
/* Symmetry data - only valid if symmetry is being enforced */
|
||||
unsigned int rate;
|
||||
unsigned int channels;
|
||||
unsigned int sample_bits;
|
||||
|
||||
/* parent platform/codec */
|
||||
struct snd_soc_platform *platform;
|
||||
|
@ -412,6 +412,7 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
|
||||
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
|
||||
struct snd_soc_dai *dai);
|
||||
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_new_pcm(struct snd_soc_card *card,
|
||||
const struct snd_soc_pcm_stream *params,
|
||||
struct snd_soc_dapm_widget *source,
|
||||
|
@ -11,6 +11,7 @@
|
||||
#ifndef __LINUX_SND_SOC_DPCM_H
|
||||
#define __LINUX_SND_SOC_DPCM_H
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/list.h>
|
||||
#include <sound/pcm.h>
|
||||
|
||||
@ -135,4 +136,25 @@ int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute);
|
||||
int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd);
|
||||
int soc_dpcm_runtime_update(struct snd_soc_card *);
|
||||
|
||||
int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
|
||||
int stream, struct snd_soc_dapm_widget_list **list_);
|
||||
int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
|
||||
int stream, struct snd_soc_dapm_widget_list **list, int new);
|
||||
int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream);
|
||||
int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream);
|
||||
void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream);
|
||||
void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream);
|
||||
int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream);
|
||||
int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int tream);
|
||||
int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd);
|
||||
int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream);
|
||||
int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
|
||||
int event);
|
||||
|
||||
static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
|
||||
{
|
||||
kfree(*list);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -334,9 +334,7 @@ struct snd_soc_jack_pin;
|
||||
#include <sound/soc-dapm.h>
|
||||
#include <sound/soc-dpcm.h>
|
||||
|
||||
#ifdef CONFIG_GPIOLIB
|
||||
struct snd_soc_jack_gpio;
|
||||
#endif
|
||||
|
||||
typedef int (*hw_write_t)(void *,const char* ,int);
|
||||
|
||||
@ -446,6 +444,17 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
|
||||
struct snd_soc_jack_gpio *gpios);
|
||||
void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
|
||||
struct snd_soc_jack_gpio *gpios);
|
||||
#else
|
||||
static inline int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
|
||||
struct snd_soc_jack_gpio *gpios)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
|
||||
struct snd_soc_jack_gpio *gpios)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* codec register bit access */
|
||||
@ -580,7 +589,6 @@ struct snd_soc_jack_zone {
|
||||
* to provide more complex checks (eg, reading an
|
||||
* ADC).
|
||||
*/
|
||||
#ifdef CONFIG_GPIOLIB
|
||||
struct snd_soc_jack_gpio {
|
||||
unsigned int gpio;
|
||||
const char *name;
|
||||
@ -594,7 +602,6 @@ struct snd_soc_jack_gpio {
|
||||
|
||||
int (*jack_status_check)(void);
|
||||
};
|
||||
#endif
|
||||
|
||||
struct snd_soc_jack {
|
||||
struct mutex mutex;
|
||||
@ -879,6 +886,8 @@ struct snd_soc_dai_link {
|
||||
|
||||
/* Symmetry requirements */
|
||||
unsigned int symmetric_rates:1;
|
||||
unsigned int symmetric_channels:1;
|
||||
unsigned int symmetric_samplebits:1;
|
||||
|
||||
/* Do not create a PCM for this DAI link (Backend link) */
|
||||
unsigned int no_pcm:1;
|
||||
@ -886,6 +895,10 @@ struct snd_soc_dai_link {
|
||||
/* This DAI link can route to other DAI links at runtime (Frontend)*/
|
||||
unsigned int dynamic:1;
|
||||
|
||||
/* DPCM capture and Playback support */
|
||||
unsigned int dpcm_capture:1;
|
||||
unsigned int dpcm_playback:1;
|
||||
|
||||
/* pmdown_time is ignored at stop */
|
||||
unsigned int ignore_pmdown_time:1;
|
||||
|
||||
@ -1029,6 +1042,7 @@ struct snd_soc_pcm_runtime {
|
||||
|
||||
/* Dynamic PCM BE runtime data */
|
||||
struct snd_soc_dpcm_runtime dpcm[2];
|
||||
int fe_compr;
|
||||
|
||||
long pmdown_time;
|
||||
unsigned char pop_wait:1;
|
||||
|
@ -29,7 +29,6 @@ struct spear_dma_data {
|
||||
dma_addr_t addr;
|
||||
u32 max_burst;
|
||||
enum dma_slave_buswidth addr_width;
|
||||
bool (*filter)(struct dma_chan *chan, void *slave);
|
||||
};
|
||||
|
||||
#endif /* SPEAR_DMA_H */
|
||||
|
@ -57,6 +57,7 @@
|
||||
#define MAX_NUM_CODECS 32
|
||||
#define MAX_NUM_CODEC_DESCRIPTORS 32
|
||||
#define MAX_NUM_BITRATES 32
|
||||
#define MAX_NUM_SAMPLE_RATES 32
|
||||
|
||||
/* Codecs are listed linearly to allow for extensibility */
|
||||
#define SND_AUDIOCODEC_PCM ((__u32) 0x00000001)
|
||||
@ -324,7 +325,8 @@ union snd_codec_options {
|
||||
|
||||
/** struct snd_codec_desc - description of codec capabilities
|
||||
* @max_ch: Maximum number of audio channels
|
||||
* @sample_rates: Sampling rates in Hz, use SNDRV_PCM_RATE_xxx for this
|
||||
* @sample_rates: Sampling rates in Hz, use values like 48000 for this
|
||||
* @num_sample_rates: Number of valid values in sample_rates array
|
||||
* @bit_rate: Indexed array containing supported bit rates
|
||||
* @num_bitrates: Number of valid values in bit_rate array
|
||||
* @rate_control: value is specified by SND_RATECONTROLMODE defines.
|
||||
@ -346,7 +348,8 @@ union snd_codec_options {
|
||||
|
||||
struct snd_codec_desc {
|
||||
__u32 max_ch;
|
||||
__u32 sample_rates;
|
||||
__u32 sample_rates[MAX_NUM_SAMPLE_RATES];
|
||||
__u32 num_sample_rates;
|
||||
__u32 bit_rate[MAX_NUM_BITRATES];
|
||||
__u32 num_bitrates;
|
||||
__u32 rate_control;
|
||||
@ -364,7 +367,8 @@ struct snd_codec_desc {
|
||||
* @ch_out: Number of output channels. In case of contradiction between
|
||||
* this field and the channelMode field, the channelMode field
|
||||
* overrides.
|
||||
* @sample_rate: Audio sample rate of input data
|
||||
* @sample_rate: Audio sample rate of input data in Hz, use values like 48000
|
||||
* for this.
|
||||
* @bit_rate: Bitrate of encoded data. May be ignored by decoders
|
||||
* @rate_control: Encoding rate control. See SND_RATECONTROLMODE defines.
|
||||
* Encoders may rely on profiles for quality levels.
|
||||
|
@ -753,7 +753,7 @@ static struct snd_pcm_ops aaci_capture_ops = {
|
||||
* Power Management.
|
||||
*/
|
||||
#ifdef CONFIG_PM
|
||||
static int aaci_do_suspend(struct snd_card *card, unsigned int state)
|
||||
static int aaci_do_suspend(struct snd_card *card)
|
||||
{
|
||||
struct aaci *aaci = card->private_data;
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3cold);
|
||||
@ -761,28 +761,28 @@ static int aaci_do_suspend(struct snd_card *card, unsigned int state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aaci_do_resume(struct snd_card *card, unsigned int state)
|
||||
static int aaci_do_resume(struct snd_card *card)
|
||||
{
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aaci_suspend(struct amba_device *dev, pm_message_t state)
|
||||
static int aaci_suspend(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = amba_get_drvdata(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
return card ? aaci_do_suspend(card) : 0;
|
||||
}
|
||||
|
||||
static int aaci_resume(struct amba_device *dev)
|
||||
static int aaci_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = amba_get_drvdata(dev);
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
return card ? aaci_do_resume(card) : 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(aaci_dev_pm_ops, aaci_suspend, aaci_resume);
|
||||
#define AACI_DEV_PM_OPS (&aaci_dev_pm_ops)
|
||||
#else
|
||||
#define aaci_do_suspend NULL
|
||||
#define aaci_do_resume NULL
|
||||
#define aaci_suspend NULL
|
||||
#define aaci_resume NULL
|
||||
#define AACI_DEV_PM_OPS NULL
|
||||
#endif
|
||||
|
||||
|
||||
@ -1100,11 +1100,10 @@ MODULE_DEVICE_TABLE(amba, aaci_ids);
|
||||
static struct amba_driver aaci_driver = {
|
||||
.drv = {
|
||||
.name = DRIVER_NAME,
|
||||
.pm = AACI_DEV_PM_OPS,
|
||||
},
|
||||
.probe = aaci_probe,
|
||||
.remove = aaci_remove,
|
||||
.suspend = aaci_suspend,
|
||||
.resume = aaci_resume,
|
||||
.id_table = aaci_ids,
|
||||
};
|
||||
|
||||
|
@ -354,7 +354,7 @@ static int set_sample_rates(struct atmel_abdac *dac)
|
||||
/* we start at 192 kHz and work our way down to 5112 Hz */
|
||||
while (new_rate >= RATE_MIN && index < (MAX_NUM_RATES + 1)) {
|
||||
new_rate = clk_round_rate(dac->sample_clk, 256 * new_rate);
|
||||
if (new_rate < 0)
|
||||
if (new_rate <= 0)
|
||||
break;
|
||||
/* make sure we are below the ABDAC clock */
|
||||
if (index < MAX_NUM_RATES &&
|
||||
|
@ -10,14 +10,12 @@ snd-$(CONFIG_SND_VMASTER) += vmaster.o
|
||||
snd-$(CONFIG_SND_KCTL_JACK) += ctljack.o
|
||||
snd-$(CONFIG_SND_JACK) += jack.o
|
||||
|
||||
snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
|
||||
pcm_memory.o
|
||||
snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
|
||||
pcm_memory.o memalloc.o
|
||||
snd-pcm-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o
|
||||
|
||||
snd-pcm-dmaengine-objs := pcm_dmaengine.o
|
||||
|
||||
snd-page-alloc-y := memalloc.o
|
||||
snd-page-alloc-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o
|
||||
|
||||
snd-rawmidi-objs := rawmidi.o
|
||||
snd-timer-objs := timer.o
|
||||
snd-hrtimer-objs := hrtimer.o
|
||||
@ -31,7 +29,7 @@ obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o
|
||||
obj-$(CONFIG_SND_TIMER) += snd-timer.o
|
||||
obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o
|
||||
obj-$(CONFIG_SND_RTCTIMER) += snd-rtctimer.o
|
||||
obj-$(CONFIG_SND_PCM) += snd-pcm.o snd-page-alloc.o
|
||||
obj-$(CONFIG_SND_PCM) += snd-pcm.o
|
||||
obj-$(CONFIG_SND_DMAENGINE_PCM) += snd-pcm-dmaengine.o
|
||||
obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o
|
||||
|
||||
|
@ -501,9 +501,6 @@ static int snd_compress_check_input(struct snd_compr_params *params)
|
||||
if (params->codec.ch_in == 0 || params->codec.ch_out == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(params->codec.sample_rate & SNDRV_PCM_RATE_8000_192000))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -21,60 +21,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/genalloc.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <sound/memalloc.h>
|
||||
|
||||
|
||||
MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>");
|
||||
MODULE_DESCRIPTION("Memory allocator for ALSA system.");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
static DEFINE_MUTEX(list_mutex);
|
||||
static LIST_HEAD(mem_list_head);
|
||||
|
||||
/* buffer preservation list */
|
||||
struct snd_mem_list {
|
||||
struct snd_dma_buffer buffer;
|
||||
unsigned int id;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/* id for pre-allocated buffers */
|
||||
#define SNDRV_DMA_DEVICE_UNUSED (unsigned int)-1
|
||||
|
||||
/*
|
||||
*
|
||||
* Generic memory allocators
|
||||
*
|
||||
*/
|
||||
|
||||
static long snd_allocated_pages; /* holding the number of allocated pages */
|
||||
|
||||
static inline void inc_snd_pages(int order)
|
||||
{
|
||||
snd_allocated_pages += 1 << order;
|
||||
}
|
||||
|
||||
static inline void dec_snd_pages(int order)
|
||||
{
|
||||
snd_allocated_pages -= 1 << order;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_malloc_pages - allocate pages with the given size
|
||||
* @size: the size to allocate in bytes
|
||||
@ -87,7 +45,6 @@ static inline void dec_snd_pages(int order)
|
||||
void *snd_malloc_pages(size_t size, gfp_t gfp_flags)
|
||||
{
|
||||
int pg;
|
||||
void *res;
|
||||
|
||||
if (WARN_ON(!size))
|
||||
return NULL;
|
||||
@ -95,9 +52,7 @@ void *snd_malloc_pages(size_t size, gfp_t gfp_flags)
|
||||
return NULL;
|
||||
gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */
|
||||
pg = get_order(size);
|
||||
if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL)
|
||||
inc_snd_pages(pg);
|
||||
return res;
|
||||
return (void *) __get_free_pages(gfp_flags, pg);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,7 +69,6 @@ void snd_free_pages(void *ptr, size_t size)
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
pg = get_order(size);
|
||||
dec_snd_pages(pg);
|
||||
free_pages((unsigned long) ptr, pg);
|
||||
}
|
||||
|
||||
@ -129,7 +83,6 @@ void snd_free_pages(void *ptr, size_t size)
|
||||
static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *dma)
|
||||
{
|
||||
int pg;
|
||||
void *res;
|
||||
gfp_t gfp_flags;
|
||||
|
||||
if (WARN_ON(!dma))
|
||||
@ -139,11 +92,7 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d
|
||||
| __GFP_COMP /* compound page lets parts be mapped */
|
||||
| __GFP_NORETRY /* don't trigger OOM-killer */
|
||||
| __GFP_NOWARN; /* no stack trace print - this call is non-critical */
|
||||
res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags);
|
||||
if (res != NULL)
|
||||
inc_snd_pages(pg);
|
||||
|
||||
return res;
|
||||
return dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags);
|
||||
}
|
||||
|
||||
/* free the coherent DMA pages */
|
||||
@ -155,7 +104,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
pg = get_order(size);
|
||||
dec_snd_pages(pg);
|
||||
dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma);
|
||||
}
|
||||
|
||||
@ -340,256 +288,6 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* snd_dma_get_reserved - get the reserved buffer for the given device
|
||||
* @dmab: the buffer allocation record to store
|
||||
* @id: the buffer id
|
||||
*
|
||||
* Looks for the reserved-buffer list and re-uses if the same buffer
|
||||
* is found in the list. When the buffer is found, it's removed from the free list.
|
||||
*
|
||||
* Return: The size of buffer if the buffer is found, or zero if not found.
|
||||
*/
|
||||
size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id)
|
||||
{
|
||||
struct snd_mem_list *mem;
|
||||
|
||||
if (WARN_ON(!dmab))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&list_mutex);
|
||||
list_for_each_entry(mem, &mem_list_head, list) {
|
||||
if (mem->id == id &&
|
||||
(mem->buffer.dev.dev == NULL || dmab->dev.dev == NULL ||
|
||||
! memcmp(&mem->buffer.dev, &dmab->dev, sizeof(dmab->dev)))) {
|
||||
struct device *dev = dmab->dev.dev;
|
||||
list_del(&mem->list);
|
||||
*dmab = mem->buffer;
|
||||
if (dmab->dev.dev == NULL)
|
||||
dmab->dev.dev = dev;
|
||||
kfree(mem);
|
||||
mutex_unlock(&list_mutex);
|
||||
return dmab->bytes;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&list_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_dma_reserve_buf - reserve the buffer
|
||||
* @dmab: the buffer to reserve
|
||||
* @id: the buffer id
|
||||
*
|
||||
* Reserves the given buffer as a reserved buffer.
|
||||
*
|
||||
* Return: Zero if successful, or a negative code on error.
|
||||
*/
|
||||
int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id)
|
||||
{
|
||||
struct snd_mem_list *mem;
|
||||
|
||||
if (WARN_ON(!dmab))
|
||||
return -EINVAL;
|
||||
mem = kmalloc(sizeof(*mem), GFP_KERNEL);
|
||||
if (! mem)
|
||||
return -ENOMEM;
|
||||
mutex_lock(&list_mutex);
|
||||
mem->buffer = *dmab;
|
||||
mem->id = id;
|
||||
list_add_tail(&mem->list, &mem_list_head);
|
||||
mutex_unlock(&list_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* purge all reserved buffers
|
||||
*/
|
||||
static void free_all_reserved_pages(void)
|
||||
{
|
||||
struct list_head *p;
|
||||
struct snd_mem_list *mem;
|
||||
|
||||
mutex_lock(&list_mutex);
|
||||
while (! list_empty(&mem_list_head)) {
|
||||
p = mem_list_head.next;
|
||||
mem = list_entry(p, struct snd_mem_list, list);
|
||||
list_del(p);
|
||||
snd_dma_free_pages(&mem->buffer);
|
||||
kfree(mem);
|
||||
}
|
||||
mutex_unlock(&list_mutex);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
/*
|
||||
* proc file interface
|
||||
*/
|
||||
#define SND_MEM_PROC_FILE "driver/snd-page-alloc"
|
||||
static struct proc_dir_entry *snd_mem_proc;
|
||||
|
||||
static int snd_mem_proc_read(struct seq_file *seq, void *offset)
|
||||
{
|
||||
long pages = snd_allocated_pages >> (PAGE_SHIFT-12);
|
||||
struct snd_mem_list *mem;
|
||||
int devno;
|
||||
static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG" };
|
||||
|
||||
mutex_lock(&list_mutex);
|
||||
seq_printf(seq, "pages : %li bytes (%li pages per %likB)\n",
|
||||
pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
|
||||
devno = 0;
|
||||
list_for_each_entry(mem, &mem_list_head, list) {
|
||||
devno++;
|
||||
seq_printf(seq, "buffer %d : ID %08x : type %s\n",
|
||||
devno, mem->id, types[mem->buffer.dev.type]);
|
||||
seq_printf(seq, " addr = 0x%lx, size = %d bytes\n",
|
||||
(unsigned long)mem->buffer.addr,
|
||||
(int)mem->buffer.bytes);
|
||||
}
|
||||
mutex_unlock(&list_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_mem_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, snd_mem_proc_read, NULL);
|
||||
}
|
||||
|
||||
/* FIXME: for pci only - other bus? */
|
||||
#ifdef CONFIG_PCI
|
||||
#define gettoken(bufp) strsep(bufp, " \t\n")
|
||||
|
||||
static ssize_t snd_mem_proc_write(struct file *file, const char __user * buffer,
|
||||
size_t count, loff_t * ppos)
|
||||
{
|
||||
char buf[128];
|
||||
char *token, *p;
|
||||
|
||||
if (count > sizeof(buf) - 1)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(buf, buffer, count))
|
||||
return -EFAULT;
|
||||
buf[count] = '\0';
|
||||
|
||||
p = buf;
|
||||
token = gettoken(&p);
|
||||
if (! token || *token == '#')
|
||||
return count;
|
||||
if (strcmp(token, "add") == 0) {
|
||||
char *endp;
|
||||
int vendor, device, size, buffers;
|
||||
long mask;
|
||||
int i, alloced;
|
||||
struct pci_dev *pci;
|
||||
|
||||
if ((token = gettoken(&p)) == NULL ||
|
||||
(vendor = simple_strtol(token, NULL, 0)) <= 0 ||
|
||||
(token = gettoken(&p)) == NULL ||
|
||||
(device = simple_strtol(token, NULL, 0)) <= 0 ||
|
||||
(token = gettoken(&p)) == NULL ||
|
||||
(mask = simple_strtol(token, NULL, 0)) < 0 ||
|
||||
(token = gettoken(&p)) == NULL ||
|
||||
(size = memparse(token, &endp)) < 64*1024 ||
|
||||
size > 16*1024*1024 /* too big */ ||
|
||||
(token = gettoken(&p)) == NULL ||
|
||||
(buffers = simple_strtol(token, NULL, 0)) <= 0 ||
|
||||
buffers > 4) {
|
||||
printk(KERN_ERR "snd-page-alloc: invalid proc write format\n");
|
||||
return count;
|
||||
}
|
||||
vendor &= 0xffff;
|
||||
device &= 0xffff;
|
||||
|
||||
alloced = 0;
|
||||
pci = NULL;
|
||||
while ((pci = pci_get_device(vendor, device, pci)) != NULL) {
|
||||
if (mask > 0 && mask < 0xffffffff) {
|
||||
if (pci_set_dma_mask(pci, mask) < 0 ||
|
||||
pci_set_consistent_dma_mask(pci, mask) < 0) {
|
||||
printk(KERN_ERR "snd-page-alloc: cannot set DMA mask %lx for pci %04x:%04x\n", mask, vendor, device);
|
||||
pci_dev_put(pci);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < buffers; i++) {
|
||||
struct snd_dma_buffer dmab;
|
||||
memset(&dmab, 0, sizeof(dmab));
|
||||
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
|
||||
size, &dmab) < 0) {
|
||||
printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size);
|
||||
pci_dev_put(pci);
|
||||
return count;
|
||||
}
|
||||
snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci));
|
||||
}
|
||||
alloced++;
|
||||
}
|
||||
if (! alloced) {
|
||||
for (i = 0; i < buffers; i++) {
|
||||
struct snd_dma_buffer dmab;
|
||||
memset(&dmab, 0, sizeof(dmab));
|
||||
/* FIXME: We can allocate only in ZONE_DMA
|
||||
* without a device pointer!
|
||||
*/
|
||||
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, NULL,
|
||||
size, &dmab) < 0) {
|
||||
printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size);
|
||||
break;
|
||||
}
|
||||
snd_dma_reserve_buf(&dmab, (unsigned int)((vendor << 16) | device));
|
||||
}
|
||||
}
|
||||
} else if (strcmp(token, "erase") == 0)
|
||||
/* FIXME: need for releasing each buffer chunk? */
|
||||
free_all_reserved_pages();
|
||||
else
|
||||
printk(KERN_ERR "snd-page-alloc: invalid proc cmd\n");
|
||||
return count;
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
static const struct file_operations snd_mem_proc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = snd_mem_proc_open,
|
||||
.read = seq_read,
|
||||
#ifdef CONFIG_PCI
|
||||
.write = snd_mem_proc_write,
|
||||
#endif
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
/*
|
||||
* module entry
|
||||
*/
|
||||
|
||||
static int __init snd_mem_init(void)
|
||||
{
|
||||
#ifdef CONFIG_PROC_FS
|
||||
snd_mem_proc = proc_create(SND_MEM_PROC_FILE, 0644, NULL,
|
||||
&snd_mem_proc_fops);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit snd_mem_exit(void)
|
||||
{
|
||||
remove_proc_entry(SND_MEM_PROC_FILE, NULL);
|
||||
free_all_reserved_pages();
|
||||
if (snd_allocated_pages > 0)
|
||||
printk(KERN_ERR "snd-malloc: Memory leak? pages not freed = %li\n", snd_allocated_pages);
|
||||
}
|
||||
|
||||
|
||||
module_init(snd_mem_init)
|
||||
module_exit(snd_mem_exit)
|
||||
|
||||
|
||||
/*
|
||||
* exports
|
||||
*/
|
||||
@ -597,8 +295,5 @@ EXPORT_SYMBOL(snd_dma_alloc_pages);
|
||||
EXPORT_SYMBOL(snd_dma_alloc_pages_fallback);
|
||||
EXPORT_SYMBOL(snd_dma_free_pages);
|
||||
|
||||
EXPORT_SYMBOL(snd_dma_get_reserved_buf);
|
||||
EXPORT_SYMBOL(snd_dma_reserve_buf);
|
||||
|
||||
EXPORT_SYMBOL(snd_malloc_pages);
|
||||
EXPORT_SYMBOL(snd_free_pages);
|
||||
|
@ -51,17 +51,9 @@ static const size_t snd_minimum_buffer = 16384;
|
||||
static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t size)
|
||||
{
|
||||
struct snd_dma_buffer *dmab = &substream->dma_buffer;
|
||||
size_t orig_size = size;
|
||||
int err;
|
||||
|
||||
/* already reserved? */
|
||||
if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) {
|
||||
if (dmab->bytes >= size)
|
||||
return 0; /* yes */
|
||||
/* no, free the reserved block */
|
||||
snd_dma_free_pages(dmab);
|
||||
dmab->bytes = 0;
|
||||
}
|
||||
|
||||
do {
|
||||
if ((err = snd_dma_alloc_pages(dmab->dev.type, dmab->dev.dev,
|
||||
size, dmab)) < 0) {
|
||||
@ -72,6 +64,10 @@ static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t siz
|
||||
size >>= 1;
|
||||
} while (size >= snd_minimum_buffer);
|
||||
dmab->bytes = 0; /* tell error */
|
||||
pr_warn("ALSA pcmC%dD%d%c,%d:%s: cannot preallocate for size %zu\n",
|
||||
substream->pcm->card->number, substream->pcm->device,
|
||||
substream->stream ? 'c' : 'p', substream->number,
|
||||
substream->pcm->name, orig_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -82,10 +78,7 @@ static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream
|
||||
{
|
||||
if (substream->dma_buffer.area == NULL)
|
||||
return;
|
||||
if (substream->dma_buf_id)
|
||||
snd_dma_reserve_buf(&substream->dma_buffer, substream->dma_buf_id);
|
||||
else
|
||||
snd_dma_free_pages(&substream->dma_buffer);
|
||||
snd_dma_free_pages(&substream->dma_buffer);
|
||||
substream->dma_buffer.area = NULL;
|
||||
}
|
||||
|
||||
@ -260,11 +253,6 @@ static int snd_pcm_lib_preallocate_pages1(struct snd_pcm_substream *substream,
|
||||
*
|
||||
* Do pre-allocation for the given DMA buffer type.
|
||||
*
|
||||
* When substream->dma_buf_id is set, the function tries to look for
|
||||
* the reserved buffer, and the buffer is not freed but reserved at
|
||||
* destruction time. The dma_buf_id must be unique for all systems
|
||||
* (in the same DMA buffer type) e.g. using snd_dma_pci_buf_id().
|
||||
*
|
||||
* Return: Zero if successful, or a negative error code on failure.
|
||||
*/
|
||||
int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream,
|
||||
|
@ -514,3 +514,42 @@ unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit)
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate);
|
||||
|
||||
static unsigned int snd_pcm_rate_mask_sanitize(unsigned int rates)
|
||||
{
|
||||
if (rates & SNDRV_PCM_RATE_CONTINUOUS)
|
||||
return SNDRV_PCM_RATE_CONTINUOUS;
|
||||
else if (rates & SNDRV_PCM_RATE_KNOT)
|
||||
return SNDRV_PCM_RATE_KNOT;
|
||||
return rates;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_pcm_rate_mask_intersect - computes the intersection between two rate masks
|
||||
* @rates_a: The first rate mask
|
||||
* @rates_b: The second rate mask
|
||||
*
|
||||
* This function computes the rates that are supported by both rate masks passed
|
||||
* to the function. It will take care of the special handling of
|
||||
* SNDRV_PCM_RATE_CONTINUOUS and SNDRV_PCM_RATE_KNOT.
|
||||
*
|
||||
* Return: A rate mask containing the rates that are supported by both rates_a
|
||||
* and rates_b.
|
||||
*/
|
||||
unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a,
|
||||
unsigned int rates_b)
|
||||
{
|
||||
rates_a = snd_pcm_rate_mask_sanitize(rates_a);
|
||||
rates_b = snd_pcm_rate_mask_sanitize(rates_b);
|
||||
|
||||
if (rates_a & SNDRV_PCM_RATE_CONTINUOUS)
|
||||
return rates_b;
|
||||
else if (rates_b & SNDRV_PCM_RATE_CONTINUOUS)
|
||||
return rates_a;
|
||||
else if (rates_a & SNDRV_PCM_RATE_KNOT)
|
||||
return rates_b;
|
||||
else if (rates_b & SNDRV_PCM_RATE_KNOT)
|
||||
return rates_a;
|
||||
return rates_a & rates_b;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_rate_mask_intersect);
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/gfp.h>
|
||||
#include "sound_config.h"
|
||||
#include "sleep.h"
|
||||
|
||||
#define DMAP_FREE_ON_CLOSE 0
|
||||
#define DMAP_KEEP_ON_CLOSE 1
|
||||
@ -351,8 +352,7 @@ static void dma_reset_output(int dev)
|
||||
if (!signal_pending(current) && adev->dmap_out->qlen &&
|
||||
adev->dmap_out->underrun_count == 0){
|
||||
spin_unlock_irqrestore(&dmap->lock,flags);
|
||||
interruptible_sleep_on_timeout(&adev->out_sleeper,
|
||||
dmabuf_timeout(dmap));
|
||||
oss_broken_sleep_on(&adev->out_sleeper, dmabuf_timeout(dmap));
|
||||
spin_lock_irqsave(&dmap->lock,flags);
|
||||
}
|
||||
adev->dmap_out->flags &= ~(DMA_SYNCING | DMA_ACTIVE);
|
||||
@ -446,7 +446,7 @@ int DMAbuf_sync(int dev)
|
||||
long t = dmabuf_timeout(dmap);
|
||||
spin_unlock_irqrestore(&dmap->lock,flags);
|
||||
/* FIXME: not safe may miss events */
|
||||
t = interruptible_sleep_on_timeout(&adev->out_sleeper, t);
|
||||
t = oss_broken_sleep_on(&adev->out_sleeper, t);
|
||||
spin_lock_irqsave(&dmap->lock,flags);
|
||||
if (!t) {
|
||||
adev->dmap_out->flags &= ~DMA_SYNCING;
|
||||
@ -466,7 +466,7 @@ int DMAbuf_sync(int dev)
|
||||
while (!signal_pending(current) &&
|
||||
adev->d->local_qlen(dev)){
|
||||
spin_unlock_irqrestore(&dmap->lock,flags);
|
||||
interruptible_sleep_on_timeout(&adev->out_sleeper,
|
||||
oss_broken_sleep_on(&adev->out_sleeper,
|
||||
dmabuf_timeout(dmap));
|
||||
spin_lock_irqsave(&dmap->lock,flags);
|
||||
}
|
||||
@ -587,8 +587,7 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
|
||||
timeout = dmabuf_timeout(dmap);
|
||||
|
||||
spin_unlock_irqrestore(&dmap->lock,flags);
|
||||
timeout = interruptible_sleep_on_timeout(&adev->in_sleeper,
|
||||
timeout);
|
||||
timeout = oss_broken_sleep_on(&adev->in_sleeper, timeout);
|
||||
if (!timeout) {
|
||||
/* FIXME: include device name */
|
||||
err = -EIO;
|
||||
@ -768,8 +767,7 @@ static int output_sleep(int dev, int dontblock)
|
||||
timeout_value = dmabuf_timeout(dmap);
|
||||
else
|
||||
timeout_value = MAX_SCHEDULE_TIMEOUT;
|
||||
timeout_value = interruptible_sleep_on_timeout(&adev->out_sleeper,
|
||||
timeout_value);
|
||||
timeout_value = oss_broken_sleep_on(&adev->out_sleeper, timeout_value);
|
||||
if (timeout != MAX_SCHEDULE_TIMEOUT && !timeout_value) {
|
||||
printk(KERN_WARNING "Sound: DMA (output) timed out - IRQ/DRQ config error?\n");
|
||||
dma_reset_output(dev);
|
||||
|
@ -239,7 +239,6 @@ struct sound_queue {
|
||||
int busy, syncing, xruns, died;
|
||||
};
|
||||
|
||||
#define SLEEP(queue) interruptible_sleep_on_timeout(&queue, HZ)
|
||||
#define WAKE_UP(queue) (wake_up_interruptible(&queue))
|
||||
|
||||
extern struct sound_queue dmasound_write_sq;
|
||||
|
@ -619,15 +619,27 @@ static ssize_t sq_write(struct file *file, const char __user *src, size_t uLeft,
|
||||
}
|
||||
|
||||
while (uLeft) {
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
while (write_sq.count >= write_sq.max_active) {
|
||||
prepare_to_wait(&write_sq.action_queue, &wait, TASK_INTERRUPTIBLE);
|
||||
sq_play();
|
||||
if (write_sq.non_blocking)
|
||||
if (write_sq.non_blocking) {
|
||||
finish_wait(&write_sq.action_queue, &wait);
|
||||
return uWritten > 0 ? uWritten : -EAGAIN;
|
||||
SLEEP(write_sq.action_queue);
|
||||
if (signal_pending(current))
|
||||
}
|
||||
if (write_sq.count < write_sq.max_active)
|
||||
break;
|
||||
|
||||
schedule_timeout(HZ);
|
||||
if (signal_pending(current)) {
|
||||
finish_wait(&write_sq.action_queue, &wait);
|
||||
return uWritten > 0 ? uWritten : -EINTR;
|
||||
}
|
||||
}
|
||||
|
||||
finish_wait(&write_sq.action_queue, &wait);
|
||||
|
||||
/* Here, we can avoid disabling the interrupt by first
|
||||
* copying and translating the data, and then updating
|
||||
* the write_sq variables. Until this is done, the interrupt
|
||||
@ -707,11 +719,8 @@ static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode,
|
||||
if (file->f_flags & O_NONBLOCK)
|
||||
return rc;
|
||||
rc = -EINTR;
|
||||
while (sq->busy) {
|
||||
SLEEP(sq->open_queue);
|
||||
if (signal_pending(current))
|
||||
return rc;
|
||||
}
|
||||
if (wait_event_interruptible(sq->open_queue, !sq->busy))
|
||||
return rc;
|
||||
rc = 0;
|
||||
#else
|
||||
/* OSS manual says we will return EBUSY regardless
|
||||
@ -844,7 +853,8 @@ static int sq_fsync(void)
|
||||
sq_play(); /* there may be an incomplete frame waiting */
|
||||
|
||||
while (write_sq.active) {
|
||||
SLEEP(write_sq.sync_queue);
|
||||
wait_event_interruptible_timeout(write_sq.sync_queue,
|
||||
!write_sq.active, HZ);
|
||||
if (signal_pending(current)) {
|
||||
/* While waiting for audio output to drain, an
|
||||
* interrupt occurred. Stop audio output immediately
|
||||
|
@ -86,9 +86,8 @@ static void drain_midi_queue(int dev)
|
||||
*/
|
||||
|
||||
if (midi_devs[dev]->buffer_status != NULL)
|
||||
while (!signal_pending(current) && midi_devs[dev]->buffer_status(dev))
|
||||
interruptible_sleep_on_timeout(&midi_sleeper[dev],
|
||||
HZ/10);
|
||||
wait_event_interruptible_timeout(midi_sleeper[dev],
|
||||
!midi_devs[dev]->buffer_status(dev), HZ/10);
|
||||
}
|
||||
|
||||
static void midi_input_intr(int dev, unsigned char data)
|
||||
@ -233,8 +232,8 @@ void MIDIbuf_release(int dev, struct file *file)
|
||||
* devices
|
||||
*/
|
||||
|
||||
while (!signal_pending(current) && DATA_AVAIL(midi_out_buf[dev]))
|
||||
interruptible_sleep_on(&midi_sleeper[dev]);
|
||||
wait_event_interruptible(midi_sleeper[dev],
|
||||
!DATA_AVAIL(midi_out_buf[dev]));
|
||||
/*
|
||||
* Sync
|
||||
*/
|
||||
@ -282,8 +281,8 @@ int MIDIbuf_write(int dev, struct file *file, const char __user *buf, int count)
|
||||
goto out;
|
||||
}
|
||||
|
||||
interruptible_sleep_on(&midi_sleeper[dev]);
|
||||
if (signal_pending(current))
|
||||
if (wait_event_interruptible(midi_sleeper[dev],
|
||||
SPACE_AVAIL(midi_out_buf[dev])))
|
||||
{
|
||||
c = -EINTR;
|
||||
goto out;
|
||||
@ -325,8 +324,9 @@ int MIDIbuf_read(int dev, struct file *file, char __user *buf, int count)
|
||||
c = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
interruptible_sleep_on_timeout(&input_sleeper[dev],
|
||||
parms[dev].prech_timeout);
|
||||
wait_event_interruptible_timeout(input_sleeper[dev],
|
||||
DATA_AVAIL(midi_in_buf[dev]),
|
||||
parms[dev].prech_timeout);
|
||||
|
||||
if (signal_pending(current))
|
||||
c = -EINTR; /* The user is getting restless */
|
||||
|
@ -664,12 +664,15 @@ static long dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
|
||||
static void dsp_write_flush(void)
|
||||
{
|
||||
int timeout = get_play_delay_jiffies(dev.DAPF.len);
|
||||
|
||||
if (!(dev.mode & FMODE_WRITE) || !test_bit(F_WRITING, &dev.flags))
|
||||
return;
|
||||
set_bit(F_WRITEFLUSH, &dev.flags);
|
||||
interruptible_sleep_on_timeout(
|
||||
&dev.writeflush,
|
||||
get_play_delay_jiffies(dev.DAPF.len));
|
||||
wait_event_interruptible_timeout(
|
||||
dev.writeflush,
|
||||
!test_bit(F_WRITEFLUSH, &dev.flags),
|
||||
timeout);
|
||||
clear_bit(F_WRITEFLUSH, &dev.flags);
|
||||
if (!signal_pending(current)) {
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
@ -897,6 +900,7 @@ static int dsp_read(char __user *buf, size_t len)
|
||||
{
|
||||
int count = len;
|
||||
char *page = (char *)__get_free_page(GFP_KERNEL);
|
||||
int timeout = get_rec_delay_jiffies(DAR_BUFF_SIZE);
|
||||
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
@ -936,11 +940,11 @@ static int dsp_read(char __user *buf, size_t len)
|
||||
|
||||
if (count > 0) {
|
||||
set_bit(F_READBLOCK, &dev.flags);
|
||||
if (!interruptible_sleep_on_timeout(
|
||||
&dev.readblock,
|
||||
get_rec_delay_jiffies(DAR_BUFF_SIZE)))
|
||||
if (wait_event_interruptible_timeout(
|
||||
dev.readblock,
|
||||
test_bit(F_READBLOCK, &dev.flags),
|
||||
timeout) <= 0)
|
||||
clear_bit(F_READING, &dev.flags);
|
||||
clear_bit(F_READBLOCK, &dev.flags);
|
||||
if (signal_pending(current)) {
|
||||
free_page((unsigned long)page);
|
||||
return -EINTR;
|
||||
@ -955,6 +959,7 @@ static int dsp_write(const char __user *buf, size_t len)
|
||||
{
|
||||
int count = len;
|
||||
char *page = (char *)__get_free_page(GFP_KERNEL);
|
||||
int timeout = get_play_delay_jiffies(DAP_BUFF_SIZE);
|
||||
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
@ -995,10 +1000,10 @@ static int dsp_write(const char __user *buf, size_t len)
|
||||
|
||||
if (count > 0) {
|
||||
set_bit(F_WRITEBLOCK, &dev.flags);
|
||||
interruptible_sleep_on_timeout(
|
||||
&dev.writeblock,
|
||||
get_play_delay_jiffies(DAP_BUFF_SIZE));
|
||||
clear_bit(F_WRITEBLOCK, &dev.flags);
|
||||
wait_event_interruptible_timeout(
|
||||
dev.writeblock,
|
||||
test_bit(F_WRITEBLOCK, &dev.flags),
|
||||
timeout);
|
||||
if (signal_pending(current)) {
|
||||
free_page((unsigned long)page);
|
||||
return -EINTR;
|
||||
@ -1044,7 +1049,7 @@ static __inline__ void eval_dsp_msg(register WORD wMessage)
|
||||
clear_bit(F_WRITING, &dev.flags);
|
||||
}
|
||||
|
||||
if (test_bit(F_WRITEBLOCK, &dev.flags))
|
||||
if (test_and_clear_bit(F_WRITEBLOCK, &dev.flags))
|
||||
wake_up_interruptible(&dev.writeblock);
|
||||
break;
|
||||
|
||||
@ -1055,7 +1060,7 @@ static __inline__ void eval_dsp_msg(register WORD wMessage)
|
||||
|
||||
pack_DARQ_to_DARF(dev.last_recbank);
|
||||
|
||||
if (test_bit(F_READBLOCK, &dev.flags))
|
||||
if (test_and_clear_bit(F_READBLOCK, &dev.flags))
|
||||
wake_up_interruptible(&dev.readblock);
|
||||
break;
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "sound_config.h"
|
||||
|
||||
#include "midi_ctrl.h"
|
||||
#include "sleep.h"
|
||||
|
||||
static int sequencer_ok;
|
||||
static struct sound_timer_operations *tmr;
|
||||
@ -100,8 +101,7 @@ int sequencer_read(int dev, struct file *file, char __user *buf, int count)
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
interruptible_sleep_on_timeout(&midi_sleeper,
|
||||
pre_event_timeout);
|
||||
oss_broken_sleep_on(&midi_sleeper, pre_event_timeout);
|
||||
spin_lock_irqsave(&lock,flags);
|
||||
if (!iqlen)
|
||||
{
|
||||
@ -343,7 +343,7 @@ static int seq_queue(unsigned char *note, char nonblock)
|
||||
/*
|
||||
* Sleep until there is enough space on the queue
|
||||
*/
|
||||
interruptible_sleep_on(&seq_sleeper);
|
||||
oss_broken_sleep_on(&seq_sleeper, MAX_SCHEDULE_TIMEOUT);
|
||||
}
|
||||
if (qlen >= SEQ_MAX_QUEUE)
|
||||
{
|
||||
@ -1122,8 +1122,7 @@ static void seq_drain_midi_queues(void)
|
||||
*/
|
||||
|
||||
if (n)
|
||||
interruptible_sleep_on_timeout(&seq_sleeper,
|
||||
HZ/10);
|
||||
oss_broken_sleep_on(&seq_sleeper, HZ/10);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1145,8 +1144,7 @@ void sequencer_release(int dev, struct file *file)
|
||||
while (!signal_pending(current) && qlen > 0)
|
||||
{
|
||||
seq_sync();
|
||||
interruptible_sleep_on_timeout(&seq_sleeper,
|
||||
3*HZ);
|
||||
oss_broken_sleep_on(&seq_sleeper, 3*HZ);
|
||||
/* Extra delay */
|
||||
}
|
||||
}
|
||||
@ -1201,7 +1199,7 @@ static int seq_sync(void)
|
||||
seq_startplay();
|
||||
|
||||
if (qlen > 0)
|
||||
interruptible_sleep_on_timeout(&seq_sleeper, HZ);
|
||||
oss_broken_sleep_on(&seq_sleeper, HZ);
|
||||
return qlen;
|
||||
}
|
||||
|
||||
@ -1224,7 +1222,7 @@ static void midi_outc(int dev, unsigned char data)
|
||||
|
||||
spin_lock_irqsave(&lock,flags);
|
||||
while (n && !midi_devs[dev]->outputc(dev, data)) {
|
||||
interruptible_sleep_on_timeout(&seq_sleeper, HZ/25);
|
||||
oss_broken_sleep_on(&seq_sleeper, HZ/25);
|
||||
n--;
|
||||
}
|
||||
spin_unlock_irqrestore(&lock,flags);
|
||||
|
18
sound/oss/sleep.h
Normal file
18
sound/oss/sleep.h
Normal file
@ -0,0 +1,18 @@
|
||||
#include <linux/wait.h>
|
||||
|
||||
/*
|
||||
* Do not use. This is a replacement for the old
|
||||
* "interruptible_sleep_on_timeout" function that has been
|
||||
* deprecated for ages. All users should instead try to use
|
||||
* wait_event_interruptible_timeout.
|
||||
*/
|
||||
|
||||
static inline long
|
||||
oss_broken_sleep_on(wait_queue_head_t *q, long timeout)
|
||||
{
|
||||
DEFINE_WAIT(wait);
|
||||
prepare_to_wait(q, &wait, TASK_INTERRUPTIBLE);
|
||||
timeout = schedule_timeout(timeout);
|
||||
finish_wait(q, &wait);
|
||||
return timeout;
|
||||
}
|
@ -90,6 +90,8 @@
|
||||
#include <asm/sibyte/sb1250_mac.h>
|
||||
#include <asm/sibyte/sb1250.h>
|
||||
|
||||
#include "sleep.h"
|
||||
|
||||
struct cs4297a_state;
|
||||
|
||||
static DEFINE_MUTEX(swarm_cs4297a_mutex);
|
||||
@ -748,7 +750,7 @@ static int serdma_reg_access(struct cs4297a_state *s, u64 data)
|
||||
/* Since a writer has the DSP open, we have to mux the
|
||||
request in */
|
||||
s->reg_request = data;
|
||||
interruptible_sleep_on(&s->dma_dac.reg_wait);
|
||||
oss_broken_sleep_on(&s->dma_dac.reg_wait, MAX_SCHEDULE_TIMEOUT);
|
||||
/* XXXKW how can I deal with the starvation case where
|
||||
the opener isn't writing? */
|
||||
} else {
|
||||
@ -790,7 +792,7 @@ static int cs4297a_read_ac97(struct cs4297a_state *s, u32 offset,
|
||||
if (serdma_reg_access(s, (0xCLL << 60) | (1LL << 47) | ((u64)(offset & 0x7F) << 40)))
|
||||
return -1;
|
||||
|
||||
interruptible_sleep_on(&s->dma_adc.reg_wait);
|
||||
oss_broken_sleep_on(&s->dma_adc.reg_wait, MAX_SCHEDULE_TIMEOUT);
|
||||
*value = s->read_value;
|
||||
CS_DBGOUT(CS_AC97, 2,
|
||||
printk(KERN_INFO "cs4297a: rdr reg %x -> %x\n", s->read_reg, s->read_value));
|
||||
@ -1740,7 +1742,7 @@ static ssize_t cs4297a_read(struct file *file, char *buffer, size_t count,
|
||||
start_adc(s);
|
||||
if (file->f_flags & O_NONBLOCK)
|
||||
return ret ? ret : -EAGAIN;
|
||||
interruptible_sleep_on(&s->dma_adc.wait);
|
||||
oss_broken_sleep_on(&s->dma_adc.wait, MAX_SCHEDULE_TIMEOUT);
|
||||
if (signal_pending(current))
|
||||
return ret ? ret : -ERESTARTSYS;
|
||||
continue;
|
||||
@ -1836,7 +1838,7 @@ static ssize_t cs4297a_write(struct file *file, const char *buffer,
|
||||
start_dac(s);
|
||||
if (file->f_flags & O_NONBLOCK)
|
||||
return ret ? ret : -EAGAIN;
|
||||
interruptible_sleep_on(&d->wait);
|
||||
oss_broken_sleep_on(&d->wait, MAX_SCHEDULE_TIMEOUT);
|
||||
if (signal_pending(current))
|
||||
return ret ? ret : -ERESTARTSYS;
|
||||
continue;
|
||||
@ -2452,7 +2454,7 @@ static int cs4297a_locked_open(struct inode *inode, struct file *file)
|
||||
return -EBUSY;
|
||||
}
|
||||
mutex_unlock(&s->open_sem_dac);
|
||||
interruptible_sleep_on(&s->open_wait_dac);
|
||||
oss_broken_sleep_on(&s->open_wait_dac, MAX_SCHEDULE_TIMEOUT);
|
||||
|
||||
if (signal_pending(current)) {
|
||||
printk("open - sig pending\n");
|
||||
@ -2469,7 +2471,7 @@ static int cs4297a_locked_open(struct inode *inode, struct file *file)
|
||||
return -EBUSY;
|
||||
}
|
||||
mutex_unlock(&s->open_sem_adc);
|
||||
interruptible_sleep_on(&s->open_wait_adc);
|
||||
oss_broken_sleep_on(&s->open_wait_adc, MAX_SCHEDULE_TIMEOUT);
|
||||
|
||||
if (signal_pending(current)) {
|
||||
printk("open - sig pending\n");
|
||||
|
@ -2921,6 +2921,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
|
||||
vwsnd_dev_t *devc;
|
||||
int minor = iminor(inode);
|
||||
int sw_samplefmt;
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
|
||||
|
||||
@ -2937,21 +2938,26 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
|
||||
}
|
||||
|
||||
mutex_lock(&devc->open_mutex);
|
||||
while (devc->open_mode & file->f_mode) {
|
||||
while (1) {
|
||||
prepare_to_wait(&devc->open_wait, &wait, TASK_INTERRUPTIBLE);
|
||||
if (!(devc->open_mode & file->f_mode))
|
||||
break;
|
||||
|
||||
mutex_unlock(&devc->open_mutex);
|
||||
mutex_unlock(&vwsnd_mutex);
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
DEC_USE_COUNT;
|
||||
mutex_unlock(&vwsnd_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
interruptible_sleep_on(&devc->open_wait);
|
||||
schedule();
|
||||
if (signal_pending(current)) {
|
||||
DEC_USE_COUNT;
|
||||
mutex_unlock(&vwsnd_mutex);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
mutex_lock(&vwsnd_mutex);
|
||||
mutex_lock(&devc->open_mutex);
|
||||
}
|
||||
finish_wait(&devc->open_wait, &wait);
|
||||
devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
|
||||
mutex_unlock(&devc->open_mutex);
|
||||
|
||||
|
@ -25,6 +25,7 @@ config SND_ALS300
|
||||
select SND_PCM
|
||||
select SND_AC97_CODEC
|
||||
select SND_OPL3_LIB
|
||||
select ZONE_DMA
|
||||
help
|
||||
Say 'Y' or 'M' to include support for Avance Logic ALS300/ALS300+
|
||||
|
||||
@ -49,6 +50,7 @@ config SND_ALI5451
|
||||
tristate "ALi M5451 PCI Audio Controller"
|
||||
select SND_MPU401_UART
|
||||
select SND_AC97_CODEC
|
||||
select ZONE_DMA
|
||||
help
|
||||
Say Y here to include support for the integrated AC97 sound
|
||||
device on motherboards using the ALi M5451 Audio Controller
|
||||
@ -153,6 +155,7 @@ config SND_AZT3328
|
||||
select SND_PCM
|
||||
select SND_RAWMIDI
|
||||
select SND_AC97_CODEC
|
||||
select ZONE_DMA
|
||||
help
|
||||
Say Y here to include support for Aztech AZF3328 (PCI168)
|
||||
soundcards.
|
||||
@ -254,6 +257,7 @@ config SND_CS46XX
|
||||
tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x"
|
||||
select SND_RAWMIDI
|
||||
select SND_AC97_CODEC
|
||||
select FW_LOADER
|
||||
help
|
||||
Say Y here to include support for Cirrus Logic CS4610/CS4612/
|
||||
CS4614/CS4615/CS4622/CS4624/CS4630/CS4280 chips.
|
||||
@ -458,6 +462,7 @@ config SND_EMU10K1
|
||||
select SND_HWDEP
|
||||
select SND_RAWMIDI
|
||||
select SND_AC97_CODEC
|
||||
select ZONE_DMA
|
||||
help
|
||||
Say Y to include support for Sound Blaster PCI 512, Live!,
|
||||
Audigy and E-mu APS (partially supported) soundcards.
|
||||
@ -473,6 +478,7 @@ config SND_EMU10K1X
|
||||
tristate "Emu10k1X (Dell OEM Version)"
|
||||
select SND_AC97_CODEC
|
||||
select SND_RAWMIDI
|
||||
select ZONE_DMA
|
||||
help
|
||||
Say Y here to include support for the Dell OEM version of the
|
||||
Sound Blaster Live!.
|
||||
@ -506,6 +512,7 @@ config SND_ES1938
|
||||
select SND_OPL3_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_AC97_CODEC
|
||||
select ZONE_DMA
|
||||
help
|
||||
Say Y here to include support for soundcards based on ESS Solo-1
|
||||
(ES1938, ES1946, ES1969) chips.
|
||||
@ -517,6 +524,7 @@ config SND_ES1968
|
||||
tristate "ESS ES1968/1978 (Maestro-1/2/2E)"
|
||||
select SND_MPU401_UART
|
||||
select SND_AC97_CODEC
|
||||
select ZONE_DMA
|
||||
help
|
||||
Say Y here to include support for soundcards based on ESS Maestro
|
||||
1/2/2E chips.
|
||||
@ -605,6 +613,7 @@ config SND_ICE1712
|
||||
select SND_MPU401_UART
|
||||
select SND_AC97_CODEC
|
||||
select BITREVERSE
|
||||
select ZONE_DMA
|
||||
help
|
||||
Say Y here to include support for soundcards based on the
|
||||
ICE1712 (Envy24) chip.
|
||||
@ -692,6 +701,7 @@ config SND_LX6464ES
|
||||
config SND_MAESTRO3
|
||||
tristate "ESS Allegro/Maestro3"
|
||||
select SND_AC97_CODEC
|
||||
select ZONE_DMA
|
||||
help
|
||||
Say Y here to include support for soundcards based on ESS Maestro 3
|
||||
(Allegro) chips.
|
||||
@ -788,6 +798,7 @@ config SND_SIS7019
|
||||
tristate "SiS 7019 Audio Accelerator"
|
||||
depends on X86 && !X86_64
|
||||
select SND_AC97_CODEC
|
||||
select ZONE_DMA
|
||||
help
|
||||
Say Y here to include support for the SiS 7019 Audio Accelerator.
|
||||
|
||||
@ -799,6 +810,7 @@ config SND_SONICVIBES
|
||||
select SND_OPL3_LIB
|
||||
select SND_MPU401_UART
|
||||
select SND_AC97_CODEC
|
||||
select ZONE_DMA
|
||||
help
|
||||
Say Y here to include support for soundcards based on the S3
|
||||
SonicVibes chip.
|
||||
@ -810,6 +822,7 @@ config SND_TRIDENT
|
||||
tristate "Trident 4D-Wave DX/NX; SiS 7018"
|
||||
select SND_MPU401_UART
|
||||
select SND_AC97_CODEC
|
||||
select ZONE_DMA
|
||||
help
|
||||
Say Y here to include support for soundcards based on Trident
|
||||
4D-Wave DX/NX or SiS 7018 chips.
|
||||
|
@ -1716,9 +1716,14 @@ struct snd_cs46xx {
|
||||
struct snd_pcm *pcm_rear;
|
||||
struct snd_pcm *pcm_center_lfe;
|
||||
struct snd_pcm *pcm_iec958;
|
||||
|
||||
#define CS46XX_DSP_MODULES 5
|
||||
struct dsp_module_desc *modules[CS46XX_DSP_MODULES];
|
||||
#else /* for compatibility */
|
||||
struct snd_cs46xx_pcm *playback_pcm;
|
||||
unsigned int play_ctl;
|
||||
|
||||
struct ba1_struct *ba1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -54,7 +54,9 @@
|
||||
#include <linux/gameport.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/export.h>
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/control.h>
|
||||
@ -330,13 +332,146 @@ int snd_cs46xx_download(struct snd_cs46xx *chip,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void memcpy_le32(void *dst, const void *src, unsigned int len)
|
||||
{
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
memcpy(dst, src, len);
|
||||
#else
|
||||
u32 *_dst = dst;
|
||||
const __le32 *_src = src;
|
||||
len /= 4;
|
||||
while (len-- > 0)
|
||||
*_dst++ = le32_to_cpu(*_src++);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
|
||||
#include "imgs/cwc4630.h"
|
||||
#include "imgs/cwcasync.h"
|
||||
#include "imgs/cwcsnoop.h"
|
||||
#include "imgs/cwcbinhack.h"
|
||||
#include "imgs/cwcdma.h"
|
||||
static const char *module_names[CS46XX_DSP_MODULES] = {
|
||||
"cwc4630", "cwcasync", "cwcsnoop", "cwcbinhack", "cwcdma"
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE("cs46xx/cwc4630");
|
||||
MODULE_FIRMWARE("cs46xx/cwcasync");
|
||||
MODULE_FIRMWARE("cs46xx/cwcsnoop");
|
||||
MODULE_FIRMWARE("cs46xx/cwcbinhack");
|
||||
MODULE_FIRMWARE("cs46xx/cwcdma");
|
||||
|
||||
static void free_module_desc(struct dsp_module_desc *module)
|
||||
{
|
||||
if (!module)
|
||||
return;
|
||||
kfree(module->module_name);
|
||||
kfree(module->symbol_table.symbols);
|
||||
if (module->segments) {
|
||||
int i;
|
||||
for (i = 0; i < module->nsegments; i++)
|
||||
kfree(module->segments[i].data);
|
||||
kfree(module->segments);
|
||||
}
|
||||
}
|
||||
|
||||
/* firmware binary format:
|
||||
* le32 nsymbols;
|
||||
* struct {
|
||||
* le32 address;
|
||||
* char symbol_name[DSP_MAX_SYMBOL_NAME];
|
||||
* le32 symbol_type;
|
||||
* } symbols[nsymbols];
|
||||
* le32 nsegments;
|
||||
* struct {
|
||||
* le32 segment_type;
|
||||
* le32 offset;
|
||||
* le32 size;
|
||||
* le32 data[size];
|
||||
* } segments[nsegments];
|
||||
*/
|
||||
|
||||
static int load_firmware(struct snd_cs46xx *chip,
|
||||
struct dsp_module_desc **module_ret,
|
||||
const char *fw_name)
|
||||
{
|
||||
int i, err;
|
||||
unsigned int nums, fwlen, fwsize;
|
||||
const __le32 *fwdat;
|
||||
struct dsp_module_desc *module = NULL;
|
||||
const struct firmware *fw;
|
||||
char fw_path[32];
|
||||
|
||||
sprintf(fw_path, "cs46xx/%s", fw_name);
|
||||
err = request_firmware(&fw, fw_path, &chip->pci->dev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
fwsize = fw->size / 4;
|
||||
if (fwsize < 2) {
|
||||
err = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = -ENOMEM;
|
||||
module = kzalloc(sizeof(*module), GFP_KERNEL);
|
||||
if (!module)
|
||||
goto error;
|
||||
module->module_name = kstrdup(fw_name, GFP_KERNEL);
|
||||
if (!module->module_name)
|
||||
goto error;
|
||||
|
||||
fwlen = 0;
|
||||
fwdat = (const __le32 *)fw->data;
|
||||
nums = module->symbol_table.nsymbols = le32_to_cpu(fwdat[fwlen++]);
|
||||
if (nums >= 40)
|
||||
goto error_inval;
|
||||
module->symbol_table.symbols =
|
||||
kcalloc(nums, sizeof(struct dsp_symbol_entry), GFP_KERNEL);
|
||||
if (!module->symbol_table.symbols)
|
||||
goto error;
|
||||
for (i = 0; i < nums; i++) {
|
||||
struct dsp_symbol_entry *entry =
|
||||
&module->symbol_table.symbols[i];
|
||||
if (fwlen + 2 + DSP_MAX_SYMBOL_NAME / 4 > fwsize)
|
||||
goto error_inval;
|
||||
entry->address = le32_to_cpu(fwdat[fwlen++]);
|
||||
memcpy(entry->symbol_name, &fwdat[fwlen], DSP_MAX_SYMBOL_NAME - 1);
|
||||
fwlen += DSP_MAX_SYMBOL_NAME / 4;
|
||||
entry->symbol_type = le32_to_cpu(fwdat[fwlen++]);
|
||||
}
|
||||
|
||||
if (fwlen >= fwsize)
|
||||
goto error_inval;
|
||||
nums = module->nsegments = le32_to_cpu(fwdat[fwlen++]);
|
||||
if (nums > 10)
|
||||
goto error_inval;
|
||||
module->segments =
|
||||
kcalloc(nums, sizeof(struct dsp_segment_desc), GFP_KERNEL);
|
||||
if (!module->segments)
|
||||
goto error;
|
||||
for (i = 0; i < nums; i++) {
|
||||
struct dsp_segment_desc *entry = &module->segments[i];
|
||||
if (fwlen + 3 > fwsize)
|
||||
goto error_inval;
|
||||
entry->segment_type = le32_to_cpu(fwdat[fwlen++]);
|
||||
entry->offset = le32_to_cpu(fwdat[fwlen++]);
|
||||
entry->size = le32_to_cpu(fwdat[fwlen++]);
|
||||
if (fwlen + entry->size > fwsize)
|
||||
goto error_inval;
|
||||
entry->data = kmalloc(entry->size * 4, GFP_KERNEL);
|
||||
if (!entry->data)
|
||||
goto error;
|
||||
memcpy_le32(entry->data, &fwdat[fwlen], entry->size * 4);
|
||||
fwlen += entry->size;
|
||||
}
|
||||
|
||||
*module_ret = module;
|
||||
release_firmware(fw);
|
||||
return 0;
|
||||
|
||||
error_inval:
|
||||
err = -EINVAL;
|
||||
error:
|
||||
free_module_desc(module);
|
||||
release_firmware(fw);
|
||||
return err;
|
||||
}
|
||||
|
||||
int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip,
|
||||
unsigned long offset,
|
||||
@ -361,20 +496,63 @@ int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip,
|
||||
|
||||
#else /* old DSP image */
|
||||
|
||||
#include "cs46xx_image.h"
|
||||
struct ba1_struct {
|
||||
struct {
|
||||
u32 offset;
|
||||
u32 size;
|
||||
} memory[BA1_MEMORY_COUNT];
|
||||
u32 map[BA1_DWORD_SIZE];
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE("cs46xx/ba1");
|
||||
|
||||
static int load_firmware(struct snd_cs46xx *chip)
|
||||
{
|
||||
const struct firmware *fw;
|
||||
int i, size, err;
|
||||
|
||||
err = request_firmware(&fw, "cs46xx/ba1", &chip->pci->dev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (fw->size != sizeof(*chip->ba1)) {
|
||||
err = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
chip->ba1 = vmalloc(sizeof(*chip->ba1));
|
||||
if (!chip->ba1) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy_le32(chip->ba1, fw->data, sizeof(*chip->ba1));
|
||||
|
||||
/* sanity check */
|
||||
size = 0;
|
||||
for (i = 0; i < BA1_MEMORY_COUNT; i++)
|
||||
size += chip->ba1->memory[i].size;
|
||||
if (size > BA1_DWORD_SIZE * 4)
|
||||
err = -EINVAL;
|
||||
|
||||
error:
|
||||
release_firmware(fw);
|
||||
return err;
|
||||
}
|
||||
|
||||
int snd_cs46xx_download_image(struct snd_cs46xx *chip)
|
||||
{
|
||||
int idx, err;
|
||||
unsigned long offset = 0;
|
||||
unsigned int offset = 0;
|
||||
struct ba1_struct *ba1 = chip->ba1;
|
||||
|
||||
for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) {
|
||||
if ((err = snd_cs46xx_download(chip,
|
||||
&BA1Struct.map[offset],
|
||||
BA1Struct.memory[idx].offset,
|
||||
BA1Struct.memory[idx].size)) < 0)
|
||||
err = snd_cs46xx_download(chip,
|
||||
&ba1->map[offset],
|
||||
ba1->memory[idx].offset,
|
||||
ba1->memory[idx].size);
|
||||
if (err < 0)
|
||||
return err;
|
||||
offset += BA1Struct.memory[idx].size >> 2;
|
||||
offset += ba1->memory[idx].size >> 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -2798,6 +2976,10 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip)
|
||||
cs46xx_dsp_spos_destroy(chip);
|
||||
chip->dsp_spos_instance = NULL;
|
||||
}
|
||||
for (idx = 0; idx < CS46XX_DSP_MODULES; idx++)
|
||||
free_module_desc(chip->modules[idx]);
|
||||
#else
|
||||
vfree(chip->ba1);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@ -3067,6 +3249,11 @@ static void cs46xx_enable_stream_irqs(struct snd_cs46xx *chip)
|
||||
int snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
|
||||
{
|
||||
unsigned int tmp;
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
int i;
|
||||
#endif
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Reset the processor.
|
||||
*/
|
||||
@ -3075,45 +3262,33 @@ int snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
|
||||
* Download the image to the processor.
|
||||
*/
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
#if 0
|
||||
if (cs46xx_dsp_load_module(chip, &cwcemb80_module) < 0) {
|
||||
snd_printk(KERN_ERR "image download error\n");
|
||||
return -EIO;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cs46xx_dsp_load_module(chip, &cwc4630_module) < 0) {
|
||||
snd_printk(KERN_ERR "image download error [cwc4630]\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (cs46xx_dsp_load_module(chip, &cwcasync_module) < 0) {
|
||||
snd_printk(KERN_ERR "image download error [cwcasync]\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (cs46xx_dsp_load_module(chip, &cwcsnoop_module) < 0) {
|
||||
snd_printk(KERN_ERR "image download error [cwcsnoop]\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (cs46xx_dsp_load_module(chip, &cwcbinhack_module) < 0) {
|
||||
snd_printk(KERN_ERR "image download error [cwcbinhack]\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (cs46xx_dsp_load_module(chip, &cwcdma_module) < 0) {
|
||||
snd_printk(KERN_ERR "image download error [cwcdma]\n");
|
||||
return -EIO;
|
||||
for (i = 0; i < CS46XX_DSP_MODULES; i++) {
|
||||
err = load_firmware(chip, &chip->modules[i], module_names[i]);
|
||||
if (err < 0) {
|
||||
snd_printk(KERN_ERR "firmware load error [%s]\n",
|
||||
module_names[i]);
|
||||
return err;
|
||||
}
|
||||
err = cs46xx_dsp_load_module(chip, chip->modules[i]);
|
||||
if (err < 0) {
|
||||
snd_printk(KERN_ERR "image download error [%s]\n",
|
||||
module_names[i]);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (cs46xx_dsp_scb_and_task_init(chip) < 0)
|
||||
return -EIO;
|
||||
#else
|
||||
err = load_firmware(chip);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* old image */
|
||||
if (snd_cs46xx_download_image(chip) < 0) {
|
||||
err = snd_cs46xx_download_image(chip);
|
||||
if (err < 0) {
|
||||
snd_printk(KERN_ERR "image download error\n");
|
||||
return -EIO;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,320 +0,0 @@
|
||||
/* generated from cwc4630.osp DO NOT MODIFY */
|
||||
|
||||
#ifndef __HEADER_cwc4630_H__
|
||||
#define __HEADER_cwc4630_H__
|
||||
|
||||
static struct dsp_symbol_entry cwc4630_symbols[] = {
|
||||
{ 0x0000, "BEGINADDRESS",0x00 },
|
||||
{ 0x8000, "EXECCHILD",0x03 },
|
||||
{ 0x8001, "EXECCHILD_98",0x03 },
|
||||
{ 0x8003, "EXECCHILD_PUSH1IND",0x03 },
|
||||
{ 0x8008, "EXECSIBLING",0x03 },
|
||||
{ 0x800a, "EXECSIBLING_298",0x03 },
|
||||
{ 0x800b, "EXECSIBLING_2IND1",0x03 },
|
||||
{ 0x8010, "TIMINGMASTER",0x03 },
|
||||
{ 0x804f, "S16_CODECINPUTTASK",0x03 },
|
||||
{ 0x805e, "PCMSERIALINPUTTASK",0x03 },
|
||||
{ 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
|
||||
{ 0x809a, "S16_MIX",0x03 },
|
||||
{ 0x80bb, "S16_UPSRC",0x03 },
|
||||
{ 0x813b, "MIX3_EXP",0x03 },
|
||||
{ 0x8164, "DECIMATEBYPOW2",0x03 },
|
||||
{ 0x8197, "VARIDECIMATE",0x03 },
|
||||
{ 0x81f2, "_3DINPUTTASK",0x03 },
|
||||
{ 0x820a, "_3DPRLGCINPTASK",0x03 },
|
||||
{ 0x8227, "_3DSTEREOINPUTTASK",0x03 },
|
||||
{ 0x8242, "_3DOUTPUTTASK",0x03 },
|
||||
{ 0x82c4, "HRTF_MORPH_TASK",0x03 },
|
||||
{ 0x82c6, "WAIT4DATA",0x03 },
|
||||
{ 0x82fa, "PROLOGIC",0x03 },
|
||||
{ 0x8496, "DECORRELATOR",0x03 },
|
||||
{ 0x84a4, "STEREO2MONO",0x03 },
|
||||
{ 0x0070, "SPOSCB",0x02 },
|
||||
{ 0x0107, "TASKTREETHREAD",0x03 },
|
||||
{ 0x013c, "TASKTREEHEADERCODE",0x03 },
|
||||
{ 0x0145, "FGTASKTREEHEADERCODE",0x03 },
|
||||
{ 0x0169, "NULLALGORITHM",0x03 },
|
||||
{ 0x016d, "HFGEXECCHILD",0x03 },
|
||||
{ 0x016e, "HFGEXECCHILD_98",0x03 },
|
||||
{ 0x0170, "HFGEXECCHILD_PUSH1IND",0x03 },
|
||||
{ 0x0173, "HFGEXECSIBLING",0x03 },
|
||||
{ 0x0175, "HFGEXECSIBLING_298",0x03 },
|
||||
{ 0x0176, "HFGEXECSIBLING_2IND1",0x03 },
|
||||
{ 0x0179, "S16_CODECOUTPUTTASK",0x03 },
|
||||
{ 0x0194, "#CODE_END",0x00 },
|
||||
}; /* cwc4630 symbols */
|
||||
|
||||
static u32 cwc4630_code[] = {
|
||||
/* BEGINADDRESS */
|
||||
/* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
|
||||
/* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003,
|
||||
/* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
|
||||
/* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003,
|
||||
/* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
|
||||
/* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003,
|
||||
/* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
|
||||
/* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003,
|
||||
/* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
|
||||
/* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003,
|
||||
/* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
|
||||
/* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003,
|
||||
/* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003,
|
||||
/* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003,
|
||||
/* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003,
|
||||
/* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003,
|
||||
/* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003,
|
||||
/* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040,
|
||||
/* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
|
||||
/* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003,
|
||||
/* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
|
||||
/* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003,
|
||||
/* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
|
||||
/* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003,
|
||||
/* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
|
||||
/* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003,
|
||||
/* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
|
||||
/* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003,
|
||||
/* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
|
||||
/* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003,
|
||||
/* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003,
|
||||
/* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003,
|
||||
/* 0040 */ 0x0001a730,0x00001008,0x000e2730,0x00001002,
|
||||
/* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
|
||||
/* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
|
||||
/* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002,
|
||||
/* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003,
|
||||
/* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
|
||||
/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000,
|
||||
/* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000,
|
||||
/* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000,
|
||||
/* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000,
|
||||
/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000,
|
||||
/* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003,
|
||||
/* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003,
|
||||
/* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
|
||||
/* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000,
|
||||
/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003,
|
||||
/* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000,
|
||||
/* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000,
|
||||
/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000,
|
||||
/* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000,
|
||||
/* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140,
|
||||
/* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
|
||||
/* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
|
||||
/* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40,
|
||||
/* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00,
|
||||
/* 007C */ 0x0000002e,0x0009d6c0,0x0002ef8a,0x00000000,
|
||||
/* 007E */ 0x00040630,0x00001004,0x0004ef0a,0x000eb785,
|
||||
/* 0080 */ 0x0003fc8a,0x00000000,0x00000000,0x000c70e0,
|
||||
/* 0082 */ 0x0007d182,0x0002c640,0x00008630,0x00001004,
|
||||
/* 0084 */ 0x000799b8,0x0002c6c0,0x00031705,0x00092240,
|
||||
/* 0086 */ 0x00039f05,0x000932c0,0x0003520a,0x00000000,
|
||||
/* 0088 */ 0x00070731,0x0000100b,0x00010705,0x000b20c0,
|
||||
/* 008A */ 0x00000000,0x000eba44,0x00032108,0x000c60c4,
|
||||
/* 008C */ 0x00065208,0x000c2917,0x000486b0,0x00001007,
|
||||
/* 008E */ 0x00012f05,0x00036880,0x0002818e,0x000c0000,
|
||||
/* 0090 */ 0x0004410a,0x00000000,0x00048630,0x00001007,
|
||||
/* 0092 */ 0x00029705,0x000c0000,0x00000000,0x00000000,
|
||||
/* 0094 */ 0x00003fc1,0x0003fc40,0x000037c1,0x00091b40,
|
||||
/* 0096 */ 0x00003fc1,0x000911c0,0x000037c1,0x000957c0,
|
||||
/* 0098 */ 0x00003fc1,0x000951c0,0x000037c1,0x00000000,
|
||||
/* 009A */ 0x00003fc1,0x000991c0,0x000037c1,0x00000000,
|
||||
/* 009C */ 0x00003fc1,0x0009d1c0,0x000037c1,0x00000000,
|
||||
/* 009E */ 0x0001ccc1,0x000915c0,0x0001c441,0x0009d800,
|
||||
/* 00A0 */ 0x0009cdc1,0x00091240,0x0001c541,0x00091d00,
|
||||
/* 00A2 */ 0x0009cfc1,0x00095240,0x0001c741,0x00095c80,
|
||||
/* 00A4 */ 0x000e8ca9,0x00099240,0x000e85ad,0x00095640,
|
||||
/* 00A6 */ 0x00069ca9,0x00099d80,0x000e952d,0x00099640,
|
||||
/* 00A8 */ 0x000eaca9,0x0009d6c0,0x000ea5ad,0x00091a40,
|
||||
/* 00AA */ 0x0006bca9,0x0009de80,0x000eb52d,0x00095a40,
|
||||
/* 00AC */ 0x000ecca9,0x00099ac0,0x000ec5ad,0x0009da40,
|
||||
/* 00AE */ 0x000edca9,0x0009d300,0x000a6e0a,0x00001000,
|
||||
/* 00B0 */ 0x000ed52d,0x00091e40,0x000eeca9,0x00095ec0,
|
||||
/* 00B2 */ 0x000ee5ad,0x00099e40,0x0006fca9,0x00002500,
|
||||
/* 00B4 */ 0x000fb208,0x000c59a0,0x000ef52d,0x0009de40,
|
||||
/* 00B6 */ 0x00068ca9,0x000912c1,0x000683ad,0x00095241,
|
||||
/* 00B8 */ 0x00020f05,0x000991c1,0x00000000,0x00000000,
|
||||
/* 00BA */ 0x00086f88,0x00001000,0x0009cf81,0x000b5340,
|
||||
/* 00BC */ 0x0009c701,0x000b92c0,0x0009de81,0x000bd300,
|
||||
/* 00BE */ 0x0009d601,0x000b1700,0x0001fd81,0x000b9d80,
|
||||
/* 00C0 */ 0x0009f501,0x000b57c0,0x000a0f81,0x000bd740,
|
||||
/* 00C2 */ 0x00020701,0x000b5c80,0x000a1681,0x000b97c0,
|
||||
/* 00C4 */ 0x00021601,0x00002500,0x000a0701,0x000b9b40,
|
||||
/* 00C6 */ 0x000a0f81,0x000b1bc0,0x00021681,0x00002d00,
|
||||
/* 00C8 */ 0x00020f81,0x000bd800,0x000a0701,0x000b5bc0,
|
||||
/* 00CA */ 0x00021601,0x00003500,0x000a0f81,0x000b5f40,
|
||||
/* 00CC */ 0x000a0701,0x000bdbc0,0x00021681,0x00003d00,
|
||||
/* 00CE */ 0x00020f81,0x000b1d00,0x000a0701,0x000b1fc0,
|
||||
/* 00D0 */ 0x00021601,0x00020500,0x00020f81,0x000b1341,
|
||||
/* 00D2 */ 0x000a0701,0x000b9fc0,0x00021681,0x00020d00,
|
||||
/* 00D4 */ 0x00020f81,0x000bde80,0x000a0701,0x000bdfc0,
|
||||
/* 00D6 */ 0x00021601,0x00021500,0x00020f81,0x000b9341,
|
||||
/* 00D8 */ 0x00020701,0x000b53c1,0x00021681,0x00021d00,
|
||||
/* 00DA */ 0x000a0f81,0x000d0380,0x0000b601,0x000b15c0,
|
||||
/* 00DC */ 0x00007b01,0x00000000,0x00007b81,0x000bd1c0,
|
||||
/* 00DE */ 0x00007b01,0x00000000,0x00007b81,0x000b91c0,
|
||||
/* 00E0 */ 0x00007b01,0x000b57c0,0x00007b81,0x000b51c0,
|
||||
/* 00E2 */ 0x00007b01,0x000b1b40,0x00007b81,0x000b11c0,
|
||||
/* 00E4 */ 0x00087b01,0x000c3dc0,0x0007e488,0x000d7e45,
|
||||
/* 00E6 */ 0x00000000,0x000d7a44,0x0007e48a,0x00000000,
|
||||
/* 00E8 */ 0x00011f05,0x00084080,0x00000000,0x00000000,
|
||||
/* 00EA */ 0x00001705,0x000b3540,0x00008a01,0x000bf040,
|
||||
/* 00EC */ 0x00007081,0x000bb5c0,0x00055488,0x00000000,
|
||||
/* 00EE */ 0x0000d482,0x0003fc40,0x0003fc88,0x00000000,
|
||||
/* 00F0 */ 0x0001e401,0x000b3a00,0x0001ec81,0x000bd6c0,
|
||||
/* 00F2 */ 0x0002ef88,0x000e7784,0x00056f08,0x00000000,
|
||||
/* 00F4 */ 0x000d86b0,0x00001007,0x00008281,0x000bb240,
|
||||
/* 00F6 */ 0x0000b801,0x000b7140,0x00007888,0x00000000,
|
||||
/* 00F8 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000,
|
||||
/* 00FA */ 0x00000000,0x00000000,0x00055288,0x000c555c,
|
||||
/* 00FC */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
|
||||
/* 00FE */ 0x0000fa88,0x00000000,0x00000032,0x00001000,
|
||||
/* 0100 */ 0x0000073d,0x00001000,0x0007f188,0x000c0000,
|
||||
/* 0102 */ 0x00000000,0x00000000,0x0008c01c,0x00001003,
|
||||
/* 0104 */ 0x00002705,0x00001008,0x0008b201,0x000c1392,
|
||||
/* 0106 */ 0x0000ba01,0x00000000,
|
||||
/* TASKTREETHREAD */
|
||||
/* 0107 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4,
|
||||
/* 0109 */ 0x00057488,0x00000000,0x000a6388,0x00001001,
|
||||
/* 010B */ 0x0008b334,0x000bc141,0x0003020e,0x00000000,
|
||||
/* 010D */ 0x000986b0,0x00001008,0x00003625,0x000c5dfa,
|
||||
/* 010F */ 0x000a638a,0x00001001,0x0008020e,0x00001002,
|
||||
/* 0111 */ 0x0009a6b0,0x00001008,0x0007f301,0x00000000,
|
||||
/* 0113 */ 0x00000000,0x00000000,0x00002725,0x000a8c40,
|
||||
/* 0115 */ 0x000000ae,0x00000000,0x000e8630,0x00001008,
|
||||
/* 0117 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640,
|
||||
/* 0119 */ 0x000b8630,0x00001008,0x000799b8,0x0002d6c0,
|
||||
/* 011B */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000,
|
||||
/* 011D */ 0x00062208,0x000c4117,0x000a0630,0x00001009,
|
||||
/* 011F */ 0x00000000,0x000c0000,0x0001022e,0x00000000,
|
||||
/* 0121 */ 0x0006a630,0x00001009,0x00000032,0x00001000,
|
||||
/* 0123 */ 0x000ca21c,0x00001003,0x00005a02,0x00000000,
|
||||
/* 0125 */ 0x0001a630,0x00001009,0x00000000,0x000c0000,
|
||||
/* 0127 */ 0x00000036,0x00001000,0x00000000,0x00000000,
|
||||
/* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 012B */ 0x00000000,0x00000000,0x0003a730,0x00001008,
|
||||
/* 012D */ 0x0007f801,0x000c0000,0x00000037,0x00001000,
|
||||
/* 012F */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0131 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0133 */ 0x0003a730,0x00001008,0x00000033,0x00001000,
|
||||
/* 0135 */ 0x0003a705,0x00001008,0x00007a01,0x000c0000,
|
||||
/* 0137 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000,
|
||||
/* 0139 */ 0x00090730,0x0000100a,0x00000000,0x000c0000,
|
||||
/* 013B */ 0x00000000,0x00000000,
|
||||
/* TASKTREEHEADERCODE */
|
||||
/* 013C */ 0x0007aab0,0x00034880,0x000a8fb0,0x0000100b,
|
||||
/* 013E */ 0x00057488,0x00000000,0x00033b94,0x00081140,
|
||||
/* 0140 */ 0x000183ae,0x00000000,0x000a86b0,0x0000100b,
|
||||
/* 0142 */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
|
||||
/* 0144 */ 0x00042731,0x00001003,
|
||||
/* FGTASKTREEHEADERCODE */
|
||||
/* 0145 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100a,
|
||||
/* 0147 */ 0x00057488,0x00000000,0x00033b94,0x00081140,
|
||||
/* 0149 */ 0x000183ae,0x00000000,0x000b06b0,0x0000100b,
|
||||
/* 014B */ 0x00022f05,0x00000000,0x00007401,0x00091140,
|
||||
/* 014D */ 0x00048f05,0x000951c0,0x00042731,0x00001003,
|
||||
/* 014F */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
|
||||
/* 0151 */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003,
|
||||
/* 0153 */ 0x00000000,0x00000000,0x0008e19c,0x00001003,
|
||||
/* 0155 */ 0x000083c1,0x00093040,0x00000f41,0x00097140,
|
||||
/* 0157 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
|
||||
/* 0159 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
|
||||
/* 015B */ 0x00000000,0x000fdc44,0x00055208,0x00000000,
|
||||
/* 015D */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00,
|
||||
/* 015F */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000,
|
||||
/* 0161 */ 0x00012f05,0x00036880,0x00065308,0x000c2997,
|
||||
/* 0163 */ 0x000086b0,0x0000100b,0x0004410a,0x000d40c7,
|
||||
/* 0165 */ 0x00000000,0x00000000,0x00088730,0x00001004,
|
||||
/* 0167 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000,
|
||||
/* NULLALGORITHM */
|
||||
/* 0169 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47,
|
||||
/* 016B */ 0x00080000,0x000bffc7,0x0000273d,0x00001000,
|
||||
/* HFGEXECCHILD */
|
||||
/* 016D */ 0x00000000,0x000eba44,
|
||||
/* HFGEXECCHILD_98 */
|
||||
/* 016E */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
|
||||
/* HFGEXECCHILD_PUSH1IND */
|
||||
/* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880,
|
||||
/* 0172 */ 0x00006a88,0x000c75c4,
|
||||
/* HFGEXECSIBLING */
|
||||
/* 0173 */ 0x00000000,0x000e5084,0x00000000,0x000eba44,
|
||||
/* HFGEXECSIBLING_298 */
|
||||
/* 0175 */ 0x00087401,0x000e4782,
|
||||
/* HFGEXECSIBLING_2IND1 */
|
||||
/* 0176 */ 0x00000734,0x00001000,0x00010705,0x000a6880,
|
||||
/* 0178 */ 0x00006a88,0x000c75c4,
|
||||
/* S16_CODECOUTPUTTASK */
|
||||
/* 0179 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40,
|
||||
/* 017B */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80,
|
||||
/* 017D */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0,
|
||||
/* 017F */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0,
|
||||
/* 0181 */ 0x00073fb0,0x00074c80,0x000583a0,0x0000100c,
|
||||
/* 0183 */ 0x000ee388,0x00042970,0x00008301,0x00021ef2,
|
||||
/* 0185 */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b,
|
||||
/* 0187 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916,
|
||||
/* 0189 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000,
|
||||
/* 018B */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b,
|
||||
/* 018D */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956,
|
||||
/* 018F */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40,
|
||||
/* 0191 */ 0x00058730,0x00001400,0x000d7488,0x000c3a00,
|
||||
/* 0193 */ 0x00048f05,0x00000000
|
||||
};
|
||||
/* #CODE_END */
|
||||
|
||||
static u32 cwc4630_parameter[] = {
|
||||
/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000,
|
||||
/* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000
|
||||
}; /* #PARAMETER_END */
|
||||
|
||||
|
||||
static struct dsp_segment_desc cwc4630_segments[] = {
|
||||
{ SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000328, cwc4630_code },
|
||||
{ SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000080, cwc4630_parameter },
|
||||
};
|
||||
|
||||
static struct dsp_module_desc cwc4630_module = {
|
||||
"cwc4630",
|
||||
{
|
||||
38,
|
||||
cwc4630_symbols
|
||||
},
|
||||
2,
|
||||
cwc4630_segments,
|
||||
};
|
||||
|
||||
#endif /* __HEADER_cwc4630_H__ */
|
@ -1,176 +0,0 @@
|
||||
/* generated from cwcasync.osp DO NOT MODIFY */
|
||||
|
||||
#ifndef __HEADER_cwcasync_H__
|
||||
#define __HEADER_cwcasync_H__
|
||||
|
||||
static struct dsp_symbol_entry cwcasync_symbols[] = {
|
||||
{ 0x8000, "EXECCHILD",0x03 },
|
||||
{ 0x8001, "EXECCHILD_98",0x03 },
|
||||
{ 0x8003, "EXECCHILD_PUSH1IND",0x03 },
|
||||
{ 0x8008, "EXECSIBLING",0x03 },
|
||||
{ 0x800a, "EXECSIBLING_298",0x03 },
|
||||
{ 0x800b, "EXECSIBLING_2IND1",0x03 },
|
||||
{ 0x8010, "TIMINGMASTER",0x03 },
|
||||
{ 0x804f, "S16_CODECINPUTTASK",0x03 },
|
||||
{ 0x805e, "PCMSERIALINPUTTASK",0x03 },
|
||||
{ 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
|
||||
{ 0x809a, "S16_MIX",0x03 },
|
||||
{ 0x80bb, "S16_UPSRC",0x03 },
|
||||
{ 0x813b, "MIX3_EXP",0x03 },
|
||||
{ 0x8164, "DECIMATEBYPOW2",0x03 },
|
||||
{ 0x8197, "VARIDECIMATE",0x03 },
|
||||
{ 0x81f2, "_3DINPUTTASK",0x03 },
|
||||
{ 0x820a, "_3DPRLGCINPTASK",0x03 },
|
||||
{ 0x8227, "_3DSTEREOINPUTTASK",0x03 },
|
||||
{ 0x8242, "_3DOUTPUTTASK",0x03 },
|
||||
{ 0x82c4, "HRTF_MORPH_TASK",0x03 },
|
||||
{ 0x82c6, "WAIT4DATA",0x03 },
|
||||
{ 0x82fa, "PROLOGIC",0x03 },
|
||||
{ 0x8496, "DECORRELATOR",0x03 },
|
||||
{ 0x84a4, "STEREO2MONO",0x03 },
|
||||
{ 0x0000, "OVERLAYBEGINADDRESS",0x00 },
|
||||
{ 0x0000, "SPIOWRITE",0x03 },
|
||||
{ 0x000d, "S16_ASYNCCODECINPUTTASK",0x03 },
|
||||
{ 0x0043, "SPDIFITASK",0x03 },
|
||||
{ 0x007b, "SPDIFOTASK",0x03 },
|
||||
{ 0x0097, "ASYNCHFGTXCODE",0x03 },
|
||||
{ 0x00be, "ASYNCHFGRXCODE",0x03 },
|
||||
{ 0x00db, "#CODE_END",0x00 },
|
||||
}; /* cwcasync symbols */
|
||||
|
||||
static u32 cwcasync_code[] = {
|
||||
/* OVERLAYBEGINADDRESS */
|
||||
/* 0000 */ 0x00002731,0x00001400,0x00003725,0x000a8440,
|
||||
/* 0002 */ 0x000000ae,0x00000000,0x00060630,0x00001000,
|
||||
/* 0004 */ 0x00000000,0x000c7560,0x00075282,0x0002d640,
|
||||
/* 0006 */ 0x00021705,0x00000000,0x00072ab8,0x0002d6c0,
|
||||
/* 0008 */ 0x00020630,0x00001000,0x000c74c2,0x000d4b82,
|
||||
/* 000A */ 0x000475c2,0x00000000,0x0003430a,0x000c0000,
|
||||
/* 000C */ 0x00042730,0x00001400,
|
||||
/* S16_ASYNCCODECINPUTTASK */
|
||||
/* 000D */ 0x0006a108,0x000cf2c4,0x0004f4c0,0x00000000,
|
||||
/* 000F */ 0x000fa418,0x0000101f,0x0005d402,0x0001c500,
|
||||
/* 0011 */ 0x000f0630,0x00001000,0x00004418,0x00001380,
|
||||
/* 0013 */ 0x000e243d,0x000d394a,0x00049705,0x00000000,
|
||||
/* 0015 */ 0x0007d530,0x000b4240,0x000e00f2,0x00001000,
|
||||
/* 0017 */ 0x00009134,0x000ca20a,0x00004c90,0x00001000,
|
||||
/* 0019 */ 0x0005d705,0x00000000,0x00004f25,0x00098240,
|
||||
/* 001B */ 0x00004725,0x00000000,0x0000e48a,0x00000000,
|
||||
/* 001D */ 0x00027295,0x0009c2c0,0x0003df25,0x00000000,
|
||||
/* 001F */ 0x000e8030,0x00001001,0x0005f718,0x000ac600,
|
||||
/* 0021 */ 0x0007cf30,0x000c2a01,0x00082630,0x00001001,
|
||||
/* 0023 */ 0x000504a0,0x00001001,0x00029314,0x000bcb80,
|
||||
/* 0025 */ 0x0003cf25,0x000b0e00,0x0004f5c0,0x00000000,
|
||||
/* 0027 */ 0x00049118,0x000d888a,0x0007dd02,0x000c6efa,
|
||||
/* 0029 */ 0x00000000,0x00000000,0x0004f5c0,0x00069c80,
|
||||
/* 002B */ 0x0000d402,0x00000000,0x000e8630,0x00001001,
|
||||
/* 002D */ 0x00079130,0x00000000,0x00049118,0x00090e00,
|
||||
/* 002F */ 0x0006c10a,0x00000000,0x00000000,0x000c0000,
|
||||
/* 0031 */ 0x0007cf30,0x00030580,0x00005725,0x00000000,
|
||||
/* 0033 */ 0x000d84a0,0x00001001,0x00029314,0x000b4780,
|
||||
/* 0035 */ 0x0003cf25,0x000b8600,0x00000000,0x00000000,
|
||||
/* 0037 */ 0x00000000,0x000c0000,0x00000000,0x00042c80,
|
||||
/* 0039 */ 0x0001dec1,0x000e488c,0x00031114,0x00000000,
|
||||
/* 003B */ 0x0004f5c2,0x00000000,0x0003640a,0x00000000,
|
||||
/* 003D */ 0x00000000,0x000e5084,0x00000000,0x000eb844,
|
||||
/* 003F */ 0x00007001,0x00000000,0x00000734,0x00001000,
|
||||
/* 0041 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4,
|
||||
/* SPDIFITASK */
|
||||
/* 0043 */ 0x0006a108,0x000cf2c4,0x0004f4c0,0x000d5384,
|
||||
/* 0045 */ 0x0007e48a,0x00000000,0x00067718,0x00001000,
|
||||
/* 0047 */ 0x0007a418,0x00001000,0x0007221a,0x00000000,
|
||||
/* 0049 */ 0x0005d402,0x00014500,0x000b8630,0x00001002,
|
||||
/* 004B */ 0x00004418,0x00001780,0x000e243d,0x000d394a,
|
||||
/* 004D */ 0x00049705,0x00000000,0x0007d530,0x000b4240,
|
||||
/* 004F */ 0x000ac0f2,0x00001002,0x00014414,0x00000000,
|
||||
/* 0051 */ 0x00004c90,0x00001000,0x0005d705,0x00000000,
|
||||
/* 0053 */ 0x00004f25,0x00098240,0x00004725,0x00000000,
|
||||
/* 0055 */ 0x0000e48a,0x00000000,0x00027295,0x0009c2c0,
|
||||
/* 0057 */ 0x0007df25,0x00000000,0x000ac030,0x00001003,
|
||||
/* 0059 */ 0x0005f718,0x000fe798,0x00029314,0x000bcb80,
|
||||
/* 005B */ 0x00000930,0x000b0e00,0x0004f5c0,0x000de204,
|
||||
/* 005D */ 0x000884a0,0x00001003,0x0007cf25,0x000e3560,
|
||||
/* 005F */ 0x00049118,0x00000000,0x00049118,0x000d888a,
|
||||
/* 0061 */ 0x0007dd02,0x000c6efa,0x0000c434,0x00030040,
|
||||
/* 0063 */ 0x000fda82,0x000c2312,0x000fdc0e,0x00001001,
|
||||
/* 0065 */ 0x00083402,0x000c2b92,0x000706b0,0x00001003,
|
||||
/* 0067 */ 0x00075a82,0x00000000,0x0000d625,0x000b0940,
|
||||
/* 0069 */ 0x0000840e,0x00001002,0x0000aabc,0x000c511e,
|
||||
/* 006B */ 0x00078730,0x00001003,0x0000aaf4,0x000e910a,
|
||||
/* 006D */ 0x0004628a,0x00000000,0x00006aca,0x00000000,
|
||||
/* 006F */ 0x00000930,0x00000000,0x0004f5c0,0x00069c80,
|
||||
/* 0071 */ 0x00046ac0,0x00000000,0x0003c40a,0x000fc898,
|
||||
/* 0073 */ 0x00049118,0x00090e00,0x0006c10a,0x00000000,
|
||||
/* 0075 */ 0x00000000,0x000e5084,0x00000000,0x000eb844,
|
||||
/* 0077 */ 0x00007001,0x00000000,0x00000734,0x00001000,
|
||||
/* 0079 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4,
|
||||
/* SPDIFOTASK */
|
||||
/* 007B */ 0x0006a108,0x000c0000,0x0004f4c0,0x000c3245,
|
||||
/* 007D */ 0x0000a418,0x00001000,0x0003a20a,0x00000000,
|
||||
/* 007F */ 0x00004418,0x00001380,0x000e243d,0x000d394a,
|
||||
/* 0081 */ 0x000c9705,0x000def92,0x0008c030,0x00001004,
|
||||
/* 0083 */ 0x0005f718,0x000fe798,0x00000000,0x000c0000,
|
||||
/* 0085 */ 0x00005725,0x00000000,0x000704a0,0x00001004,
|
||||
/* 0087 */ 0x00029314,0x000b4780,0x0003cf25,0x000b8600,
|
||||
/* 0089 */ 0x00000000,0x00000000,0x00000000,0x000c0000,
|
||||
/* 008B */ 0x00000000,0x00042c80,0x0001dec1,0x000e488c,
|
||||
/* 008D */ 0x00031114,0x00000000,0x0004f5c2,0x00000000,
|
||||
/* 008F */ 0x0004a918,0x00098600,0x0006c28a,0x00000000,
|
||||
/* 0091 */ 0x00000000,0x000e5084,0x00000000,0x000eb844,
|
||||
/* 0093 */ 0x00007001,0x00000000,0x00000734,0x00001000,
|
||||
/* 0095 */ 0x00010705,0x000a6880,0x00006a88,0x000c75c4,
|
||||
/* ASYNCHFGTXCODE */
|
||||
/* 0097 */ 0x0002a880,0x000b4e40,0x00042214,0x000e5548,
|
||||
/* 0099 */ 0x000542bf,0x00000000,0x00000000,0x000481c0,
|
||||
/* 009B */ 0x00000000,0x00000000,0x00000000,0x00000030,
|
||||
/* 009D */ 0x0000072d,0x000fbf8a,0x00077f94,0x000ea7df,
|
||||
/* 009F */ 0x0002ac95,0x000d3145,0x00002731,0x00001400,
|
||||
/* 00A1 */ 0x00006288,0x000c71c4,0x00014108,0x000e6044,
|
||||
/* 00A3 */ 0x00035408,0x00000000,0x00025418,0x000a0ec0,
|
||||
/* 00A5 */ 0x0001443d,0x000ca21e,0x00046595,0x000d730c,
|
||||
/* 00A7 */ 0x0006538e,0x00000000,0x00064630,0x00001005,
|
||||
/* 00A9 */ 0x000e7b0e,0x000df782,0x000746b0,0x00001005,
|
||||
/* 00AB */ 0x00036f05,0x000c0000,0x00043695,0x000d598c,
|
||||
/* 00AD */ 0x0005331a,0x000f2185,0x00000000,0x00000000,
|
||||
/* 00AF */ 0x000007ae,0x000bdb00,0x00040630,0x00001400,
|
||||
/* 00B1 */ 0x0005e708,0x000c0000,0x0007ef30,0x000b1c00,
|
||||
/* 00B3 */ 0x000d86a0,0x00001005,0x00066408,0x000c0000,
|
||||
/* 00B5 */ 0x00000000,0x00000000,0x00021843,0x00000000,
|
||||
/* 00B7 */ 0x00000cac,0x00062c00,0x00001dac,0x00063400,
|
||||
/* 00B9 */ 0x00002cac,0x0006cc80,0x000db943,0x000e5ca1,
|
||||
/* 00BB */ 0x00000000,0x00000000,0x0006680a,0x000f3205,
|
||||
/* 00BD */ 0x00042730,0x00001400,
|
||||
/* ASYNCHFGRXCODE */
|
||||
/* 00BE */ 0x00014108,0x000f2204,0x00025418,0x000a2ec0,
|
||||
/* 00C0 */ 0x00015dbd,0x00038100,0x00015dbc,0x00000000,
|
||||
/* 00C2 */ 0x0005e415,0x00034880,0x0001258a,0x000d730c,
|
||||
/* 00C4 */ 0x0006538e,0x000baa40,0x00060630,0x00001006,
|
||||
/* 00C6 */ 0x00067b0e,0x000ac380,0x0003ef05,0x00000000,
|
||||
/* 00C8 */ 0x0000f734,0x0001c300,0x000586b0,0x00001400,
|
||||
/* 00CA */ 0x000b6f05,0x000c3a00,0x00048f05,0x00000000,
|
||||
/* 00CC */ 0x0005b695,0x0008c380,0x0002058e,0x00000000,
|
||||
/* 00CE */ 0x000500b0,0x00001400,0x0002b318,0x000e998d,
|
||||
/* 00D0 */ 0x0006430a,0x00000000,0x00000000,0x000ef384,
|
||||
/* 00D2 */ 0x00004725,0x000c0000,0x00000000,0x000f3204,
|
||||
/* 00D4 */ 0x00004f25,0x000c0000,0x00080000,0x000e5ca1,
|
||||
/* 00D6 */ 0x000cb943,0x000e5ca1,0x0004b943,0x00000000,
|
||||
/* 00D8 */ 0x00040730,0x00001400,0x000cb943,0x000e5ca1,
|
||||
/* 00DA */ 0x0004b943,0x00000000
|
||||
};
|
||||
/* #CODE_END */
|
||||
|
||||
static struct dsp_segment_desc cwcasync_segments[] = {
|
||||
{ SEGTYPE_SP_PROGRAM, 0x00000000, 0x000001b6, cwcasync_code },
|
||||
};
|
||||
|
||||
static struct dsp_module_desc cwcasync_module = {
|
||||
"cwcasync",
|
||||
{
|
||||
32,
|
||||
cwcasync_symbols
|
||||
},
|
||||
1,
|
||||
cwcasync_segments,
|
||||
};
|
||||
|
||||
#endif /* __HEADER_cwcasync_H__ */
|
@ -1,48 +0,0 @@
|
||||
/* generated by Benny
|
||||
MODIFY ON YOUR OWN RISK */
|
||||
|
||||
#ifndef __HEADER_cwcbinhack_H__
|
||||
#define __HEADER_cwcbinhack_H__
|
||||
|
||||
static struct dsp_symbol_entry cwcbinhack_symbols[] = {
|
||||
{ 0x02c8, "OVERLAYBEGINADDRESS",0x00 },
|
||||
{ 0x02c8, "MAGICSNOOPTASK",0x03 },
|
||||
{ 0x0308, "#CODE_END",0x00 },
|
||||
}; /* cwcbinhack symbols */
|
||||
|
||||
static u32 cwcbinhack_code[] = {
|
||||
/* 0x02c8 */
|
||||
0x0007bfb0,0x000bc240,0x00000c2e,0x000c6084, /* 1 */
|
||||
0x000b8630,0x00001016,0x00006408,0x000efb84, /* 2 */
|
||||
0x00016008,0x00000000,0x0001c088,0x000c0000, /* 3 */
|
||||
0x000fc908,0x000e3392,0x0005f488,0x000efb84, /* 4 */
|
||||
0x0001d402,0x000b2e00,0x0003d418,0x00001000, /* 5 */
|
||||
0x0008d574,0x000c4293,0x00065625,0x000ea30e, /* 6 */
|
||||
0x00096c01,0x000c6f92,0x0001a58a,0x000c6085, /* 7 */
|
||||
0x00002f43,0x00000000,0x000e03a0,0x00001016, /* 8 */
|
||||
0x0005e608,0x000c0000,0x00000000,0x00000000, /* 9 */
|
||||
0x000ca108,0x000dcca1,0x00003bac,0x000c3205, /* 10 */
|
||||
0x00073843,0x00000000,0x00010730,0x00001017, /* 11 */
|
||||
0x0001600a,0x000c0000,0x00057488,0x00000000, /* 12 */
|
||||
0x00000000,0x000e5084,0x00000000,0x000eba44, /* 13 */
|
||||
0x00087401,0x000e4782,0x00000734,0x00001000, /* 14 */
|
||||
0x00010705,0x000a6880,0x00006a88,0x000c75c4, /* 15 */
|
||||
0x00000000,0x00000000,0x00000000,0x00000000, /* 16 */
|
||||
};
|
||||
/* #CODE_END */
|
||||
|
||||
static struct dsp_segment_desc cwcbinhack_segments[] = {
|
||||
{ SEGTYPE_SP_PROGRAM, 0x00000000, 64, cwcbinhack_code },
|
||||
};
|
||||
|
||||
static struct dsp_module_desc cwcbinhack_module = {
|
||||
"cwcbinhack",
|
||||
{
|
||||
3,
|
||||
cwcbinhack_symbols
|
||||
},
|
||||
1,
|
||||
cwcbinhack_segments,
|
||||
};
|
||||
|
||||
#endif /* __HEADER_cwcbinhack_H__ */
|
@ -1,170 +0,0 @@
|
||||
//
|
||||
// Copyright(c) by Benny Sjostrand (benny@hostmobility.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// This code runs inside the DSP (cs4610, cs4612, cs4624, or cs4630),
|
||||
// to compile it you need a tool named SPASM 3.0 and DSP code owned by
|
||||
// Cirrus Logic(R). The SPASM program will generate a object file (cwcdma.osp),
|
||||
// the "ospparser" tool will genereate the cwcdma.h file it's included from
|
||||
// the cs46xx_lib.c file.
|
||||
//
|
||||
//
|
||||
// The purpose of this code is very simple: make it possible to tranfser
|
||||
// the samples 'as they are' with no alteration from a PCMreader
|
||||
// SCB (DMA from host) to any other SCB. This is useful for AC3 through SPDIF.
|
||||
// SRC (source rate converters) task always alters the samples in somehow,
|
||||
// however it's from 48khz -> 48khz.
|
||||
// The alterations are not audible, but AC3 wont work.
|
||||
//
|
||||
// ...
|
||||
// |
|
||||
// +---------------+
|
||||
// | AsynchFGTxSCB |
|
||||
// +---------------+
|
||||
// |
|
||||
// subListPtr
|
||||
// |
|
||||
// +--------------+
|
||||
// | DMAReader |
|
||||
// +--------------+
|
||||
// |
|
||||
// subListPtr
|
||||
// |
|
||||
// +-------------+
|
||||
// | PCMReader |
|
||||
// +-------------+
|
||||
// (DMA from host)
|
||||
//
|
||||
|
||||
struct dmaSCB
|
||||
{
|
||||
long dma_reserved1[3];
|
||||
|
||||
short dma_reserved2:dma_outBufPtr;
|
||||
|
||||
short dma_unused1:dma_unused2;
|
||||
|
||||
long dma_reserved3[4];
|
||||
|
||||
short dma_subListPtr:dma_nextSCB;
|
||||
short dma_SPBptr:dma_entryPoint;
|
||||
|
||||
long dma_strmRsConfig;
|
||||
long dma_strmBufPtr;
|
||||
|
||||
long dma_reserved4;
|
||||
|
||||
VolumeControl s2m_volume;
|
||||
};
|
||||
|
||||
#export DMAReader
|
||||
void DMAReader()
|
||||
{
|
||||
execChild();
|
||||
r2 = r0->dma_subListPtr;
|
||||
r1 = r0->nextSCB;
|
||||
|
||||
rsConfig01 = r2->strmRsConfig;
|
||||
// Load rsConfig for input buffer
|
||||
|
||||
rsDMA01 = r2->basicReq.daw, , tb = Z(0 - rf);
|
||||
// Load rsDMA in case input buffer is a DMA buffer Test to see if there is any data to transfer
|
||||
|
||||
if (tb) goto execSibling_2ind1 after {
|
||||
r5 = rf + (-1);
|
||||
r6 = r1->dma_entryPoint; // r6 = entry point of sibling task
|
||||
r1 = r1->dma_SPBptr, // r1 = pointer to sibling task's SPB
|
||||
, ind = r6; // Load entry point of sibling task
|
||||
}
|
||||
|
||||
rsConfig23 = r0->dma_strmRsConfig;
|
||||
// Load rsConfig for output buffer (never a DMA buffer)
|
||||
|
||||
r4 = r0->dma_outBufPtr;
|
||||
|
||||
rsa0 = r2->strmBufPtr;
|
||||
// rsa0 = input buffer pointer
|
||||
|
||||
for (i = r5; i >= 0; --i)
|
||||
after {
|
||||
rsa2 = r4;
|
||||
// rsa2 = output buffer pointer
|
||||
|
||||
nop;
|
||||
nop;
|
||||
}
|
||||
//*****************************
|
||||
// TODO: cycles to this point *
|
||||
//*****************************
|
||||
{
|
||||
acc0 = (rsd0 = *rsa0++1);
|
||||
// get sample
|
||||
|
||||
nop; // Those "nop"'s are really uggly, but there's
|
||||
nop; // something with DSP's pipelines which I don't
|
||||
nop; // understand, resulting this code to fail without
|
||||
// having those "nop"'s (Benny)
|
||||
|
||||
rsa0?reqDMA = r2;
|
||||
// Trigger DMA transfer on input stream,
|
||||
// if needed to replenish input buffer
|
||||
|
||||
nop;
|
||||
// Yet another magic "nop" to make stuff work
|
||||
|
||||
,,r98 = acc0 $+>> 0;
|
||||
// store sample in ALU
|
||||
|
||||
nop;
|
||||
// latency on load register.
|
||||
// (this one is understandable)
|
||||
|
||||
*rsa2++1 = r98;
|
||||
// store sample in output buffer
|
||||
|
||||
nop; // The same story
|
||||
nop; // as above again ...
|
||||
nop;
|
||||
}
|
||||
// TODO: cycles per loop iteration
|
||||
|
||||
r2->strmBufPtr = rsa0,, ;
|
||||
// Update the modified buffer pointers
|
||||
|
||||
r4 = rsa2;
|
||||
// Load output pointer position into r4
|
||||
|
||||
r2 = r0->nextSCB;
|
||||
// Sibling task
|
||||
|
||||
goto execSibling_2ind1 // takes 6 cycles
|
||||
after {
|
||||
r98 = r2->thisSPB:entryPoint;
|
||||
// Load child routine entry and data address
|
||||
|
||||
r1 = r9;
|
||||
// r9 is r2->thisSPB
|
||||
|
||||
r0->dma_outBufPtr = r4,,
|
||||
// Store updated output buffer pointer
|
||||
|
||||
ind = r8;
|
||||
// r8 is r2->entryPoint
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
/* generated from cwcdma.osp DO NOT MODIFY */
|
||||
|
||||
#ifndef __HEADER_cwcdma_H__
|
||||
#define __HEADER_cwcdma_H__
|
||||
|
||||
static struct dsp_symbol_entry cwcdma_symbols[] = {
|
||||
{ 0x8000, "EXECCHILD",0x03 },
|
||||
{ 0x8001, "EXECCHILD_98",0x03 },
|
||||
{ 0x8003, "EXECCHILD_PUSH1IND",0x03 },
|
||||
{ 0x8008, "EXECSIBLING",0x03 },
|
||||
{ 0x800a, "EXECSIBLING_298",0x03 },
|
||||
{ 0x800b, "EXECSIBLING_2IND1",0x03 },
|
||||
{ 0x8010, "TIMINGMASTER",0x03 },
|
||||
{ 0x804f, "S16_CODECINPUTTASK",0x03 },
|
||||
{ 0x805e, "PCMSERIALINPUTTASK",0x03 },
|
||||
{ 0x806d, "S16_MIX_TO_OSTREAM",0x03 },
|
||||
{ 0x809a, "S16_MIX",0x03 },
|
||||
{ 0x80bb, "S16_UPSRC",0x03 },
|
||||
{ 0x813b, "MIX3_EXP",0x03 },
|
||||
{ 0x8164, "DECIMATEBYPOW2",0x03 },
|
||||
{ 0x8197, "VARIDECIMATE",0x03 },
|
||||
{ 0x81f2, "_3DINPUTTASK",0x03 },
|
||||
{ 0x820a, "_3DPRLGCINPTASK",0x03 },
|
||||
{ 0x8227, "_3DSTEREOINPUTTASK",0x03 },
|
||||
{ 0x8242, "_3DOUTPUTTASK",0x03 },
|
||||
{ 0x82c4, "HRTF_MORPH_TASK",0x03 },
|
||||
{ 0x82c6, "WAIT4DATA",0x03 },
|
||||
{ 0x82fa, "PROLOGIC",0x03 },
|
||||
{ 0x8496, "DECORRELATOR",0x03 },
|
||||
{ 0x84a4, "STEREO2MONO",0x03 },
|
||||
{ 0x0000, "OVERLAYBEGINADDRESS",0x00 },
|
||||
{ 0x0000, "DMAREADER",0x03 },
|
||||
{ 0x0018, "#CODE_END",0x00 },
|
||||
}; /* cwcdma symbols */
|
||||
|
||||
static u32 cwcdma_code[] = {
|
||||
/* OVERLAYBEGINADDRESS */
|
||||
/* 0000 */ 0x00002731,0x00001400,0x0004c108,0x000e5044,
|
||||
/* 0002 */ 0x0005f608,0x00000000,0x000007ae,0x000be300,
|
||||
/* 0004 */ 0x00058630,0x00001400,0x0007afb0,0x000e9584,
|
||||
/* 0006 */ 0x00007301,0x000a9840,0x0005e708,0x000cd104,
|
||||
/* 0008 */ 0x00067008,0x00000000,0x000902a0,0x00001000,
|
||||
/* 000A */ 0x00012a01,0x000c0000,0x00000000,0x00000000,
|
||||
/* 000C */ 0x00021843,0x000c0000,0x00000000,0x000c0000,
|
||||
/* 000E */ 0x0000e101,0x000c0000,0x00000cac,0x00000000,
|
||||
/* 0010 */ 0x00080000,0x000e5ca1,0x00000000,0x000c0000,
|
||||
/* 0012 */ 0x00000000,0x00000000,0x00000000,0x00092c00,
|
||||
/* 0014 */ 0x000122c1,0x000e5084,0x00058730,0x00001400,
|
||||
/* 0016 */ 0x000d7488,0x000e4782,0x00007401,0x0001c100
|
||||
};
|
||||
|
||||
/* #CODE_END */
|
||||
|
||||
static struct dsp_segment_desc cwcdma_segments[] = {
|
||||
{ SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000030, cwcdma_code },
|
||||
};
|
||||
|
||||
static struct dsp_module_desc cwcdma_module = {
|
||||
"cwcdma",
|
||||
{
|
||||
27,
|
||||
cwcdma_symbols
|
||||
},
|
||||
1,
|
||||
cwcdma_segments,
|
||||
};
|
||||
|
||||
#endif /* __HEADER_cwcdma_H__ */
|
@ -1,46 +0,0 @@
|
||||
/* generated from cwcsnoop.osp DO NOT MODIFY */
|
||||
|
||||
#ifndef __HEADER_cwcsnoop_H__
|
||||
#define __HEADER_cwcsnoop_H__
|
||||
|
||||
static struct dsp_symbol_entry cwcsnoop_symbols[] = {
|
||||
{ 0x0500, "OVERLAYBEGINADDRESS",0x00 },
|
||||
{ 0x0500, "OUTPUTSNOOP",0x03 },
|
||||
{ 0x051f, "#CODE_END",0x00 },
|
||||
}; /* cwcsnoop symbols */
|
||||
|
||||
static u32 cwcsnoop_code[] = {
|
||||
/* 0000 */ 0x0007bfb0,0x000b4e40,0x0007c088,0x000c0617,
|
||||
/* 0002 */ 0x00049705,0x00000000,0x00080630,0x00001028,
|
||||
/* 0004 */ 0x00076408,0x000efb84,0x00066008,0x00000000,
|
||||
/* 0006 */ 0x0007c908,0x000c0000,0x00046725,0x000efa44,
|
||||
/* 0008 */ 0x0005f708,0x00000000,0x0001d402,0x000b2e00,
|
||||
/* 000A */ 0x0003d418,0x00001000,0x0008d574,0x000c4293,
|
||||
/* 000C */ 0x00065625,0x000ea30e,0x00096c01,0x000c6f92,
|
||||
/* 000E */ 0x0006a58a,0x000f6085,0x00002f43,0x00000000,
|
||||
/* 0010 */ 0x000a83a0,0x00001028,0x0005e608,0x000c0000,
|
||||
/* 0012 */ 0x00000000,0x00000000,0x000ca108,0x000dcca1,
|
||||
/* 0014 */ 0x00003bac,0x000fb205,0x00073843,0x00000000,
|
||||
/* 0016 */ 0x000d8730,0x00001028,0x0006600a,0x000c0000,
|
||||
/* 0018 */ 0x00057488,0x00000000,0x00000000,0x000e5084,
|
||||
/* 001A */ 0x00000000,0x000eba44,0x00087401,0x000e4782,
|
||||
/* 001C */ 0x00000734,0x00001000,0x00010705,0x000a6880,
|
||||
/* 001E */ 0x00006a88,0x000c75c4
|
||||
};
|
||||
/* #CODE_END */
|
||||
|
||||
static struct dsp_segment_desc cwcsnoop_segments[] = {
|
||||
{ SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000003e, cwcsnoop_code },
|
||||
};
|
||||
|
||||
static struct dsp_module_desc cwcsnoop_module = {
|
||||
"cwcsnoop",
|
||||
{
|
||||
3,
|
||||
cwcsnoop_symbols
|
||||
},
|
||||
1,
|
||||
cwcsnoop_segments,
|
||||
};
|
||||
|
||||
#endif /* __HEADER_cwcsnoop_H__ */
|
@ -253,7 +253,7 @@ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
|
||||
static int snd_cs5535audio_free(struct cs5535audio *cs5535au)
|
||||
{
|
||||
synchronize_irq(cs5535au->irq);
|
||||
pci_set_power_state(cs5535au->pci, 3);
|
||||
pci_set_power_state(cs5535au->pci, PCI_D3hot);
|
||||
|
||||
if (cs5535au->irq >= 0)
|
||||
free_irq(cs5535au->irq, cs5535au);
|
||||
|
@ -435,6 +435,11 @@ atc_pcm_playback_position(struct ct_atc *atc, struct ct_atc_pcm *apcm)
|
||||
return 0;
|
||||
position = src->ops->get_ca(src);
|
||||
|
||||
if (position < apcm->vm_block->addr) {
|
||||
snd_printdd("ctxfi: bad ca - ca=0x%08x, vba=0x%08x, vbs=0x%08x\n", position, apcm->vm_block->addr, apcm->vm_block->size);
|
||||
position = apcm->vm_block->addr;
|
||||
}
|
||||
|
||||
size = apcm->vm_block->size;
|
||||
max_cisz = src->multi * src->rsc.msr;
|
||||
max_cisz = 128 * (max_cisz < 8 ? max_cisz : 8);
|
||||
|
@ -1422,7 +1422,7 @@ static void snd_es1968_free_dmabuf(struct es1968 *chip)
|
||||
|
||||
if (! chip->dma.area)
|
||||
return;
|
||||
snd_dma_reserve_buf(&chip->dma, snd_dma_pci_buf_id(chip->pci));
|
||||
snd_dma_free_pages(&chip->dma);
|
||||
while ((p = chip->buf_list.next) != &chip->buf_list) {
|
||||
struct esm_memory *chunk = list_entry(p, struct esm_memory, list);
|
||||
list_del(p);
|
||||
@ -1438,20 +1438,18 @@ snd_es1968_init_dmabuf(struct es1968 *chip)
|
||||
|
||||
chip->dma.dev.type = SNDRV_DMA_TYPE_DEV;
|
||||
chip->dma.dev.dev = snd_dma_pci_data(chip->pci);
|
||||
if (! snd_dma_get_reserved_buf(&chip->dma, snd_dma_pci_buf_id(chip->pci))) {
|
||||
err = snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV,
|
||||
snd_dma_pci_data(chip->pci),
|
||||
chip->total_bufsize, &chip->dma);
|
||||
if (err < 0 || ! chip->dma.area) {
|
||||
snd_printk(KERN_ERR "es1968: can't allocate dma pages for size %d\n",
|
||||
chip->total_bufsize);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) {
|
||||
snd_dma_free_pages(&chip->dma);
|
||||
snd_printk(KERN_ERR "es1968: DMA buffer beyond 256MB.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
err = snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV,
|
||||
snd_dma_pci_data(chip->pci),
|
||||
chip->total_bufsize, &chip->dma);
|
||||
if (err < 0 || ! chip->dma.area) {
|
||||
snd_printk(KERN_ERR "es1968: can't allocate dma pages for size %d\n",
|
||||
chip->total_bufsize);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if ((chip->dma.addr + chip->dma.bytes - 1) & ~((1 << 28) - 1)) {
|
||||
snd_dma_free_pages(&chip->dma);
|
||||
snd_printk(KERN_ERR "es1968: DMA buffer beyond 256MB.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&chip->buf_list);
|
||||
|
@ -87,69 +87,54 @@ config SND_HDA_PATCH_LOADER
|
||||
This option turns on hwdep and reconfig features automatically.
|
||||
|
||||
config SND_HDA_CODEC_REALTEK
|
||||
bool "Build Realtek HD-audio codec support"
|
||||
default y
|
||||
tristate "Build Realtek HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y here to include Realtek HD-audio codec support in
|
||||
Say Y or M here to include Realtek HD-audio codec support in
|
||||
snd-hda-intel driver, such as ALC880.
|
||||
|
||||
When the HD-audio driver is built as a module, the codec
|
||||
support code is also built as another module,
|
||||
snd-hda-codec-realtek.
|
||||
This module is automatically loaded at probing.
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA_INTEL=y && SND_HDA_CODEC_REALTEK=m
|
||||
|
||||
config SND_HDA_CODEC_ANALOG
|
||||
bool "Build Analog Device HD-audio codec support"
|
||||
default y
|
||||
tristate "Build Analog Device HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y here to include Analog Device HD-audio codec support in
|
||||
Say Y or M here to include Analog Device HD-audio codec support in
|
||||
snd-hda-intel driver, such as AD1986A.
|
||||
|
||||
When the HD-audio driver is built as a module, the codec
|
||||
support code is also built as another module,
|
||||
snd-hda-codec-analog.
|
||||
This module is automatically loaded at probing.
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA_INTEL=y && SND_HDA_CODEC_ANALOG=m
|
||||
|
||||
config SND_HDA_CODEC_SIGMATEL
|
||||
bool "Build IDT/Sigmatel HD-audio codec support"
|
||||
default y
|
||||
tristate "Build IDT/Sigmatel HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y here to include IDT (Sigmatel) HD-audio codec support in
|
||||
Say Y or M here to include IDT (Sigmatel) HD-audio codec support in
|
||||
snd-hda-intel driver, such as STAC9200.
|
||||
|
||||
When the HD-audio driver is built as a module, the codec
|
||||
support code is also built as another module,
|
||||
snd-hda-codec-idt.
|
||||
This module is automatically loaded at probing.
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA_INTEL=y && SND_HDA_CODEC_SIGMATEL=m
|
||||
|
||||
config SND_HDA_CODEC_VIA
|
||||
bool "Build VIA HD-audio codec support"
|
||||
default y
|
||||
tristate "Build VIA HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y here to include VIA HD-audio codec support in
|
||||
Say Y or M here to include VIA HD-audio codec support in
|
||||
snd-hda-intel driver, such as VT1708.
|
||||
|
||||
When the HD-audio driver is built as a module, the codec
|
||||
support code is also built as another module,
|
||||
snd-hda-codec-via.
|
||||
This module is automatically loaded at probing.
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA_INTEL=y && SND_HDA_CODEC_VIA=m
|
||||
|
||||
config SND_HDA_CODEC_HDMI
|
||||
bool "Build HDMI/DisplayPort HD-audio codec support"
|
||||
default y
|
||||
tristate "Build HDMI/DisplayPort HD-audio codec support"
|
||||
help
|
||||
Say Y here to include HDMI and DisplayPort HD-audio codec
|
||||
Say Y or M here to include HDMI and DisplayPort HD-audio codec
|
||||
support in snd-hda-intel driver. This includes all AMD/ATI,
|
||||
Intel and Nvidia HDMI/DisplayPort codecs.
|
||||
|
||||
When the HD-audio driver is built as a module, the codec
|
||||
support code is also built as another module,
|
||||
snd-hda-codec-hdmi.
|
||||
This module is automatically loaded at probing.
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA_INTEL=y && SND_HDA_CODEC_HDMI=m
|
||||
|
||||
config SND_HDA_I915
|
||||
bool
|
||||
@ -157,55 +142,43 @@ config SND_HDA_I915
|
||||
depends on DRM_I915
|
||||
|
||||
config SND_HDA_CODEC_CIRRUS
|
||||
bool "Build Cirrus Logic codec support"
|
||||
default y
|
||||
tristate "Build Cirrus Logic codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y here to include Cirrus Logic codec support in
|
||||
Say Y or M here to include Cirrus Logic codec support in
|
||||
snd-hda-intel driver, such as CS4206.
|
||||
|
||||
When the HD-audio driver is built as a module, the codec
|
||||
support code is also built as another module,
|
||||
snd-hda-codec-cirrus.
|
||||
This module is automatically loaded at probing.
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA_INTEL=y && SND_HDA_CODEC_CIRRUS=m
|
||||
|
||||
config SND_HDA_CODEC_CONEXANT
|
||||
bool "Build Conexant HD-audio codec support"
|
||||
default y
|
||||
tristate "Build Conexant HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y here to include Conexant HD-audio codec support in
|
||||
Say Y or M here to include Conexant HD-audio codec support in
|
||||
snd-hda-intel driver, such as CX20549.
|
||||
|
||||
When the HD-audio driver is built as a module, the codec
|
||||
support code is also built as another module,
|
||||
snd-hda-codec-conexant.
|
||||
This module is automatically loaded at probing.
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA_INTEL=y && SND_HDA_CODEC_CONEXANT=m
|
||||
|
||||
config SND_HDA_CODEC_CA0110
|
||||
bool "Build Creative CA0110-IBG codec support"
|
||||
default y
|
||||
tristate "Build Creative CA0110-IBG codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y here to include Creative CA0110-IBG codec support in
|
||||
Say Y or M here to include Creative CA0110-IBG codec support in
|
||||
snd-hda-intel driver, found on some Creative X-Fi cards.
|
||||
|
||||
When the HD-audio driver is built as a module, the codec
|
||||
support code is also built as another module,
|
||||
snd-hda-codec-ca0110.
|
||||
This module is automatically loaded at probing.
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA_INTEL=y && SND_HDA_CODEC_CA0110=m
|
||||
|
||||
config SND_HDA_CODEC_CA0132
|
||||
bool "Build Creative CA0132 codec support"
|
||||
default y
|
||||
tristate "Build Creative CA0132 codec support"
|
||||
help
|
||||
Say Y here to include Creative CA0132 codec support in
|
||||
Say Y or M here to include Creative CA0132 codec support in
|
||||
snd-hda-intel driver.
|
||||
|
||||
When the HD-audio driver is built as a module, the codec
|
||||
support code is also built as another module,
|
||||
snd-hda-codec-ca0132.
|
||||
This module is automatically loaded at probing.
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA_INTEL=y && SND_HDA_CODEC_CA0132=m
|
||||
|
||||
config SND_HDA_CODEC_CA0132_DSP
|
||||
bool "Support new DSP code for CA0132 codec"
|
||||
@ -220,37 +193,33 @@ config SND_HDA_CODEC_CA0132_DSP
|
||||
(ctefx.bin).
|
||||
|
||||
config SND_HDA_CODEC_CMEDIA
|
||||
bool "Build C-Media HD-audio codec support"
|
||||
default y
|
||||
tristate "Build C-Media HD-audio codec support"
|
||||
select SND_HDA_GENERIC
|
||||
help
|
||||
Say Y here to include C-Media HD-audio codec support in
|
||||
Say Y or M here to include C-Media HD-audio codec support in
|
||||
snd-hda-intel driver, such as CMI9880.
|
||||
|
||||
When the HD-audio driver is built as a module, the codec
|
||||
support code is also built as another module,
|
||||
snd-hda-codec-cmedia.
|
||||
This module is automatically loaded at probing.
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA_INTEL=y && SND_HDA_CODEC_CMEDIA=m
|
||||
|
||||
config SND_HDA_CODEC_SI3054
|
||||
bool "Build Silicon Labs 3054 HD-modem codec support"
|
||||
default y
|
||||
tristate "Build Silicon Labs 3054 HD-modem codec support"
|
||||
help
|
||||
Say Y here to include Silicon Labs 3054 HD-modem codec
|
||||
Say Y or M here to include Silicon Labs 3054 HD-modem codec
|
||||
(and compatibles) support in snd-hda-intel driver.
|
||||
|
||||
When the HD-audio driver is built as a module, the codec
|
||||
support code is also built as another module,
|
||||
snd-hda-codec-si3054.
|
||||
This module is automatically loaded at probing.
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA_INTEL=y && SND_HDA_CODEC_SI3054=m
|
||||
|
||||
config SND_HDA_GENERIC
|
||||
bool "Enable generic HD-audio codec parser"
|
||||
default y
|
||||
tristate "Enable generic HD-audio codec parser"
|
||||
help
|
||||
Say Y here to enable the generic HD-audio codec parser
|
||||
Say Y or M here to enable the generic HD-audio codec parser
|
||||
in snd-hda-intel driver.
|
||||
|
||||
comment "Set to Y if you want auto-loading the codec driver"
|
||||
depends on SND_HDA_INTEL=y && SND_HDA_GENERIC=m
|
||||
|
||||
config SND_HDA_POWER_SAVE_DEFAULT
|
||||
int "Default time-out for HD-audio power-save mode"
|
||||
depends on PM
|
||||
|
@ -3,7 +3,6 @@ snd-hda-intel-objs := hda_intel.o
|
||||
snd-hda-intel-$(CONFIG_SND_HDA_I915) += hda_i915.o
|
||||
|
||||
snd-hda-codec-y := hda_codec.o hda_jack.o hda_auto_parser.o
|
||||
snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
|
||||
snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
|
||||
snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
|
||||
snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
|
||||
@ -12,6 +11,7 @@ snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
|
||||
CFLAGS_hda_codec.o := -I$(src)
|
||||
CFLAGS_hda_intel.o := -I$(src)
|
||||
|
||||
snd-hda-codec-generic-objs := hda_generic.o
|
||||
snd-hda-codec-realtek-objs := patch_realtek.o
|
||||
snd-hda-codec-cmedia-objs := patch_cmedia.o
|
||||
snd-hda-codec-analog-objs := patch_analog.o
|
||||
@ -27,40 +27,19 @@ snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o
|
||||
# common driver
|
||||
obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
|
||||
|
||||
# codec drivers (note: CONFIG_SND_HDA_CODEC_XXX are booleans)
|
||||
ifdef CONFIG_SND_HDA_CODEC_REALTEK
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-realtek.o
|
||||
endif
|
||||
ifdef CONFIG_SND_HDA_CODEC_CMEDIA
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cmedia.o
|
||||
endif
|
||||
ifdef CONFIG_SND_HDA_CODEC_ANALOG
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-analog.o
|
||||
endif
|
||||
ifdef CONFIG_SND_HDA_CODEC_SIGMATEL
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-idt.o
|
||||
endif
|
||||
ifdef CONFIG_SND_HDA_CODEC_SI3054
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-si3054.o
|
||||
endif
|
||||
ifdef CONFIG_SND_HDA_CODEC_CIRRUS
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cirrus.o
|
||||
endif
|
||||
ifdef CONFIG_SND_HDA_CODEC_CA0110
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o
|
||||
endif
|
||||
ifdef CONFIG_SND_HDA_CODEC_CA0132
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0132.o
|
||||
endif
|
||||
ifdef CONFIG_SND_HDA_CODEC_CONEXANT
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o
|
||||
endif
|
||||
ifdef CONFIG_SND_HDA_CODEC_VIA
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-via.o
|
||||
endif
|
||||
ifdef CONFIG_SND_HDA_CODEC_HDMI
|
||||
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-hdmi.o
|
||||
endif
|
||||
# codec drivers
|
||||
obj-$(CONFIG_SND_HDA_GENERIC) += snd-hda-codec-generic.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_REALTEK) += snd-hda-codec-realtek.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_CMEDIA) += snd-hda-codec-cmedia.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_ANALOG) += snd-hda-codec-analog.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_SIGMATEL) += snd-hda-codec-idt.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_SI3054) += snd-hda-codec-si3054.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_CIRRUS) += snd-hda-codec-cirrus.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_CONEXANT) += snd-hda-codec-conexant.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_VIA) += snd-hda-codec-via.o
|
||||
obj-$(CONFIG_SND_HDA_CODEC_HDMI) += snd-hda-codec-hdmi.o
|
||||
|
||||
# this must be the last entry after codec drivers;
|
||||
# otherwise the codec patches won't be hooked before the PCI probe
|
||||
|
@ -414,7 +414,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_parse_pin_defcfg);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_parse_pin_defcfg);
|
||||
|
||||
int snd_hda_get_input_pin_attr(unsigned int def_conf)
|
||||
{
|
||||
@ -435,7 +435,7 @@ int snd_hda_get_input_pin_attr(unsigned int def_conf)
|
||||
return INPUT_PIN_ATTR_FRONT;
|
||||
return INPUT_PIN_ATTR_NORMAL;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_get_input_pin_attr);
|
||||
|
||||
/**
|
||||
* hda_get_input_pin_label - Give a label for the given input pin
|
||||
@ -547,7 +547,7 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec,
|
||||
cfg->inputs[input].pin,
|
||||
has_multiple_pins);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label);
|
||||
EXPORT_SYMBOL_GPL(hda_get_autocfg_input_label);
|
||||
|
||||
/* return the position of NID in the list, or -1 if not found */
|
||||
static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
|
||||
@ -721,7 +721,7 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
|
||||
strlcpy(label, name, maxlen);
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_get_pin_label);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_get_pin_label);
|
||||
|
||||
int snd_hda_add_verbs(struct hda_codec *codec,
|
||||
const struct hda_verb *list)
|
||||
@ -733,7 +733,7 @@ int snd_hda_add_verbs(struct hda_codec *codec,
|
||||
*v = list;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_add_verbs);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_add_verbs);
|
||||
|
||||
void snd_hda_apply_verbs(struct hda_codec *codec)
|
||||
{
|
||||
@ -743,7 +743,7 @@ void snd_hda_apply_verbs(struct hda_codec *codec)
|
||||
snd_hda_sequence_write(codec, *v);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_apply_verbs);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_apply_verbs);
|
||||
|
||||
void snd_hda_apply_pincfgs(struct hda_codec *codec,
|
||||
const struct hda_pintbl *cfg)
|
||||
@ -751,7 +751,7 @@ void snd_hda_apply_pincfgs(struct hda_codec *codec,
|
||||
for (; cfg->nid; cfg++)
|
||||
snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_apply_pincfgs);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_apply_pincfgs);
|
||||
|
||||
static void set_pin_targets(struct hda_codec *codec,
|
||||
const struct hda_pintbl *cfg)
|
||||
@ -822,7 +822,7 @@ void snd_hda_apply_fixup(struct hda_codec *codec, int action)
|
||||
if (codec->fixup_list)
|
||||
apply_fixup(codec, codec->fixup_id, action, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_apply_fixup);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_apply_fixup);
|
||||
|
||||
void snd_hda_pick_fixup(struct hda_codec *codec,
|
||||
const struct hda_model_fixup *models,
|
||||
@ -880,4 +880,4 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
|
||||
codec->fixup_name = name;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_pick_fixup);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_pick_fixup);
|
||||
|
@ -194,7 +194,7 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_enable_beep_device);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_enable_beep_device);
|
||||
|
||||
int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
|
||||
{
|
||||
@ -231,7 +231,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_attach_beep_device);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_attach_beep_device);
|
||||
|
||||
void snd_hda_detach_beep_device(struct hda_codec *codec)
|
||||
{
|
||||
@ -243,7 +243,7 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
|
||||
kfree(beep);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_detach_beep_device);
|
||||
|
||||
static bool ctl_has_mute(struct snd_kcontrol *kcontrol)
|
||||
{
|
||||
@ -265,7 +265,7 @@ int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol,
|
||||
}
|
||||
return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get_beep);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_get_beep);
|
||||
|
||||
int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
@ -288,4 +288,4 @@ int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
|
||||
return 0;
|
||||
return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_put_beep);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,552 +25,7 @@
|
||||
#include <sound/control.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/hwdep.h>
|
||||
|
||||
/*
|
||||
* nodes
|
||||
*/
|
||||
#define AC_NODE_ROOT 0x00
|
||||
|
||||
/*
|
||||
* function group types
|
||||
*/
|
||||
enum {
|
||||
AC_GRP_AUDIO_FUNCTION = 0x01,
|
||||
AC_GRP_MODEM_FUNCTION = 0x02,
|
||||
};
|
||||
|
||||
/*
|
||||
* widget types
|
||||
*/
|
||||
enum {
|
||||
AC_WID_AUD_OUT, /* Audio Out */
|
||||
AC_WID_AUD_IN, /* Audio In */
|
||||
AC_WID_AUD_MIX, /* Audio Mixer */
|
||||
AC_WID_AUD_SEL, /* Audio Selector */
|
||||
AC_WID_PIN, /* Pin Complex */
|
||||
AC_WID_POWER, /* Power */
|
||||
AC_WID_VOL_KNB, /* Volume Knob */
|
||||
AC_WID_BEEP, /* Beep Generator */
|
||||
AC_WID_VENDOR = 0x0f /* Vendor specific */
|
||||
};
|
||||
|
||||
/*
|
||||
* GET verbs
|
||||
*/
|
||||
#define AC_VERB_GET_STREAM_FORMAT 0x0a00
|
||||
#define AC_VERB_GET_AMP_GAIN_MUTE 0x0b00
|
||||
#define AC_VERB_GET_PROC_COEF 0x0c00
|
||||
#define AC_VERB_GET_COEF_INDEX 0x0d00
|
||||
#define AC_VERB_PARAMETERS 0x0f00
|
||||
#define AC_VERB_GET_CONNECT_SEL 0x0f01
|
||||
#define AC_VERB_GET_CONNECT_LIST 0x0f02
|
||||
#define AC_VERB_GET_PROC_STATE 0x0f03
|
||||
#define AC_VERB_GET_SDI_SELECT 0x0f04
|
||||
#define AC_VERB_GET_POWER_STATE 0x0f05
|
||||
#define AC_VERB_GET_CONV 0x0f06
|
||||
#define AC_VERB_GET_PIN_WIDGET_CONTROL 0x0f07
|
||||
#define AC_VERB_GET_UNSOLICITED_RESPONSE 0x0f08
|
||||
#define AC_VERB_GET_PIN_SENSE 0x0f09
|
||||
#define AC_VERB_GET_BEEP_CONTROL 0x0f0a
|
||||
#define AC_VERB_GET_EAPD_BTLENABLE 0x0f0c
|
||||
#define AC_VERB_GET_DIGI_CONVERT_1 0x0f0d
|
||||
#define AC_VERB_GET_DIGI_CONVERT_2 0x0f0e /* unused */
|
||||
#define AC_VERB_GET_VOLUME_KNOB_CONTROL 0x0f0f
|
||||
/* f10-f1a: GPIO */
|
||||
#define AC_VERB_GET_GPIO_DATA 0x0f15
|
||||
#define AC_VERB_GET_GPIO_MASK 0x0f16
|
||||
#define AC_VERB_GET_GPIO_DIRECTION 0x0f17
|
||||
#define AC_VERB_GET_GPIO_WAKE_MASK 0x0f18
|
||||
#define AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK 0x0f19
|
||||
#define AC_VERB_GET_GPIO_STICKY_MASK 0x0f1a
|
||||
#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c
|
||||
/* f20: AFG/MFG */
|
||||
#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20
|
||||
#define AC_VERB_GET_CVT_CHAN_COUNT 0x0f2d
|
||||
#define AC_VERB_GET_HDMI_DIP_SIZE 0x0f2e
|
||||
#define AC_VERB_GET_HDMI_ELDD 0x0f2f
|
||||
#define AC_VERB_GET_HDMI_DIP_INDEX 0x0f30
|
||||
#define AC_VERB_GET_HDMI_DIP_DATA 0x0f31
|
||||
#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32
|
||||
#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33
|
||||
#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34
|
||||
#define AC_VERB_GET_DEVICE_SEL 0xf35
|
||||
#define AC_VERB_GET_DEVICE_LIST 0xf36
|
||||
|
||||
/*
|
||||
* SET verbs
|
||||
*/
|
||||
#define AC_VERB_SET_STREAM_FORMAT 0x200
|
||||
#define AC_VERB_SET_AMP_GAIN_MUTE 0x300
|
||||
#define AC_VERB_SET_PROC_COEF 0x400
|
||||
#define AC_VERB_SET_COEF_INDEX 0x500
|
||||
#define AC_VERB_SET_CONNECT_SEL 0x701
|
||||
#define AC_VERB_SET_PROC_STATE 0x703
|
||||
#define AC_VERB_SET_SDI_SELECT 0x704
|
||||
#define AC_VERB_SET_POWER_STATE 0x705
|
||||
#define AC_VERB_SET_CHANNEL_STREAMID 0x706
|
||||
#define AC_VERB_SET_PIN_WIDGET_CONTROL 0x707
|
||||
#define AC_VERB_SET_UNSOLICITED_ENABLE 0x708
|
||||
#define AC_VERB_SET_PIN_SENSE 0x709
|
||||
#define AC_VERB_SET_BEEP_CONTROL 0x70a
|
||||
#define AC_VERB_SET_EAPD_BTLENABLE 0x70c
|
||||
#define AC_VERB_SET_DIGI_CONVERT_1 0x70d
|
||||
#define AC_VERB_SET_DIGI_CONVERT_2 0x70e
|
||||
#define AC_VERB_SET_VOLUME_KNOB_CONTROL 0x70f
|
||||
#define AC_VERB_SET_GPIO_DATA 0x715
|
||||
#define AC_VERB_SET_GPIO_MASK 0x716
|
||||
#define AC_VERB_SET_GPIO_DIRECTION 0x717
|
||||
#define AC_VERB_SET_GPIO_WAKE_MASK 0x718
|
||||
#define AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK 0x719
|
||||
#define AC_VERB_SET_GPIO_STICKY_MASK 0x71a
|
||||
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 0x71c
|
||||
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d
|
||||
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e
|
||||
#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3 0x71f
|
||||
#define AC_VERB_SET_EAPD 0x788
|
||||
#define AC_VERB_SET_CODEC_RESET 0x7ff
|
||||
#define AC_VERB_SET_CVT_CHAN_COUNT 0x72d
|
||||
#define AC_VERB_SET_HDMI_DIP_INDEX 0x730
|
||||
#define AC_VERB_SET_HDMI_DIP_DATA 0x731
|
||||
#define AC_VERB_SET_HDMI_DIP_XMIT 0x732
|
||||
#define AC_VERB_SET_HDMI_CP_CTRL 0x733
|
||||
#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734
|
||||
#define AC_VERB_SET_DEVICE_SEL 0x735
|
||||
|
||||
/*
|
||||
* Parameter IDs
|
||||
*/
|
||||
#define AC_PAR_VENDOR_ID 0x00
|
||||
#define AC_PAR_SUBSYSTEM_ID 0x01
|
||||
#define AC_PAR_REV_ID 0x02
|
||||
#define AC_PAR_NODE_COUNT 0x04
|
||||
#define AC_PAR_FUNCTION_TYPE 0x05
|
||||
#define AC_PAR_AUDIO_FG_CAP 0x08
|
||||
#define AC_PAR_AUDIO_WIDGET_CAP 0x09
|
||||
#define AC_PAR_PCM 0x0a
|
||||
#define AC_PAR_STREAM 0x0b
|
||||
#define AC_PAR_PIN_CAP 0x0c
|
||||
#define AC_PAR_AMP_IN_CAP 0x0d
|
||||
#define AC_PAR_CONNLIST_LEN 0x0e
|
||||
#define AC_PAR_POWER_STATE 0x0f
|
||||
#define AC_PAR_PROC_CAP 0x10
|
||||
#define AC_PAR_GPIO_CAP 0x11
|
||||
#define AC_PAR_AMP_OUT_CAP 0x12
|
||||
#define AC_PAR_VOL_KNB_CAP 0x13
|
||||
#define AC_PAR_DEVLIST_LEN 0x15
|
||||
#define AC_PAR_HDMI_LPCM_CAP 0x20
|
||||
|
||||
/*
|
||||
* AC_VERB_PARAMETERS results (32bit)
|
||||
*/
|
||||
|
||||
/* Function Group Type */
|
||||
#define AC_FGT_TYPE (0xff<<0)
|
||||
#define AC_FGT_TYPE_SHIFT 0
|
||||
#define AC_FGT_UNSOL_CAP (1<<8)
|
||||
|
||||
/* Audio Function Group Capabilities */
|
||||
#define AC_AFG_OUT_DELAY (0xf<<0)
|
||||
#define AC_AFG_IN_DELAY (0xf<<8)
|
||||
#define AC_AFG_BEEP_GEN (1<<16)
|
||||
|
||||
/* Audio Widget Capabilities */
|
||||
#define AC_WCAP_STEREO (1<<0) /* stereo I/O */
|
||||
#define AC_WCAP_IN_AMP (1<<1) /* AMP-in present */
|
||||
#define AC_WCAP_OUT_AMP (1<<2) /* AMP-out present */
|
||||
#define AC_WCAP_AMP_OVRD (1<<3) /* AMP-parameter override */
|
||||
#define AC_WCAP_FORMAT_OVRD (1<<4) /* format override */
|
||||
#define AC_WCAP_STRIPE (1<<5) /* stripe */
|
||||
#define AC_WCAP_PROC_WID (1<<6) /* Proc Widget */
|
||||
#define AC_WCAP_UNSOL_CAP (1<<7) /* Unsol capable */
|
||||
#define AC_WCAP_CONN_LIST (1<<8) /* connection list */
|
||||
#define AC_WCAP_DIGITAL (1<<9) /* digital I/O */
|
||||
#define AC_WCAP_POWER (1<<10) /* power control */
|
||||
#define AC_WCAP_LR_SWAP (1<<11) /* L/R swap */
|
||||
#define AC_WCAP_CP_CAPS (1<<12) /* content protection */
|
||||
#define AC_WCAP_CHAN_CNT_EXT (7<<13) /* channel count ext */
|
||||
#define AC_WCAP_DELAY (0xf<<16)
|
||||
#define AC_WCAP_DELAY_SHIFT 16
|
||||
#define AC_WCAP_TYPE (0xf<<20)
|
||||
#define AC_WCAP_TYPE_SHIFT 20
|
||||
|
||||
/* supported PCM rates and bits */
|
||||
#define AC_SUPPCM_RATES (0xfff << 0)
|
||||
#define AC_SUPPCM_BITS_8 (1<<16)
|
||||
#define AC_SUPPCM_BITS_16 (1<<17)
|
||||
#define AC_SUPPCM_BITS_20 (1<<18)
|
||||
#define AC_SUPPCM_BITS_24 (1<<19)
|
||||
#define AC_SUPPCM_BITS_32 (1<<20)
|
||||
|
||||
/* supported PCM stream format */
|
||||
#define AC_SUPFMT_PCM (1<<0)
|
||||
#define AC_SUPFMT_FLOAT32 (1<<1)
|
||||
#define AC_SUPFMT_AC3 (1<<2)
|
||||
|
||||
/* GP I/O count */
|
||||
#define AC_GPIO_IO_COUNT (0xff<<0)
|
||||
#define AC_GPIO_O_COUNT (0xff<<8)
|
||||
#define AC_GPIO_O_COUNT_SHIFT 8
|
||||
#define AC_GPIO_I_COUNT (0xff<<16)
|
||||
#define AC_GPIO_I_COUNT_SHIFT 16
|
||||
#define AC_GPIO_UNSOLICITED (1<<30)
|
||||
#define AC_GPIO_WAKE (1<<31)
|
||||
|
||||
/* Converter stream, channel */
|
||||
#define AC_CONV_CHANNEL (0xf<<0)
|
||||
#define AC_CONV_STREAM (0xf<<4)
|
||||
#define AC_CONV_STREAM_SHIFT 4
|
||||
|
||||
/* Input converter SDI select */
|
||||
#define AC_SDI_SELECT (0xf<<0)
|
||||
|
||||
/* stream format id */
|
||||
#define AC_FMT_CHAN_SHIFT 0
|
||||
#define AC_FMT_CHAN_MASK (0x0f << 0)
|
||||
#define AC_FMT_BITS_SHIFT 4
|
||||
#define AC_FMT_BITS_MASK (7 << 4)
|
||||
#define AC_FMT_BITS_8 (0 << 4)
|
||||
#define AC_FMT_BITS_16 (1 << 4)
|
||||
#define AC_FMT_BITS_20 (2 << 4)
|
||||
#define AC_FMT_BITS_24 (3 << 4)
|
||||
#define AC_FMT_BITS_32 (4 << 4)
|
||||
#define AC_FMT_DIV_SHIFT 8
|
||||
#define AC_FMT_DIV_MASK (7 << 8)
|
||||
#define AC_FMT_MULT_SHIFT 11
|
||||
#define AC_FMT_MULT_MASK (7 << 11)
|
||||
#define AC_FMT_BASE_SHIFT 14
|
||||
#define AC_FMT_BASE_48K (0 << 14)
|
||||
#define AC_FMT_BASE_44K (1 << 14)
|
||||
#define AC_FMT_TYPE_SHIFT 15
|
||||
#define AC_FMT_TYPE_PCM (0 << 15)
|
||||
#define AC_FMT_TYPE_NON_PCM (1 << 15)
|
||||
|
||||
/* Unsolicited response control */
|
||||
#define AC_UNSOL_TAG (0x3f<<0)
|
||||
#define AC_UNSOL_ENABLED (1<<7)
|
||||
#define AC_USRSP_EN AC_UNSOL_ENABLED
|
||||
|
||||
/* Unsolicited responses */
|
||||
#define AC_UNSOL_RES_TAG (0x3f<<26)
|
||||
#define AC_UNSOL_RES_TAG_SHIFT 26
|
||||
#define AC_UNSOL_RES_SUBTAG (0x1f<<21)
|
||||
#define AC_UNSOL_RES_SUBTAG_SHIFT 21
|
||||
#define AC_UNSOL_RES_DE (0x3f<<15) /* Device Entry
|
||||
* (for DP1.2 MST)
|
||||
*/
|
||||
#define AC_UNSOL_RES_DE_SHIFT 15
|
||||
#define AC_UNSOL_RES_IA (1<<2) /* Inactive (for DP1.2 MST) */
|
||||
#define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */
|
||||
#define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */
|
||||
#define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */
|
||||
#define AC_UNSOL_RES_CP_READY (1<<0) /* content protection */
|
||||
|
||||
/* Pin widget capabilies */
|
||||
#define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */
|
||||
#define AC_PINCAP_TRIG_REQ (1<<1) /* trigger required */
|
||||
#define AC_PINCAP_PRES_DETECT (1<<2) /* presence detect capable */
|
||||
#define AC_PINCAP_HP_DRV (1<<3) /* headphone drive capable */
|
||||
#define AC_PINCAP_OUT (1<<4) /* output capable */
|
||||
#define AC_PINCAP_IN (1<<5) /* input capable */
|
||||
#define AC_PINCAP_BALANCE (1<<6) /* balanced I/O capable */
|
||||
/* Note: This LR_SWAP pincap is defined in the Realtek ALC883 specification,
|
||||
* but is marked reserved in the Intel HDA specification.
|
||||
*/
|
||||
#define AC_PINCAP_LR_SWAP (1<<7) /* L/R swap */
|
||||
/* Note: The same bit as LR_SWAP is newly defined as HDMI capability
|
||||
* in HD-audio specification
|
||||
*/
|
||||
#define AC_PINCAP_HDMI (1<<7) /* HDMI pin */
|
||||
#define AC_PINCAP_DP (1<<24) /* DisplayPort pin, can
|
||||
* coexist with AC_PINCAP_HDMI
|
||||
*/
|
||||
#define AC_PINCAP_VREF (0x37<<8)
|
||||
#define AC_PINCAP_VREF_SHIFT 8
|
||||
#define AC_PINCAP_EAPD (1<<16) /* EAPD capable */
|
||||
#define AC_PINCAP_HBR (1<<27) /* High Bit Rate */
|
||||
/* Vref status (used in pin cap) */
|
||||
#define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */
|
||||
#define AC_PINCAP_VREF_50 (1<<1) /* 50% */
|
||||
#define AC_PINCAP_VREF_GRD (1<<2) /* ground */
|
||||
#define AC_PINCAP_VREF_80 (1<<4) /* 80% */
|
||||
#define AC_PINCAP_VREF_100 (1<<5) /* 100% */
|
||||
|
||||
/* Amplifier capabilities */
|
||||
#define AC_AMPCAP_OFFSET (0x7f<<0) /* 0dB offset */
|
||||
#define AC_AMPCAP_OFFSET_SHIFT 0
|
||||
#define AC_AMPCAP_NUM_STEPS (0x7f<<8) /* number of steps */
|
||||
#define AC_AMPCAP_NUM_STEPS_SHIFT 8
|
||||
#define AC_AMPCAP_STEP_SIZE (0x7f<<16) /* step size 0-32dB
|
||||
* in 0.25dB
|
||||
*/
|
||||
#define AC_AMPCAP_STEP_SIZE_SHIFT 16
|
||||
#define AC_AMPCAP_MUTE (1<<31) /* mute capable */
|
||||
#define AC_AMPCAP_MUTE_SHIFT 31
|
||||
|
||||
/* driver-specific amp-caps: using bits 24-30 */
|
||||
#define AC_AMPCAP_MIN_MUTE (1 << 30) /* min-volume = mute */
|
||||
|
||||
/* Connection list */
|
||||
#define AC_CLIST_LENGTH (0x7f<<0)
|
||||
#define AC_CLIST_LONG (1<<7)
|
||||
|
||||
/* Supported power status */
|
||||
#define AC_PWRST_D0SUP (1<<0)
|
||||
#define AC_PWRST_D1SUP (1<<1)
|
||||
#define AC_PWRST_D2SUP (1<<2)
|
||||
#define AC_PWRST_D3SUP (1<<3)
|
||||
#define AC_PWRST_D3COLDSUP (1<<4)
|
||||
#define AC_PWRST_S3D3COLDSUP (1<<29)
|
||||
#define AC_PWRST_CLKSTOP (1<<30)
|
||||
#define AC_PWRST_EPSS (1U<<31)
|
||||
|
||||
/* Power state values */
|
||||
#define AC_PWRST_SETTING (0xf<<0)
|
||||
#define AC_PWRST_ACTUAL (0xf<<4)
|
||||
#define AC_PWRST_ACTUAL_SHIFT 4
|
||||
#define AC_PWRST_D0 0x00
|
||||
#define AC_PWRST_D1 0x01
|
||||
#define AC_PWRST_D2 0x02
|
||||
#define AC_PWRST_D3 0x03
|
||||
#define AC_PWRST_ERROR (1<<8)
|
||||
#define AC_PWRST_CLK_STOP_OK (1<<9)
|
||||
#define AC_PWRST_SETTING_RESET (1<<10)
|
||||
|
||||
/* Processing capabilies */
|
||||
#define AC_PCAP_BENIGN (1<<0)
|
||||
#define AC_PCAP_NUM_COEF (0xff<<8)
|
||||
#define AC_PCAP_NUM_COEF_SHIFT 8
|
||||
|
||||
/* Volume knobs capabilities */
|
||||
#define AC_KNBCAP_NUM_STEPS (0x7f<<0)
|
||||
#define AC_KNBCAP_DELTA (1<<7)
|
||||
|
||||
/* HDMI LPCM capabilities */
|
||||
#define AC_LPCMCAP_48K_CP_CHNS (0x0f<<0) /* max channels w/ CP-on */
|
||||
#define AC_LPCMCAP_48K_NO_CHNS (0x0f<<4) /* max channels w/o CP-on */
|
||||
#define AC_LPCMCAP_48K_20BIT (1<<8) /* 20b bitrate supported */
|
||||
#define AC_LPCMCAP_48K_24BIT (1<<9) /* 24b bitrate supported */
|
||||
#define AC_LPCMCAP_96K_CP_CHNS (0x0f<<10) /* max channels w/ CP-on */
|
||||
#define AC_LPCMCAP_96K_NO_CHNS (0x0f<<14) /* max channels w/o CP-on */
|
||||
#define AC_LPCMCAP_96K_20BIT (1<<18) /* 20b bitrate supported */
|
||||
#define AC_LPCMCAP_96K_24BIT (1<<19) /* 24b bitrate supported */
|
||||
#define AC_LPCMCAP_192K_CP_CHNS (0x0f<<20) /* max channels w/ CP-on */
|
||||
#define AC_LPCMCAP_192K_NO_CHNS (0x0f<<24) /* max channels w/o CP-on */
|
||||
#define AC_LPCMCAP_192K_20BIT (1<<28) /* 20b bitrate supported */
|
||||
#define AC_LPCMCAP_192K_24BIT (1<<29) /* 24b bitrate supported */
|
||||
#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */
|
||||
#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */
|
||||
|
||||
/* Display pin's device list length */
|
||||
#define AC_DEV_LIST_LEN_MASK 0x3f
|
||||
#define AC_MAX_DEV_LIST_LEN 64
|
||||
|
||||
/*
|
||||
* Control Parameters
|
||||
*/
|
||||
|
||||
/* Amp gain/mute */
|
||||
#define AC_AMP_MUTE (1<<7)
|
||||
#define AC_AMP_GAIN (0x7f)
|
||||
#define AC_AMP_GET_INDEX (0xf<<0)
|
||||
|
||||
#define AC_AMP_GET_LEFT (1<<13)
|
||||
#define AC_AMP_GET_RIGHT (0<<13)
|
||||
#define AC_AMP_GET_OUTPUT (1<<15)
|
||||
#define AC_AMP_GET_INPUT (0<<15)
|
||||
|
||||
#define AC_AMP_SET_INDEX (0xf<<8)
|
||||
#define AC_AMP_SET_INDEX_SHIFT 8
|
||||
#define AC_AMP_SET_RIGHT (1<<12)
|
||||
#define AC_AMP_SET_LEFT (1<<13)
|
||||
#define AC_AMP_SET_INPUT (1<<14)
|
||||
#define AC_AMP_SET_OUTPUT (1<<15)
|
||||
|
||||
/* DIGITAL1 bits */
|
||||
#define AC_DIG1_ENABLE (1<<0)
|
||||
#define AC_DIG1_V (1<<1)
|
||||
#define AC_DIG1_VCFG (1<<2)
|
||||
#define AC_DIG1_EMPHASIS (1<<3)
|
||||
#define AC_DIG1_COPYRIGHT (1<<4)
|
||||
#define AC_DIG1_NONAUDIO (1<<5)
|
||||
#define AC_DIG1_PROFESSIONAL (1<<6)
|
||||
#define AC_DIG1_LEVEL (1<<7)
|
||||
|
||||
/* DIGITAL2 bits */
|
||||
#define AC_DIG2_CC (0x7f<<0)
|
||||
|
||||
/* DIGITAL3 bits */
|
||||
#define AC_DIG3_ICT (0xf<<0)
|
||||
#define AC_DIG3_KAE (1<<7)
|
||||
|
||||
/* Pin widget control - 8bit */
|
||||
#define AC_PINCTL_EPT (0x3<<0)
|
||||
#define AC_PINCTL_EPT_NATIVE 0
|
||||
#define AC_PINCTL_EPT_HBR 3
|
||||
#define AC_PINCTL_VREFEN (0x7<<0)
|
||||
#define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */
|
||||
#define AC_PINCTL_VREF_50 1 /* 50% */
|
||||
#define AC_PINCTL_VREF_GRD 2 /* ground */
|
||||
#define AC_PINCTL_VREF_80 4 /* 80% */
|
||||
#define AC_PINCTL_VREF_100 5 /* 100% */
|
||||
#define AC_PINCTL_IN_EN (1<<5)
|
||||
#define AC_PINCTL_OUT_EN (1<<6)
|
||||
#define AC_PINCTL_HP_EN (1<<7)
|
||||
|
||||
/* Pin sense - 32bit */
|
||||
#define AC_PINSENSE_IMPEDANCE_MASK (0x7fffffff)
|
||||
#define AC_PINSENSE_PRESENCE (1<<31)
|
||||
#define AC_PINSENSE_ELDV (1<<30) /* ELD valid (HDMI) */
|
||||
|
||||
/* EAPD/BTL enable - 32bit */
|
||||
#define AC_EAPDBTL_BALANCED (1<<0)
|
||||
#define AC_EAPDBTL_EAPD (1<<1)
|
||||
#define AC_EAPDBTL_LR_SWAP (1<<2)
|
||||
|
||||
/* HDMI ELD data */
|
||||
#define AC_ELDD_ELD_VALID (1<<31)
|
||||
#define AC_ELDD_ELD_DATA 0xff
|
||||
|
||||
/* HDMI DIP size */
|
||||
#define AC_DIPSIZE_ELD_BUF (1<<3) /* ELD buf size of packet size */
|
||||
#define AC_DIPSIZE_PACK_IDX (0x07<<0) /* packet index */
|
||||
|
||||
/* HDMI DIP index */
|
||||
#define AC_DIPIDX_PACK_IDX (0x07<<5) /* packet idnex */
|
||||
#define AC_DIPIDX_BYTE_IDX (0x1f<<0) /* byte index */
|
||||
|
||||
/* HDMI DIP xmit (transmit) control */
|
||||
#define AC_DIPXMIT_MASK (0x3<<6)
|
||||
#define AC_DIPXMIT_DISABLE (0x0<<6) /* disable xmit */
|
||||
#define AC_DIPXMIT_ONCE (0x2<<6) /* xmit once then disable */
|
||||
#define AC_DIPXMIT_BEST (0x3<<6) /* best effort */
|
||||
|
||||
/* HDMI content protection (CP) control */
|
||||
#define AC_CPCTRL_CES (1<<9) /* current encryption state */
|
||||
#define AC_CPCTRL_READY (1<<8) /* ready bit */
|
||||
#define AC_CPCTRL_SUBTAG (0x1f<<3) /* subtag for unsol-resp */
|
||||
#define AC_CPCTRL_STATE (3<<0) /* current CP request state */
|
||||
|
||||
/* Converter channel <-> HDMI slot mapping */
|
||||
#define AC_CVTMAP_HDMI_SLOT (0xf<<0) /* HDMI slot number */
|
||||
#define AC_CVTMAP_CHAN (0xf<<4) /* converter channel number */
|
||||
|
||||
/* configuration default - 32bit */
|
||||
#define AC_DEFCFG_SEQUENCE (0xf<<0)
|
||||
#define AC_DEFCFG_DEF_ASSOC (0xf<<4)
|
||||
#define AC_DEFCFG_ASSOC_SHIFT 4
|
||||
#define AC_DEFCFG_MISC (0xf<<8)
|
||||
#define AC_DEFCFG_MISC_SHIFT 8
|
||||
#define AC_DEFCFG_MISC_NO_PRESENCE (1<<0)
|
||||
#define AC_DEFCFG_COLOR (0xf<<12)
|
||||
#define AC_DEFCFG_COLOR_SHIFT 12
|
||||
#define AC_DEFCFG_CONN_TYPE (0xf<<16)
|
||||
#define AC_DEFCFG_CONN_TYPE_SHIFT 16
|
||||
#define AC_DEFCFG_DEVICE (0xf<<20)
|
||||
#define AC_DEFCFG_DEVICE_SHIFT 20
|
||||
#define AC_DEFCFG_LOCATION (0x3f<<24)
|
||||
#define AC_DEFCFG_LOCATION_SHIFT 24
|
||||
#define AC_DEFCFG_PORT_CONN (0x3<<30)
|
||||
#define AC_DEFCFG_PORT_CONN_SHIFT 30
|
||||
|
||||
/* Display pin's device list entry */
|
||||
#define AC_DE_PD (1<<0)
|
||||
#define AC_DE_ELDV (1<<1)
|
||||
#define AC_DE_IA (1<<2)
|
||||
|
||||
/* device device types (0x0-0xf) */
|
||||
enum {
|
||||
AC_JACK_LINE_OUT,
|
||||
AC_JACK_SPEAKER,
|
||||
AC_JACK_HP_OUT,
|
||||
AC_JACK_CD,
|
||||
AC_JACK_SPDIF_OUT,
|
||||
AC_JACK_DIG_OTHER_OUT,
|
||||
AC_JACK_MODEM_LINE_SIDE,
|
||||
AC_JACK_MODEM_HAND_SIDE,
|
||||
AC_JACK_LINE_IN,
|
||||
AC_JACK_AUX,
|
||||
AC_JACK_MIC_IN,
|
||||
AC_JACK_TELEPHONY,
|
||||
AC_JACK_SPDIF_IN,
|
||||
AC_JACK_DIG_OTHER_IN,
|
||||
AC_JACK_OTHER = 0xf,
|
||||
};
|
||||
|
||||
/* jack connection types (0x0-0xf) */
|
||||
enum {
|
||||
AC_JACK_CONN_UNKNOWN,
|
||||
AC_JACK_CONN_1_8,
|
||||
AC_JACK_CONN_1_4,
|
||||
AC_JACK_CONN_ATAPI,
|
||||
AC_JACK_CONN_RCA,
|
||||
AC_JACK_CONN_OPTICAL,
|
||||
AC_JACK_CONN_OTHER_DIGITAL,
|
||||
AC_JACK_CONN_OTHER_ANALOG,
|
||||
AC_JACK_CONN_DIN,
|
||||
AC_JACK_CONN_XLR,
|
||||
AC_JACK_CONN_RJ11,
|
||||
AC_JACK_CONN_COMB,
|
||||
AC_JACK_CONN_OTHER = 0xf,
|
||||
};
|
||||
|
||||
/* jack colors (0x0-0xf) */
|
||||
enum {
|
||||
AC_JACK_COLOR_UNKNOWN,
|
||||
AC_JACK_COLOR_BLACK,
|
||||
AC_JACK_COLOR_GREY,
|
||||
AC_JACK_COLOR_BLUE,
|
||||
AC_JACK_COLOR_GREEN,
|
||||
AC_JACK_COLOR_RED,
|
||||
AC_JACK_COLOR_ORANGE,
|
||||
AC_JACK_COLOR_YELLOW,
|
||||
AC_JACK_COLOR_PURPLE,
|
||||
AC_JACK_COLOR_PINK,
|
||||
AC_JACK_COLOR_WHITE = 0xe,
|
||||
AC_JACK_COLOR_OTHER,
|
||||
};
|
||||
|
||||
/* Jack location (0x0-0x3f) */
|
||||
/* common case */
|
||||
enum {
|
||||
AC_JACK_LOC_NONE,
|
||||
AC_JACK_LOC_REAR,
|
||||
AC_JACK_LOC_FRONT,
|
||||
AC_JACK_LOC_LEFT,
|
||||
AC_JACK_LOC_RIGHT,
|
||||
AC_JACK_LOC_TOP,
|
||||
AC_JACK_LOC_BOTTOM,
|
||||
};
|
||||
/* bits 4-5 */
|
||||
enum {
|
||||
AC_JACK_LOC_EXTERNAL = 0x00,
|
||||
AC_JACK_LOC_INTERNAL = 0x10,
|
||||
AC_JACK_LOC_SEPARATE = 0x20,
|
||||
AC_JACK_LOC_OTHER = 0x30,
|
||||
};
|
||||
enum {
|
||||
/* external on primary chasis */
|
||||
AC_JACK_LOC_REAR_PANEL = 0x07,
|
||||
AC_JACK_LOC_DRIVE_BAY,
|
||||
/* internal */
|
||||
AC_JACK_LOC_RISER = 0x17,
|
||||
AC_JACK_LOC_HDMI,
|
||||
AC_JACK_LOC_ATAPI,
|
||||
/* others */
|
||||
AC_JACK_LOC_MOBILE_IN = 0x37,
|
||||
AC_JACK_LOC_MOBILE_OUT,
|
||||
};
|
||||
|
||||
/* Port connectivity (0-3) */
|
||||
enum {
|
||||
AC_JACK_PORT_COMPLEX,
|
||||
AC_JACK_PORT_NONE,
|
||||
AC_JACK_PORT_FIXED,
|
||||
AC_JACK_PORT_BOTH,
|
||||
};
|
||||
|
||||
/* max. codec address */
|
||||
#define HDA_MAX_CODEC_ADDRESS 0x0f
|
||||
#include <sound/hda_verbs.h>
|
||||
|
||||
/*
|
||||
* generic arrays
|
||||
@ -673,6 +128,7 @@ struct hda_bus {
|
||||
|
||||
/* codec linked list */
|
||||
struct list_head codec_list;
|
||||
unsigned int num_codecs;
|
||||
/* link caddr -> codec */
|
||||
struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1];
|
||||
|
||||
@ -834,6 +290,7 @@ struct hda_codec {
|
||||
/* detected preset */
|
||||
const struct hda_codec_preset *preset;
|
||||
struct module *owner;
|
||||
int (*parser)(struct hda_codec *codec);
|
||||
const char *vendor_name; /* codec vendor name */
|
||||
const char *chip_name; /* codec chip name */
|
||||
const char *modelname; /* model name for preset */
|
||||
@ -907,7 +364,7 @@ struct hda_codec {
|
||||
#ifdef CONFIG_PM
|
||||
unsigned int power_on :1; /* current (global) power-state */
|
||||
unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */
|
||||
unsigned int pm_down_notified:1; /* PM notified to controller */
|
||||
unsigned int pm_up_notified:1; /* PM notified to controller */
|
||||
unsigned int in_pm:1; /* suspend/resume being performed */
|
||||
int power_transition; /* power-state in transition */
|
||||
int power_count; /* current (global) power refcount */
|
||||
@ -936,6 +393,8 @@ struct hda_codec {
|
||||
struct snd_array jacks;
|
||||
#endif
|
||||
|
||||
int depop_delay; /* depop delay in ms, -1 for default delay time */
|
||||
|
||||
/* fix-up list */
|
||||
int fixup_id;
|
||||
const struct hda_fixup *fixup_list;
|
||||
@ -1222,19 +681,6 @@ snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec,
|
||||
struct snd_dma_buffer *dmab) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Codec modularization
|
||||
*/
|
||||
|
||||
/* Export symbols only for communication with codec drivers;
|
||||
* When built in kernel, all HD-audio drivers are supposed to be statically
|
||||
* linked to the kernel. Thus, the symbols don't have to (or shouldn't) be
|
||||
* exported unless it's built as a module.
|
||||
*/
|
||||
#ifdef MODULE
|
||||
#define EXPORT_SYMBOL_HDA(sym) EXPORT_SYMBOL_GPL(sym)
|
||||
#else
|
||||
#define EXPORT_SYMBOL_HDA(sym)
|
||||
#endif
|
||||
|
||||
#endif /* __SOUND_HDA_CODEC_H */
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/module.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/jack.h>
|
||||
#include "hda_codec.h"
|
||||
@ -47,7 +48,7 @@ int snd_hda_gen_spec_init(struct hda_gen_spec *spec)
|
||||
mutex_init(&spec->pcm_mutex);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_spec_init);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_spec_init);
|
||||
|
||||
struct snd_kcontrol_new *
|
||||
snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name,
|
||||
@ -65,7 +66,7 @@ snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name,
|
||||
return NULL;
|
||||
return knew;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_add_kctl);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_add_kctl);
|
||||
|
||||
static void free_kctls(struct hda_gen_spec *spec)
|
||||
{
|
||||
@ -86,7 +87,7 @@ void snd_hda_gen_spec_free(struct hda_gen_spec *spec)
|
||||
snd_array_free(&spec->paths);
|
||||
snd_array_free(&spec->loopback_list);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_spec_free);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_spec_free);
|
||||
|
||||
/*
|
||||
* store user hints
|
||||
@ -266,7 +267,7 @@ struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec,
|
||||
{
|
||||
return get_nid_path(codec, from_nid, to_nid, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_get_nid_path);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_get_nid_path);
|
||||
|
||||
/* get the index number corresponding to the path instance;
|
||||
* the index starts from 1, for easier checking the invalid value
|
||||
@ -284,7 +285,7 @@ int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path)
|
||||
return 0;
|
||||
return idx + 1;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_get_path_idx);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_get_path_idx);
|
||||
|
||||
/* get the path instance corresponding to the given index number */
|
||||
struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx)
|
||||
@ -295,7 +296,7 @@ struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx)
|
||||
return NULL;
|
||||
return snd_array_elem(&spec->paths, idx - 1);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_get_path_from_idx);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_get_path_from_idx);
|
||||
|
||||
/* check whether the given DAC is already found in any existing paths */
|
||||
static bool is_dac_already_used(struct hda_codec *codec, hda_nid_t nid)
|
||||
@ -432,7 +433,7 @@ bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid,
|
||||
}
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_parse_nid_path);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_parse_nid_path);
|
||||
|
||||
/*
|
||||
* parse the path between the given NIDs and add to the path list.
|
||||
@ -463,7 +464,7 @@ snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid,
|
||||
spec->paths.used--;
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_add_new_path);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_add_new_path);
|
||||
|
||||
/* clear the given path as invalid so that it won't be picked up later */
|
||||
static void invalidate_nid_path(struct hda_codec *codec, int idx)
|
||||
@ -773,7 +774,7 @@ void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path,
|
||||
if (enable)
|
||||
path->active = true;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_activate_path);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_activate_path);
|
||||
|
||||
/* if the given path is inactive, put widgets into D3 (only if suitable) */
|
||||
static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path)
|
||||
@ -1149,7 +1150,7 @@ const struct badness_table hda_main_out_badness = {
|
||||
.shared_clfe = BAD_SHARED_CLFE,
|
||||
.shared_surr_main = BAD_SHARED_SURROUND,
|
||||
};
|
||||
EXPORT_SYMBOL_HDA(hda_main_out_badness);
|
||||
EXPORT_SYMBOL_GPL(hda_main_out_badness);
|
||||
|
||||
const struct badness_table hda_extra_out_badness = {
|
||||
.no_primary_dac = BAD_NO_DAC,
|
||||
@ -1159,7 +1160,7 @@ const struct badness_table hda_extra_out_badness = {
|
||||
.shared_clfe = BAD_SHARED_EXTRA_SURROUND,
|
||||
.shared_surr_main = BAD_NO_EXTRA_SURR_DAC,
|
||||
};
|
||||
EXPORT_SYMBOL_HDA(hda_extra_out_badness);
|
||||
EXPORT_SYMBOL_GPL(hda_extra_out_badness);
|
||||
|
||||
/* get the DAC of the primary output corresponding to the given array index */
|
||||
static hda_nid_t get_primary_out(struct hda_codec *codec, int idx)
|
||||
@ -2857,9 +2858,11 @@ static bool look_for_mix_leaf_ctls(struct hda_codec *codec, hda_nid_t mix_nid,
|
||||
if (num_conns < idx)
|
||||
return false;
|
||||
nid = list[idx];
|
||||
if (!*mix_val && nid_has_volume(codec, nid, HDA_OUTPUT))
|
||||
if (!*mix_val && nid_has_volume(codec, nid, HDA_OUTPUT) &&
|
||||
!is_ctl_associated(codec, nid, HDA_OUTPUT, 0, NID_PATH_VOL_CTL))
|
||||
*mix_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
|
||||
if (!*mute_val && nid_has_mute(codec, nid, HDA_OUTPUT))
|
||||
if (!*mute_val && nid_has_mute(codec, nid, HDA_OUTPUT) &&
|
||||
!is_ctl_associated(codec, nid, HDA_OUTPUT, 0, NID_PATH_MUTE_CTL))
|
||||
*mute_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
|
||||
|
||||
return *mix_val || *mute_val;
|
||||
@ -3053,6 +3056,8 @@ static int parse_capture_source(struct hda_codec *codec, hda_nid_t pin,
|
||||
spec->imux_pins[imux->num_items] = pin;
|
||||
snd_hda_add_imux_item(imux, label, cfg_idx, NULL);
|
||||
imux_added = true;
|
||||
if (spec->dyn_adc_switch)
|
||||
spec->dyn_adc_idx[imux_idx] = c;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3150,7 +3155,9 @@ static int create_input_ctls(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
if (mixer && spec->add_stereo_mix_input) {
|
||||
/* add stereo mix when explicitly enabled via hint */
|
||||
if (mixer && spec->add_stereo_mix_input &&
|
||||
snd_hda_get_bool_hint(codec, "add_stereo_mix_input") > 0) {
|
||||
err = parse_capture_source(codec, mixer, CFG_IDX_MIX, num_adcs,
|
||||
"Stereo Mix", 0);
|
||||
if (err < 0)
|
||||
@ -3916,7 +3923,7 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec)
|
||||
do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
|
||||
spec->autocfg.line_out_pins, paths, on);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_update_outputs);
|
||||
|
||||
static void call_update_outputs(struct hda_codec *codec)
|
||||
{
|
||||
@ -3949,7 +3956,7 @@ void snd_hda_gen_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
|
||||
return;
|
||||
call_update_outputs(codec);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_hp_automute);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute);
|
||||
|
||||
/* standard line-out-automute helper */
|
||||
void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
|
||||
@ -3969,7 +3976,7 @@ void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jac
|
||||
return;
|
||||
call_update_outputs(codec);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_line_automute);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute);
|
||||
|
||||
/* standard mic auto-switch helper */
|
||||
void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *jack)
|
||||
@ -3992,7 +3999,7 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja
|
||||
}
|
||||
mux_select(codec, 0, spec->am_entry[0].idx);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_mic_autoswitch);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_mic_autoswitch);
|
||||
|
||||
/* call appropriate hooks */
|
||||
static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
|
||||
@ -4305,11 +4312,11 @@ static int check_auto_mic_availability(struct hda_codec *codec)
|
||||
}
|
||||
|
||||
/* power_filter hook; make inactive widgets into power down */
|
||||
static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
|
||||
unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
|
||||
hda_nid_t nid,
|
||||
unsigned int power_state)
|
||||
{
|
||||
if (power_state != AC_PWRST_D0)
|
||||
if (power_state != AC_PWRST_D0 || nid == codec->afg)
|
||||
return power_state;
|
||||
if (get_wcaps_type(get_wcaps(codec, nid)) >= AC_WID_POWER)
|
||||
return power_state;
|
||||
@ -4317,6 +4324,7 @@ static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
|
||||
return power_state;
|
||||
return AC_PWRST_D3;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_path_power_filter);
|
||||
|
||||
/* mute all aamix inputs initially; parse up to the first leaves */
|
||||
static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix)
|
||||
@ -4374,7 +4382,8 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
|
||||
spec->no_analog = 1;
|
||||
goto dig_only;
|
||||
}
|
||||
return 0; /* can't find valid BIOS pin config */
|
||||
if (!cfg->num_inputs && !cfg->dig_in_pin)
|
||||
return 0; /* can't find valid BIOS pin config */
|
||||
}
|
||||
|
||||
if (!spec->no_primary_hp &&
|
||||
@ -4442,6 +4451,19 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* add stereo mix if available and not enabled yet */
|
||||
if (!spec->auto_mic && spec->mixer_nid &&
|
||||
spec->add_stereo_mix_input &&
|
||||
spec->input_mux.num_items > 1 &&
|
||||
snd_hda_get_bool_hint(codec, "add_stereo_mix_input") < 0) {
|
||||
err = parse_capture_source(codec, spec->mixer_nid,
|
||||
CFG_IDX_MIX, spec->num_all_adcs,
|
||||
"Stereo Mix", 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
err = create_capture_mixers(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
@ -4494,7 +4516,7 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
|
||||
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_parse_auto_config);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_parse_auto_config);
|
||||
|
||||
|
||||
/*
|
||||
@ -4576,7 +4598,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_build_controls);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_build_controls);
|
||||
|
||||
|
||||
/*
|
||||
@ -5109,7 +5131,7 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_build_pcms);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_build_pcms);
|
||||
|
||||
|
||||
/*
|
||||
@ -5183,6 +5205,23 @@ static void init_multi_io(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
static void init_aamix_paths(struct hda_codec *codec)
|
||||
{
|
||||
struct hda_gen_spec *spec = codec->spec;
|
||||
|
||||
if (!spec->have_aamix_ctl)
|
||||
return;
|
||||
update_aamix_paths(codec, spec->aamix_mode, spec->out_paths[0],
|
||||
spec->aamix_out_paths[0],
|
||||
spec->autocfg.line_out_type);
|
||||
update_aamix_paths(codec, spec->aamix_mode, spec->hp_paths[0],
|
||||
spec->aamix_out_paths[1],
|
||||
AUTO_PIN_HP_OUT);
|
||||
update_aamix_paths(codec, spec->aamix_mode, spec->speaker_paths[0],
|
||||
spec->aamix_out_paths[2],
|
||||
AUTO_PIN_SPEAKER_OUT);
|
||||
}
|
||||
|
||||
/* set up input pins and loopback paths */
|
||||
static void init_analog_input(struct hda_codec *codec)
|
||||
{
|
||||
@ -5285,6 +5324,7 @@ int snd_hda_gen_init(struct hda_codec *codec)
|
||||
init_multi_out(codec);
|
||||
init_extra_out(codec);
|
||||
init_multi_io(codec);
|
||||
init_aamix_paths(codec);
|
||||
init_analog_input(codec);
|
||||
init_input_src(codec);
|
||||
init_digital(codec);
|
||||
@ -5302,7 +5342,7 @@ int snd_hda_gen_init(struct hda_codec *codec)
|
||||
hda_call_check_power_status(codec, 0x01);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_init);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_init);
|
||||
|
||||
/*
|
||||
* free the generic spec;
|
||||
@ -5315,7 +5355,7 @@ void snd_hda_gen_free(struct hda_codec *codec)
|
||||
kfree(codec->spec);
|
||||
codec->spec = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_free);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_free);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
/*
|
||||
@ -5327,7 +5367,7 @@ int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid)
|
||||
struct hda_gen_spec *spec = codec->spec;
|
||||
return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_gen_check_power_status);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_check_power_status);
|
||||
#endif
|
||||
|
||||
|
||||
@ -5372,4 +5412,7 @@ int snd_hda_parse_generic_codec(struct hda_codec *codec)
|
||||
snd_hda_gen_free(codec);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_parse_generic_codec);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_parse_generic_codec);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Generic HD-audio codec parser");
|
||||
|
@ -335,5 +335,8 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec);
|
||||
#ifdef CONFIG_PM
|
||||
int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid);
|
||||
#endif
|
||||
unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
|
||||
hda_nid_t nid,
|
||||
unsigned int power_state);
|
||||
|
||||
#endif /* __SOUND_HDA_GENERIC_H */
|
||||
|
@ -616,7 +616,7 @@ const char *snd_hda_get_hint(struct hda_codec *codec, const char *key)
|
||||
struct hda_hint *hint = get_hint(codec, key);
|
||||
return hint ? hint->val : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_get_hint);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_get_hint);
|
||||
|
||||
int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
|
||||
{
|
||||
@ -642,7 +642,7 @@ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
|
||||
mutex_unlock(&codec->user_mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_get_bool_hint);
|
||||
|
||||
int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp)
|
||||
{
|
||||
@ -663,7 +663,7 @@ int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp)
|
||||
mutex_unlock(&codec->user_mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_get_int_hint);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_get_int_hint);
|
||||
#endif /* CONFIG_SND_HDA_RECONFIG */
|
||||
|
||||
#ifdef CONFIG_SND_HDA_PATCH_LOADER
|
||||
@ -762,20 +762,50 @@ DEFINE_PARSE_ID_MODE(revision_id);
|
||||
|
||||
struct hda_patch_item {
|
||||
const char *tag;
|
||||
const char *alias;
|
||||
void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
|
||||
int need_codec;
|
||||
};
|
||||
|
||||
static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
|
||||
[LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 },
|
||||
[LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 },
|
||||
[LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 },
|
||||
[LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 },
|
||||
[LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 },
|
||||
[LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 },
|
||||
[LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 },
|
||||
[LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 },
|
||||
[LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 },
|
||||
[LINE_MODE_CODEC] = {
|
||||
.tag = "[codec]",
|
||||
.parser = parse_codec_mode,
|
||||
},
|
||||
[LINE_MODE_MODEL] = {
|
||||
.tag = "[model]",
|
||||
.parser = parse_model_mode,
|
||||
},
|
||||
[LINE_MODE_VERB] = {
|
||||
.tag = "[verb]",
|
||||
.alias = "[init_verbs]",
|
||||
.parser = parse_verb_mode,
|
||||
},
|
||||
[LINE_MODE_PINCFG] = {
|
||||
.tag = "[pincfg]",
|
||||
.alias = "[user_pin_configs]",
|
||||
.parser = parse_pincfg_mode,
|
||||
},
|
||||
[LINE_MODE_HINT] = {
|
||||
.tag = "[hint]",
|
||||
.alias = "[hints]",
|
||||
.parser = parse_hint_mode
|
||||
},
|
||||
[LINE_MODE_VENDOR_ID] = {
|
||||
.tag = "[vendor_id]",
|
||||
.parser = parse_vendor_id_mode,
|
||||
},
|
||||
[LINE_MODE_SUBSYSTEM_ID] = {
|
||||
.tag = "[subsystem_id]",
|
||||
.parser = parse_subsystem_id_mode,
|
||||
},
|
||||
[LINE_MODE_REVISION_ID] = {
|
||||
.tag = "[revision_id]",
|
||||
.parser = parse_revision_id_mode,
|
||||
},
|
||||
[LINE_MODE_CHIP_NAME] = {
|
||||
.tag = "[chip_name]",
|
||||
.parser = parse_chip_name_mode,
|
||||
},
|
||||
};
|
||||
|
||||
/* check the line starting with '[' -- change the parser mode accodingly */
|
||||
@ -787,6 +817,8 @@ static int parse_line_mode(char *buf, struct hda_bus *bus)
|
||||
continue;
|
||||
if (strmatch(buf, patch_items[i].tag))
|
||||
return i;
|
||||
if (patch_items[i].alias && strmatch(buf, patch_items[i].alias))
|
||||
return i;
|
||||
}
|
||||
return LINE_MODE_NONE;
|
||||
}
|
||||
@ -846,10 +878,10 @@ int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, const void *fw_buf)
|
||||
if (*buf == '[')
|
||||
line_mode = parse_line_mode(buf, bus);
|
||||
else if (patch_items[line_mode].parser &&
|
||||
(codec || !patch_items[line_mode].need_codec))
|
||||
(codec || line_mode <= LINE_MODE_CODEC))
|
||||
patch_items[line_mode].parser(buf, bus, &codec);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_load_patch);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_load_patch);
|
||||
#endif /* CONFIG_SND_HDA_PATCH_LOADER */
|
||||
|
@ -297,9 +297,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
|
||||
#define ULI_NUM_CAPTURE 5
|
||||
#define ULI_NUM_PLAYBACK 6
|
||||
|
||||
/* ATI HDMI has 1 playback and 0 capture */
|
||||
/* ATI HDMI may have up to 8 playbacks and 0 capture */
|
||||
#define ATIHDMI_NUM_CAPTURE 0
|
||||
#define ATIHDMI_NUM_PLAYBACK 1
|
||||
#define ATIHDMI_NUM_PLAYBACK 8
|
||||
|
||||
/* TERA has 4 playback and 3 capture */
|
||||
#define TERA_NUM_CAPTURE 3
|
||||
@ -431,6 +431,8 @@ struct azx_dev {
|
||||
struct timecounter azx_tc;
|
||||
struct cyclecounter azx_cc;
|
||||
|
||||
int delay_negative_threshold;
|
||||
|
||||
#ifdef CONFIG_SND_HDA_DSP_LOADER
|
||||
struct mutex dsp_mutex;
|
||||
#endif
|
||||
@ -543,9 +545,7 @@ struct azx {
|
||||
/* for pending irqs */
|
||||
struct work_struct irq_pending_work;
|
||||
|
||||
#ifdef CONFIG_SND_HDA_I915
|
||||
struct work_struct probe_work;
|
||||
#endif
|
||||
|
||||
/* reboot notifier (for mysterious hangup problem at power-down) */
|
||||
struct notifier_block reboot_notifier;
|
||||
@ -2197,6 +2197,15 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* when LPIB delay correction gives a small negative value,
|
||||
* we ignore it; currently set the threshold statically to
|
||||
* 64 frames
|
||||
*/
|
||||
if (runtime->period_size > 64)
|
||||
azx_dev->delay_negative_threshold = -frames_to_bytes(runtime, 64);
|
||||
else
|
||||
azx_dev->delay_negative_threshold = 0;
|
||||
|
||||
/* wallclk has 24Mhz clock source */
|
||||
azx_dev->period_wallclk = (((runtime->period_size * 24000) /
|
||||
runtime->rate) * 1000);
|
||||
@ -2449,8 +2458,12 @@ static unsigned int azx_get_position(struct azx *chip,
|
||||
delay = pos - lpib_pos;
|
||||
else
|
||||
delay = lpib_pos - pos;
|
||||
if (delay < 0)
|
||||
delay += azx_dev->bufsize;
|
||||
if (delay < 0) {
|
||||
if (delay >= azx_dev->delay_negative_threshold)
|
||||
delay = 0;
|
||||
else
|
||||
delay += azx_dev->bufsize;
|
||||
}
|
||||
if (delay >= azx_dev->period_bytes) {
|
||||
snd_printk(KERN_WARNING SFX
|
||||
"%s: Unstable LPIB (%d >= %d); "
|
||||
@ -3504,12 +3517,10 @@ static void azx_check_snoop_available(struct azx *chip)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_HDA_I915
|
||||
static void azx_probe_work(struct work_struct *work)
|
||||
{
|
||||
azx_probe_continue(container_of(work, struct azx, probe_work));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* constructor
|
||||
@ -3586,10 +3597,8 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_HDA_I915
|
||||
/* continue probing in work context as may trigger request module */
|
||||
INIT_WORK(&chip->probe_work, azx_probe_work);
|
||||
#endif
|
||||
|
||||
*rchip = chip;
|
||||
|
||||
@ -3809,7 +3818,7 @@ static int azx_probe(struct pci_dev *pci,
|
||||
static int dev;
|
||||
struct snd_card *card;
|
||||
struct azx *chip;
|
||||
bool probe_now;
|
||||
bool schedule_probe;
|
||||
int err;
|
||||
|
||||
if (dev >= SNDRV_CARDS)
|
||||
@ -3848,7 +3857,7 @@ static int azx_probe(struct pci_dev *pci,
|
||||
chip->disabled = true;
|
||||
}
|
||||
|
||||
probe_now = !chip->disabled;
|
||||
schedule_probe = !chip->disabled;
|
||||
|
||||
#ifdef CONFIG_SND_HDA_PATCH_LOADER
|
||||
if (patch[dev] && *patch[dev]) {
|
||||
@ -3859,25 +3868,17 @@ static int azx_probe(struct pci_dev *pci,
|
||||
azx_firmware_cb);
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
probe_now = false; /* continued in azx_firmware_cb() */
|
||||
schedule_probe = false; /* continued in azx_firmware_cb() */
|
||||
}
|
||||
#endif /* CONFIG_SND_HDA_PATCH_LOADER */
|
||||
|
||||
/* continue probing in work context, avoid request_module deadlock */
|
||||
if (probe_now && (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)) {
|
||||
#ifdef CONFIG_SND_HDA_I915
|
||||
probe_now = false;
|
||||
schedule_work(&chip->probe_work);
|
||||
#else
|
||||
#ifndef CONFIG_SND_HDA_I915
|
||||
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
|
||||
snd_printk(KERN_ERR SFX "Haswell must build in CONFIG_SND_HDA_I915\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (probe_now) {
|
||||
err = azx_probe_continue(chip);
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
}
|
||||
if (schedule_probe)
|
||||
schedule_work(&chip->probe_work);
|
||||
|
||||
dev++;
|
||||
if (chip->disabled)
|
||||
@ -3983,7 +3984,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
|
||||
/* Panther Point */
|
||||
{ PCI_DEVICE(0x8086, 0x1e20),
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
||||
/* Lynx Point */
|
||||
{ PCI_DEVICE(0x8086, 0x8c20),
|
||||
.driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
|
||||
@ -4008,6 +4009,9 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
|
||||
.driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
|
||||
{ PCI_DEVICE(0x8086, 0x0d0c),
|
||||
.driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
|
||||
/* Broadwell */
|
||||
{ PCI_DEVICE(0x8086, 0x160c),
|
||||
.driver_data = AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL },
|
||||
/* 5 Series/3400 */
|
||||
{ PCI_DEVICE(0x8086, 0x3b56),
|
||||
.driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
|
||||
|
@ -34,7 +34,7 @@ bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(is_jack_detectable);
|
||||
EXPORT_SYMBOL_GPL(is_jack_detectable);
|
||||
|
||||
/* execute pin sense measurement */
|
||||
static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
|
||||
@ -71,7 +71,7 @@ snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid)
|
||||
return jack;
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get);
|
||||
|
||||
/**
|
||||
* snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag
|
||||
@ -89,7 +89,7 @@ snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag)
|
||||
return jack;
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get_from_tag);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get_from_tag);
|
||||
|
||||
/**
|
||||
* snd_hda_jack_tbl_new - create a jack-table entry for the given NID
|
||||
@ -108,7 +108,7 @@ snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
|
||||
jack->tag = codec->jacktbl.used;
|
||||
return jack;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_new);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_new);
|
||||
|
||||
void snd_hda_jack_tbl_clear(struct hda_codec *codec)
|
||||
{
|
||||
@ -172,7 +172,7 @@ void snd_hda_jack_set_dirty_all(struct hda_codec *codec)
|
||||
if (jack->nid)
|
||||
jack->jack_dirty = 1;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_set_dirty_all);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_set_dirty_all);
|
||||
|
||||
/**
|
||||
* snd_hda_pin_sense - execute pin sense measurement
|
||||
@ -191,7 +191,7 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
|
||||
}
|
||||
return read_pin_sense(codec, nid);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_pin_sense);
|
||||
|
||||
/**
|
||||
* snd_hda_jack_detect_state - query pin Presence Detect status
|
||||
@ -211,7 +211,7 @@ int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid)
|
||||
else
|
||||
return HDA_JACK_NOT_PRESENT;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_detect_state);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_detect_state);
|
||||
|
||||
/**
|
||||
* snd_hda_jack_detect_enable - enable the jack-detection
|
||||
@ -236,14 +236,14 @@ int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
|
||||
AC_VERB_SET_UNSOLICITED_ENABLE,
|
||||
AC_USRSP_EN | jack->tag);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable_callback);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback);
|
||||
|
||||
int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
|
||||
unsigned char action)
|
||||
{
|
||||
return snd_hda_jack_detect_enable_callback(codec, nid, action, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable);
|
||||
|
||||
/**
|
||||
* snd_hda_jack_set_gating_jack - Set gating jack.
|
||||
@ -264,7 +264,7 @@ int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_set_gating_jack);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_set_gating_jack);
|
||||
|
||||
/**
|
||||
* snd_hda_jack_report_sync - sync the states of all jacks and report if changed
|
||||
@ -297,7 +297,7 @@ void snd_hda_jack_report_sync(struct hda_codec *codec)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_report_sync);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_report_sync);
|
||||
|
||||
#ifdef CONFIG_SND_HDA_INPUT_JACK
|
||||
/* guess the jack type from the pin-config */
|
||||
@ -377,7 +377,7 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
|
||||
{
|
||||
return __snd_hda_jack_add_kctl(codec, nid, name, idx, false);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctl);
|
||||
|
||||
/* get the unique index number for the given kctl name */
|
||||
static int get_unique_index(struct hda_codec *codec, const char *name, int idx)
|
||||
@ -493,7 +493,7 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctls);
|
||||
|
||||
static void call_jack_callback(struct hda_codec *codec,
|
||||
struct hda_jack_tbl *jack)
|
||||
@ -521,7 +521,7 @@ void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res)
|
||||
call_jack_callback(codec, event);
|
||||
snd_hda_jack_report_sync(codec);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_unsol_event);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_unsol_event);
|
||||
|
||||
void snd_hda_jack_poll_all(struct hda_codec *codec)
|
||||
{
|
||||
@ -542,5 +542,5 @@ void snd_hda_jack_poll_all(struct hda_codec *codec)
|
||||
if (changes)
|
||||
snd_hda_jack_report_sync(codec);
|
||||
}
|
||||
EXPORT_SYMBOL_HDA(snd_hda_jack_poll_all);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_jack_poll_all);
|
||||
|
||||
|
@ -352,14 +352,8 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
|
||||
/*
|
||||
* generic codec parser
|
||||
*/
|
||||
#ifdef CONFIG_SND_HDA_GENERIC
|
||||
int snd_hda_parse_generic_codec(struct hda_codec *codec);
|
||||
#else
|
||||
static inline int snd_hda_parse_generic_codec(struct hda_codec *codec)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
int snd_hda_parse_hdmi_codec(struct hda_codec *codec);
|
||||
|
||||
/*
|
||||
* generic proc interface
|
||||
|
@ -185,7 +185,7 @@ static const struct hda_codec_ops ad198x_auto_patch_ops = {
|
||||
};
|
||||
|
||||
|
||||
static int ad198x_parse_auto_config(struct hda_codec *codec)
|
||||
static int ad198x_parse_auto_config(struct hda_codec *codec, bool indep_hp)
|
||||
{
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
struct auto_pin_cfg *cfg = &spec->gen.autocfg;
|
||||
@ -195,7 +195,8 @@ static int ad198x_parse_auto_config(struct hda_codec *codec)
|
||||
codec->no_trigger_sense = 1;
|
||||
codec->no_sticky_stream = 1;
|
||||
|
||||
spec->gen.indep_hp = 1;
|
||||
spec->gen.indep_hp = indep_hp;
|
||||
spec->gen.add_stereo_mix_input = 1;
|
||||
|
||||
err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
|
||||
if (err < 0)
|
||||
@ -280,11 +281,11 @@ static const struct hda_fixup ad1986a_fixups[] = {
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x1a, 0x02214021 }, /* headphone */
|
||||
{ 0x1b, 0x01014011 }, /* front */
|
||||
{ 0x1c, 0x01013012 }, /* surround */
|
||||
{ 0x1d, 0x01019015 }, /* clfe */
|
||||
{ 0x1c, 0x01813030 }, /* line-in */
|
||||
{ 0x1d, 0x01a19020 }, /* rear mic */
|
||||
{ 0x1e, 0x411111f0 }, /* N/A */
|
||||
{ 0x1f, 0x02a190f0 }, /* mic */
|
||||
{ 0x20, 0x018130f0 }, /* line-in */
|
||||
{ 0x20, 0x411111f0 }, /* N/A */
|
||||
{}
|
||||
},
|
||||
},
|
||||
@ -378,7 +379,7 @@ static int patch_ad1986a(struct hda_codec *codec)
|
||||
ad1986a_fixups);
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
|
||||
|
||||
err = ad198x_parse_auto_config(codec);
|
||||
err = ad198x_parse_auto_config(codec, false);
|
||||
if (err < 0) {
|
||||
snd_hda_gen_free(codec);
|
||||
return err;
|
||||
@ -480,7 +481,7 @@ static int patch_ad1983(struct hda_codec *codec)
|
||||
|
||||
spec->gen.beep_nid = 0x10;
|
||||
set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
|
||||
err = ad198x_parse_auto_config(codec);
|
||||
err = ad198x_parse_auto_config(codec, false);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
err = ad1983_add_spdif_mux_ctl(codec);
|
||||
@ -567,7 +568,7 @@ static int patch_ad1981(struct hda_codec *codec)
|
||||
snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups);
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
|
||||
|
||||
err = ad198x_parse_auto_config(codec);
|
||||
err = ad198x_parse_auto_config(codec, false);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
err = ad1983_add_spdif_mux_ctl(codec);
|
||||
@ -893,7 +894,7 @@ static int patch_ad1988(struct hda_codec *codec)
|
||||
snd_hda_pick_fixup(codec, ad1988_fixup_models, NULL, ad1988_fixups);
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
|
||||
|
||||
err = ad198x_parse_auto_config(codec);
|
||||
err = ad198x_parse_auto_config(codec, true);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
err = ad1988_add_spdif_mux_ctl(codec);
|
||||
@ -1070,7 +1071,7 @@ static int patch_ad1884(struct hda_codec *codec)
|
||||
snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups);
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
|
||||
|
||||
err = ad198x_parse_auto_config(codec);
|
||||
err = ad198x_parse_auto_config(codec, true);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
err = ad1983_add_spdif_mux_ctl(codec);
|
||||
@ -1112,7 +1113,7 @@ static int patch_ad1882(struct hda_codec *codec)
|
||||
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);
|
||||
err = ad198x_parse_auto_config(codec, true);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
err = ad1988_add_spdif_mux_ctl(codec);
|
||||
|
@ -3240,102 +3240,8 @@ enum {
|
||||
CXT_FIXUP_THINKPAD_ACPI,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_THINKPAD_ACPI)
|
||||
|
||||
#include <linux/thinkpad_acpi.h>
|
||||
#include <acpi/acpi.h>
|
||||
|
||||
static int (*led_set_func)(int, bool);
|
||||
|
||||
static acpi_status acpi_check_cb(acpi_handle handle, u32 lvl, void *context,
|
||||
void **rv)
|
||||
{
|
||||
bool *found = context;
|
||||
*found = true;
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static bool is_thinkpad(struct hda_codec *codec)
|
||||
{
|
||||
bool found = false;
|
||||
if (codec->subsystem_id >> 16 != 0x17aa)
|
||||
return false;
|
||||
if (ACPI_SUCCESS(acpi_get_devices("LEN0068", acpi_check_cb, &found, NULL)) && found)
|
||||
return true;
|
||||
found = false;
|
||||
return ACPI_SUCCESS(acpi_get_devices("IBM0068", acpi_check_cb, &found, NULL)) && found;
|
||||
}
|
||||
|
||||
static void update_tpacpi_mute_led(void *private_data, int enabled)
|
||||
{
|
||||
struct hda_codec *codec = private_data;
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
|
||||
if (spec->dynamic_eapd)
|
||||
cx_auto_vmaster_hook(private_data, enabled);
|
||||
|
||||
if (led_set_func)
|
||||
led_set_func(TPACPI_LED_MUTE, !enabled);
|
||||
}
|
||||
|
||||
static void update_tpacpi_micmute_led(struct hda_codec *codec,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
if (!ucontrol || !led_set_func)
|
||||
return;
|
||||
if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) {
|
||||
/* TODO: How do I verify if it's a mono or stereo here? */
|
||||
bool val = ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1];
|
||||
led_set_func(TPACPI_LED_MICMUTE, !val);
|
||||
}
|
||||
}
|
||||
|
||||
static void cxt_fixup_thinkpad_acpi(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
|
||||
bool removefunc = false;
|
||||
|
||||
if (action == HDA_FIXUP_ACT_PROBE) {
|
||||
if (!is_thinkpad(codec))
|
||||
return;
|
||||
if (!led_set_func)
|
||||
led_set_func = symbol_request(tpacpi_led_set);
|
||||
if (!led_set_func) {
|
||||
snd_printk(KERN_WARNING "Failed to find thinkpad-acpi symbol tpacpi_led_set\n");
|
||||
return;
|
||||
}
|
||||
|
||||
removefunc = true;
|
||||
if (led_set_func(TPACPI_LED_MUTE, false) >= 0) {
|
||||
spec->gen.vmaster_mute.hook = update_tpacpi_mute_led;
|
||||
removefunc = false;
|
||||
}
|
||||
if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) {
|
||||
if (spec->gen.num_adc_nids > 1)
|
||||
snd_printdd("Skipping micmute LED control due to several ADCs");
|
||||
else {
|
||||
spec->gen.cap_sync_hook = update_tpacpi_micmute_led;
|
||||
removefunc = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) {
|
||||
symbol_put(tpacpi_led_set);
|
||||
led_set_func = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void cxt_fixup_thinkpad_acpi(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
/* for hda_fixup_thinkpad_acpi() */
|
||||
#include "thinkpad_helper.c"
|
||||
|
||||
static void cxt_fixup_stereo_dmic(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
@ -3492,7 +3398,7 @@ static const struct hda_fixup cxt_fixups[] = {
|
||||
},
|
||||
[CXT_FIXUP_THINKPAD_ACPI] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = cxt_fixup_thinkpad_acpi,
|
||||
.v.func = hda_fixup_thinkpad_acpi,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -46,6 +46,9 @@ module_param(static_hdmi_pcm, bool, 0644);
|
||||
MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
|
||||
|
||||
#define is_haswell(codec) ((codec)->vendor_id == 0x80862807)
|
||||
#define is_broadwell(codec) ((codec)->vendor_id == 0x80862808)
|
||||
#define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec))
|
||||
|
||||
#define is_valleyview(codec) ((codec)->vendor_id == 0x80862882)
|
||||
|
||||
struct hdmi_spec_per_cvt {
|
||||
@ -1101,7 +1104,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
|
||||
if (!channels)
|
||||
return;
|
||||
|
||||
if (is_haswell(codec))
|
||||
if (is_haswell_plus(codec))
|
||||
snd_hda_codec_write(codec, pin_nid, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AMP_OUT_UNMUTE);
|
||||
@ -1280,7 +1283,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
int err;
|
||||
|
||||
if (is_haswell(codec))
|
||||
if (is_haswell_plus(codec))
|
||||
haswell_verify_D0(codec, cvt_nid, pin_nid);
|
||||
|
||||
err = spec->ops.pin_hbr_setup(codec, pin_nid, is_hbr_format(format));
|
||||
@ -1421,7 +1424,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
|
||||
mux_idx);
|
||||
|
||||
/* configure unused pins to choose other converters */
|
||||
if (is_haswell(codec) || is_valleyview(codec))
|
||||
if (is_haswell_plus(codec) || is_valleyview(codec))
|
||||
intel_not_share_assigned_cvt(codec, per_pin->pin_nid, mux_idx);
|
||||
|
||||
snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
|
||||
@ -1496,11 +1499,14 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
|
||||
* specification worked this way. Hence, we just ignore the data in
|
||||
* the unsolicited response to avoid custom WARs.
|
||||
*/
|
||||
int present = snd_hda_pin_sense(codec, pin_nid);
|
||||
int present;
|
||||
bool update_eld = false;
|
||||
bool eld_changed = false;
|
||||
bool ret;
|
||||
|
||||
snd_hda_power_up(codec);
|
||||
present = snd_hda_pin_sense(codec, pin_nid);
|
||||
|
||||
mutex_lock(&per_pin->lock);
|
||||
pin_eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
|
||||
if (pin_eld->monitor_present)
|
||||
@ -1573,6 +1579,7 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
|
||||
jack->block_report = !ret;
|
||||
|
||||
mutex_unlock(&per_pin->lock);
|
||||
snd_hda_power_down(codec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1607,7 +1614,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
|
||||
if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
|
||||
return 0;
|
||||
|
||||
if (is_haswell(codec))
|
||||
if (is_haswell_plus(codec))
|
||||
intel_haswell_fixup_connect_list(codec, pin_nid);
|
||||
|
||||
pin_idx = spec->num_pins;
|
||||
@ -1694,21 +1701,6 @@ static int hdmi_parse_codec(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
/* We're seeing some problems with unsolicited hot plug events on
|
||||
* PantherPoint after S3, if this is not enabled */
|
||||
if (codec->vendor_id == 0x80862806)
|
||||
codec->bus->power_keep_link_on = 1;
|
||||
/*
|
||||
* G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
|
||||
* can be lost and presence sense verb will become inaccurate if the
|
||||
* HDA link is powered off at hot plug or hw initialization time.
|
||||
*/
|
||||
else if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
|
||||
AC_PWRST_EPSS))
|
||||
codec->bus->power_keep_link_on = 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2260,18 +2252,22 @@ static int patch_generic_hdmi(struct hda_codec *codec)
|
||||
codec->spec = spec;
|
||||
hdmi_array_init(spec, 4);
|
||||
|
||||
if (is_haswell(codec)) {
|
||||
if (is_haswell_plus(codec)) {
|
||||
intel_haswell_enable_all_pins(codec, true);
|
||||
intel_haswell_fixup_enable_dp12(codec);
|
||||
}
|
||||
|
||||
if (is_haswell(codec) || is_valleyview(codec)) {
|
||||
codec->depop_delay = 0;
|
||||
}
|
||||
|
||||
if (hdmi_parse_codec(codec) < 0) {
|
||||
codec->spec = NULL;
|
||||
kfree(spec);
|
||||
return -EINVAL;
|
||||
}
|
||||
codec->patch_ops = generic_hdmi_patch_ops;
|
||||
if (is_haswell(codec)) {
|
||||
if (is_haswell_plus(codec)) {
|
||||
codec->patch_ops.set_power_state = haswell_set_power_state;
|
||||
codec->dp_mst = true;
|
||||
}
|
||||
@ -3217,6 +3213,15 @@ static int patch_via_hdmi(struct hda_codec *codec)
|
||||
return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
|
||||
}
|
||||
|
||||
/*
|
||||
* called from hda_codec.c for generic HDMI support
|
||||
*/
|
||||
int snd_hda_parse_hdmi_codec(struct hda_codec *codec)
|
||||
{
|
||||
return patch_generic_hdmi(codec);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_parse_hdmi_codec);
|
||||
|
||||
/*
|
||||
* patch entries
|
||||
*/
|
||||
@ -3271,6 +3276,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
|
||||
{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x80862807, .name = "Haswell HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x80862808, .name = "Broadwell HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x80862882, .name = "Valleyview2 HDMI", .patch = patch_generic_hdmi },
|
||||
{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi },
|
||||
@ -3326,6 +3332,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862804");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80862805");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80862806");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80862807");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80862808");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80862880");
|
||||
MODULE_ALIAS("snd-hda-codec-id:80862882");
|
||||
MODULE_ALIAS("snd-hda-codec-id:808629fb");
|
||||
|
@ -118,7 +118,8 @@ struct alc_spec {
|
||||
|
||||
int init_amp;
|
||||
int codec_variant; /* flag for other variants */
|
||||
bool has_alc5505_dsp;
|
||||
unsigned int has_alc5505_dsp:1;
|
||||
unsigned int no_depop_delay:1;
|
||||
|
||||
/* for PLL fix */
|
||||
hda_nid_t pll_nid;
|
||||
@ -280,8 +281,11 @@ static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
|
||||
*/
|
||||
static void alc_eapd_shutup(struct hda_codec *codec)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
|
||||
alc_auto_setup_eapd(codec, false);
|
||||
msleep(200);
|
||||
if (!spec->no_depop_delay)
|
||||
msleep(200);
|
||||
snd_hda_shutup_pins(codec);
|
||||
}
|
||||
|
||||
@ -365,6 +369,17 @@ static void alc_fixup_sku_ignore(struct hda_codec *codec,
|
||||
}
|
||||
}
|
||||
|
||||
static void alc_fixup_no_depop_delay(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
|
||||
if (action == HDA_FIXUP_ACT_PROBE) {
|
||||
spec->no_depop_delay = 1;
|
||||
codec->depop_delay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int alc_auto_parse_customize_define(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int ass, tmp, i;
|
||||
@ -454,9 +469,7 @@ static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
|
||||
* 7 ~ 0 : Assembly ID
|
||||
* port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
|
||||
*/
|
||||
static int alc_subsystem_id(struct hda_codec *codec,
|
||||
hda_nid_t porta, hda_nid_t porte,
|
||||
hda_nid_t portd, hda_nid_t porti)
|
||||
static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
|
||||
{
|
||||
unsigned int ass, tmp, i;
|
||||
unsigned nid;
|
||||
@ -546,14 +559,7 @@ static int alc_subsystem_id(struct hda_codec *codec,
|
||||
spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
|
||||
hda_nid_t nid;
|
||||
tmp = (ass >> 11) & 0x3; /* HP to chassis */
|
||||
if (tmp == 0)
|
||||
nid = porta;
|
||||
else if (tmp == 1)
|
||||
nid = porte;
|
||||
else if (tmp == 2)
|
||||
nid = portd;
|
||||
else if (tmp == 3)
|
||||
nid = porti;
|
||||
nid = ports[tmp];
|
||||
if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
|
||||
spec->gen.autocfg.line_outs))
|
||||
return 1;
|
||||
@ -566,7 +572,7 @@ static int alc_subsystem_id(struct hda_codec *codec,
|
||||
* ports contains an array of 4 pin NIDs for port-A, E, D and I */
|
||||
static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
|
||||
{
|
||||
if (!alc_subsystem_id(codec, ports[0], ports[1], ports[2], ports[3])) {
|
||||
if (!alc_subsystem_id(codec, ports)) {
|
||||
struct alc_spec *spec = codec->spec;
|
||||
snd_printd("realtek: "
|
||||
"Enable default setup for auto mode as fallback\n");
|
||||
@ -863,7 +869,10 @@ static int alc_suspend(struct hda_codec *codec)
|
||||
#ifdef CONFIG_PM
|
||||
static int alc_resume(struct hda_codec *codec)
|
||||
{
|
||||
msleep(150); /* to avoid pop noise */
|
||||
struct alc_spec *spec = codec->spec;
|
||||
|
||||
if (!spec->no_depop_delay)
|
||||
msleep(150); /* to avoid pop noise */
|
||||
codec->patch_ops.init(codec);
|
||||
snd_hda_codec_resume_amp(codec);
|
||||
snd_hda_codec_resume_cache(codec);
|
||||
@ -903,7 +912,7 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name)
|
||||
}
|
||||
|
||||
/*
|
||||
* Rename codecs appropriately from COEF value
|
||||
* Rename codecs appropriately from COEF value or subvendor id
|
||||
*/
|
||||
struct alc_codec_rename_table {
|
||||
unsigned int vendor_id;
|
||||
@ -912,6 +921,13 @@ struct alc_codec_rename_table {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct alc_codec_rename_pci_table {
|
||||
unsigned int codec_vendor_id;
|
||||
unsigned short pci_subvendor;
|
||||
unsigned short pci_subdevice;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static struct alc_codec_rename_table rename_tbl[] = {
|
||||
{ 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
|
||||
{ 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
|
||||
@ -931,9 +947,20 @@ static struct alc_codec_rename_table rename_tbl[] = {
|
||||
{ } /* terminator */
|
||||
};
|
||||
|
||||
static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
|
||||
{ 0x10ec0280, 0x1028, 0, "ALC3220" },
|
||||
{ 0x10ec0282, 0x1028, 0, "ALC3221" },
|
||||
{ 0x10ec0283, 0x1028, 0, "ALC3223" },
|
||||
{ 0x10ec0292, 0x1028, 0, "ALC3226" },
|
||||
{ 0x10ec0255, 0x1028, 0, "ALC3234" },
|
||||
{ 0x10ec0668, 0x1028, 0, "ALC3661" },
|
||||
{ } /* terminator */
|
||||
};
|
||||
|
||||
static int alc_codec_rename_from_preset(struct hda_codec *codec)
|
||||
{
|
||||
const struct alc_codec_rename_table *p;
|
||||
const struct alc_codec_rename_pci_table *q;
|
||||
|
||||
for (p = rename_tbl; p->vendor_id; p++) {
|
||||
if (p->vendor_id != codec->vendor_id)
|
||||
@ -941,6 +968,17 @@ static int alc_codec_rename_from_preset(struct hda_codec *codec)
|
||||
if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
|
||||
return alc_codec_rename(codec, p->name);
|
||||
}
|
||||
|
||||
for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
|
||||
if (q->codec_vendor_id != codec->vendor_id)
|
||||
continue;
|
||||
if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
|
||||
continue;
|
||||
if (!q->pci_subdevice ||
|
||||
q->pci_subdevice == codec->bus->pci->subsystem_device)
|
||||
return alc_codec_rename(codec, q->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1763,6 +1801,7 @@ enum {
|
||||
ALC882_FIXUP_ACER_ASPIRE_7736,
|
||||
ALC882_FIXUP_ASUS_W90V,
|
||||
ALC889_FIXUP_CD,
|
||||
ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
|
||||
ALC889_FIXUP_VAIO_TT,
|
||||
ALC888_FIXUP_EEE1601,
|
||||
ALC882_FIXUP_EAPD,
|
||||
@ -1980,6 +2019,15 @@ static const struct hda_fixup alc882_fixups[] = {
|
||||
{ }
|
||||
}
|
||||
},
|
||||
[ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
|
||||
{ }
|
||||
},
|
||||
.chained = true,
|
||||
.chain_id = ALC889_FIXUP_CD,
|
||||
},
|
||||
[ALC889_FIXUP_VAIO_TT] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
@ -2211,7 +2259,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
|
||||
SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
|
||||
SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
|
||||
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3", ALC889_FIXUP_CD),
|
||||
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
|
||||
SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
|
||||
SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
|
||||
@ -2314,6 +2362,7 @@ enum {
|
||||
ALC262_FIXUP_BENQ,
|
||||
ALC262_FIXUP_BENQ_T31,
|
||||
ALC262_FIXUP_INV_DMIC,
|
||||
ALC262_FIXUP_INTEL_BAYLEYBAY,
|
||||
};
|
||||
|
||||
static const struct hda_fixup alc262_fixups[] = {
|
||||
@ -2378,6 +2427,10 @@ static const struct hda_fixup alc262_fixups[] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_inv_dmic_0x12,
|
||||
},
|
||||
[ALC262_FIXUP_INTEL_BAYLEYBAY] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_no_depop_delay,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc262_fixup_tbl[] = {
|
||||
@ -2389,6 +2442,7 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
|
||||
SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
|
||||
SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
|
||||
SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
|
||||
{}
|
||||
};
|
||||
|
||||
@ -3526,6 +3580,15 @@ static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
|
||||
alc_fixup_headset_mode(codec, fix, action);
|
||||
}
|
||||
|
||||
static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
|
||||
struct alc_spec *spec = codec->spec;
|
||||
spec->gen.auto_mute_via_amp = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
@ -3717,101 +3780,18 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
|
||||
static void alc290_fixup_mono_speakers(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
if (action == HDA_FIXUP_ACT_PRE_PROBE)
|
||||
/* Remove DAC node 0x03, as it seems to be
|
||||
giving mono output */
|
||||
snd_hda_override_wcaps(codec, 0x03, 0);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_THINKPAD_ACPI)
|
||||
|
||||
#include <linux/thinkpad_acpi.h>
|
||||
#include <acpi/acpi.h>
|
||||
|
||||
static int (*led_set_func)(int, bool);
|
||||
|
||||
static acpi_status acpi_check_cb(acpi_handle handle, u32 lvl, void *context,
|
||||
void **rv)
|
||||
{
|
||||
bool *found = context;
|
||||
*found = true;
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static bool is_thinkpad(struct hda_codec *codec)
|
||||
{
|
||||
bool found = false;
|
||||
if (codec->subsystem_id >> 16 != 0x17aa)
|
||||
return false;
|
||||
if (ACPI_SUCCESS(acpi_get_devices("LEN0068", acpi_check_cb, &found, NULL)) && found)
|
||||
return true;
|
||||
found = false;
|
||||
return ACPI_SUCCESS(acpi_get_devices("IBM0068", acpi_check_cb, &found, NULL)) && found;
|
||||
}
|
||||
|
||||
static void update_tpacpi_mute_led(void *private_data, int enabled)
|
||||
{
|
||||
if (led_set_func)
|
||||
led_set_func(TPACPI_LED_MUTE, !enabled);
|
||||
}
|
||||
|
||||
static void update_tpacpi_micmute_led(struct hda_codec *codec,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
if (!ucontrol || !led_set_func)
|
||||
return;
|
||||
if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) {
|
||||
/* TODO: How do I verify if it's a mono or stereo here? */
|
||||
bool val = ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1];
|
||||
led_set_func(TPACPI_LED_MICMUTE, !val);
|
||||
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
|
||||
/* DAC node 0x03 is giving mono output. We therefore want to
|
||||
make sure 0x14 (front speaker) and 0x15 (headphones) use the
|
||||
stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
|
||||
hda_nid_t conn1[2] = { 0x0c };
|
||||
snd_hda_override_conn_list(codec, 0x14, 1, conn1);
|
||||
snd_hda_override_conn_list(codec, 0x15, 1, conn1);
|
||||
}
|
||||
}
|
||||
|
||||
static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
bool removefunc = false;
|
||||
|
||||
if (action == HDA_FIXUP_ACT_PROBE) {
|
||||
if (!is_thinkpad(codec))
|
||||
return;
|
||||
if (!led_set_func)
|
||||
led_set_func = symbol_request(tpacpi_led_set);
|
||||
if (!led_set_func) {
|
||||
snd_printk(KERN_WARNING "Failed to find thinkpad-acpi symbol tpacpi_led_set\n");
|
||||
return;
|
||||
}
|
||||
|
||||
removefunc = true;
|
||||
if (led_set_func(TPACPI_LED_MUTE, false) >= 0) {
|
||||
spec->gen.vmaster_mute.hook = update_tpacpi_mute_led;
|
||||
removefunc = false;
|
||||
}
|
||||
if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) {
|
||||
if (spec->gen.num_adc_nids > 1)
|
||||
snd_printdd("Skipping micmute LED control due to several ADCs");
|
||||
else {
|
||||
spec->gen.cap_sync_hook = update_tpacpi_micmute_led;
|
||||
removefunc = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) {
|
||||
symbol_put(tpacpi_led_set);
|
||||
led_set_func = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void alc_fixup_thinkpad_acpi(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
/* for hda_fixup_thinkpad_acpi() */
|
||||
#include "thinkpad_helper.c"
|
||||
|
||||
enum {
|
||||
ALC269_FIXUP_SONY_VAIO,
|
||||
@ -3860,6 +3840,9 @@ enum {
|
||||
ALC282_FIXUP_ASUS_TX300,
|
||||
ALC283_FIXUP_INT_MIC,
|
||||
ALC290_FIXUP_MONO_SPEAKERS,
|
||||
ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
|
||||
ALC290_FIXUP_SUBWOOFER,
|
||||
ALC290_FIXUP_SUBWOOFER_HSJACK,
|
||||
ALC269_FIXUP_THINKPAD_ACPI,
|
||||
ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
|
||||
ALC255_FIXUP_HEADSET_MODE,
|
||||
@ -4182,15 +4165,37 @@ static const struct hda_fixup alc269_fixups[] = {
|
||||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
|
||||
},
|
||||
[ALC290_FIXUP_SUBWOOFER_HSJACK] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x17, 0x90170112 }, /* subwoofer */
|
||||
{ }
|
||||
},
|
||||
.chained = true,
|
||||
.chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
|
||||
},
|
||||
[ALC290_FIXUP_SUBWOOFER] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x17, 0x90170112 }, /* subwoofer */
|
||||
{ }
|
||||
},
|
||||
.chained = true,
|
||||
.chain_id = ALC290_FIXUP_MONO_SPEAKERS,
|
||||
},
|
||||
[ALC290_FIXUP_MONO_SPEAKERS] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc290_fixup_mono_speakers,
|
||||
},
|
||||
[ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc290_fixup_mono_speakers,
|
||||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
|
||||
},
|
||||
[ALC269_FIXUP_THINKPAD_ACPI] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_thinkpad_acpi,
|
||||
.v.func = hda_fixup_thinkpad_acpi,
|
||||
},
|
||||
[ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
@ -4229,6 +4234,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
|
||||
SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
@ -4247,16 +4253,23 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x060f, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_MONO_SPEAKERS),
|
||||
SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
|
||||
SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
|
||||
SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS),
|
||||
SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
|
||||
SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
|
||||
@ -4502,7 +4515,7 @@ static int patch_alc269(struct hda_codec *codec)
|
||||
}
|
||||
|
||||
if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
|
||||
spec->has_alc5505_dsp = true;
|
||||
spec->has_alc5505_dsp = 1;
|
||||
spec->init_hook = alc5505_dsp_init;
|
||||
}
|
||||
|
||||
@ -4841,6 +4854,7 @@ enum {
|
||||
ALC662_FIXUP_BASS_CHMAP,
|
||||
ALC662_FIXUP_BASS_1A,
|
||||
ALC662_FIXUP_BASS_1A_CHMAP,
|
||||
ALC668_FIXUP_AUTO_MUTE,
|
||||
};
|
||||
|
||||
static const struct hda_fixup alc662_fixups[] = {
|
||||
@ -5001,6 +5015,12 @@ static const struct hda_fixup alc662_fixups[] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_inv_dmic_0x12,
|
||||
},
|
||||
[ALC668_FIXUP_AUTO_MUTE] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_auto_mute_via_amp,
|
||||
.chained = true,
|
||||
.chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
|
||||
},
|
||||
[ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
@ -5046,11 +5066,12 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
|
||||
SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE),
|
||||
SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
|
||||
SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A_CHMAP),
|
||||
SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_CHMAP),
|
||||
|
@ -368,6 +368,17 @@ static int stac_vrefout_set(struct hda_codec *codec,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* prevent codec AFG to D3 state when vref-out pin is used for mute LED */
|
||||
/* this hook is set in stac_setup_gpio() */
|
||||
static unsigned int stac_vref_led_power_filter(struct hda_codec *codec,
|
||||
hda_nid_t nid,
|
||||
unsigned int power_state)
|
||||
{
|
||||
if (nid == codec->afg && power_state == AC_PWRST_D3)
|
||||
return AC_PWRST_D1;
|
||||
return snd_hda_gen_path_power_filter(codec, nid, power_state);
|
||||
}
|
||||
|
||||
/* update mute-LED accoring to the master switch */
|
||||
static void stac_update_led_status(struct hda_codec *codec, int enabled)
|
||||
{
|
||||
@ -4260,30 +4271,8 @@ static int stac_suspend(struct hda_codec *codec)
|
||||
stac_shutup(codec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void stac_set_power_state(struct hda_codec *codec, hda_nid_t fg,
|
||||
unsigned int power_state)
|
||||
{
|
||||
unsigned int afg_power_state = power_state;
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
|
||||
if (power_state == AC_PWRST_D3) {
|
||||
if (spec->vref_mute_led_nid) {
|
||||
/* with vref-out pin used for mute led control
|
||||
* codec AFG is prevented from D3 state
|
||||
*/
|
||||
afg_power_state = AC_PWRST_D1;
|
||||
}
|
||||
/* this delay seems necessary to avoid click noise at power-down */
|
||||
msleep(100);
|
||||
}
|
||||
snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
|
||||
afg_power_state);
|
||||
snd_hda_codec_set_power_to_all(codec, fg, power_state);
|
||||
}
|
||||
#else
|
||||
#define stac_suspend NULL
|
||||
#define stac_set_power_state NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static const struct hda_codec_ops stac_patch_ops = {
|
||||
@ -4466,8 +4455,7 @@ static void stac_setup_gpio(struct hda_codec *codec)
|
||||
spec->gpio_dir |= spec->gpio_led;
|
||||
spec->gpio_data |= spec->gpio_led;
|
||||
} else {
|
||||
codec->patch_ops.set_power_state =
|
||||
stac_set_power_state;
|
||||
codec->power_filter = stac_vref_led_power_filter;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,6 +138,7 @@ static struct via_spec *via_new_spec(struct hda_codec *codec)
|
||||
spec->gen.indep_hp = 1;
|
||||
spec->gen.keep_eapd_on = 1;
|
||||
spec->gen.pcm_playback_hook = via_playback_pcm_hook;
|
||||
spec->gen.add_stereo_mix_input = 1;
|
||||
return spec;
|
||||
}
|
||||
|
||||
|
99
sound/pci/hda/thinkpad_helper.c
Normal file
99
sound/pci/hda/thinkpad_helper.c
Normal file
@ -0,0 +1,99 @@
|
||||
/* Helper functions for Thinkpad LED control;
|
||||
* to be included from codec driver
|
||||
*/
|
||||
|
||||
#if IS_ENABLED(CONFIG_THINKPAD_ACPI)
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/thinkpad_acpi.h>
|
||||
|
||||
static int (*led_set_func)(int, bool);
|
||||
static void (*old_vmaster_hook)(void *, int);
|
||||
|
||||
static acpi_status acpi_check_cb(acpi_handle handle, u32 lvl, void *context,
|
||||
void **rv)
|
||||
{
|
||||
bool *found = context;
|
||||
*found = true;
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static bool is_thinkpad(struct hda_codec *codec)
|
||||
{
|
||||
bool found = false;
|
||||
if (codec->subsystem_id >> 16 != 0x17aa)
|
||||
return false;
|
||||
if (ACPI_SUCCESS(acpi_get_devices("LEN0068", acpi_check_cb, &found, NULL)) && found)
|
||||
return true;
|
||||
found = false;
|
||||
return ACPI_SUCCESS(acpi_get_devices("IBM0068", acpi_check_cb, &found, NULL)) && found;
|
||||
}
|
||||
|
||||
static void update_tpacpi_mute_led(void *private_data, int enabled)
|
||||
{
|
||||
if (old_vmaster_hook)
|
||||
old_vmaster_hook(private_data, enabled);
|
||||
|
||||
if (led_set_func)
|
||||
led_set_func(TPACPI_LED_MUTE, !enabled);
|
||||
}
|
||||
|
||||
static void update_tpacpi_micmute_led(struct hda_codec *codec,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
if (!ucontrol || !led_set_func)
|
||||
return;
|
||||
if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) {
|
||||
/* TODO: How do I verify if it's a mono or stereo here? */
|
||||
bool val = ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1];
|
||||
led_set_func(TPACPI_LED_MICMUTE, !val);
|
||||
}
|
||||
}
|
||||
|
||||
static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
struct hda_gen_spec *spec = codec->spec;
|
||||
bool removefunc = false;
|
||||
|
||||
if (action == HDA_FIXUP_ACT_PROBE) {
|
||||
if (!is_thinkpad(codec))
|
||||
return;
|
||||
if (!led_set_func)
|
||||
led_set_func = symbol_request(tpacpi_led_set);
|
||||
if (!led_set_func) {
|
||||
snd_printk(KERN_WARNING "Failed to find thinkpad-acpi symbol tpacpi_led_set\n");
|
||||
return;
|
||||
}
|
||||
|
||||
removefunc = true;
|
||||
if (led_set_func(TPACPI_LED_MUTE, false) >= 0) {
|
||||
old_vmaster_hook = spec->vmaster_mute.hook;
|
||||
spec->vmaster_mute.hook = update_tpacpi_mute_led;
|
||||
removefunc = false;
|
||||
}
|
||||
if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) {
|
||||
if (spec->num_adc_nids > 1)
|
||||
snd_printdd("Skipping micmute LED control due to several ADCs");
|
||||
else {
|
||||
spec->cap_sync_hook = update_tpacpi_micmute_led;
|
||||
removefunc = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) {
|
||||
symbol_put(tpacpi_led_set);
|
||||
led_set_func = NULL;
|
||||
old_vmaster_hook = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* CONFIG_THINKPAD_ACPI */
|
||||
|
||||
static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_THINKPAD_ACPI */
|
@ -584,10 +584,6 @@ static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer
|
||||
{
|
||||
dmab->dev.type = SNDRV_DMA_TYPE_DEV;
|
||||
dmab->dev.dev = snd_dma_pci_data(pci);
|
||||
if (snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) {
|
||||
if (dmab->bytes >= size)
|
||||
return 0;
|
||||
}
|
||||
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
|
||||
size, dmab) < 0)
|
||||
return -ENOMEM;
|
||||
@ -596,10 +592,8 @@ static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer
|
||||
|
||||
static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci)
|
||||
{
|
||||
if (dmab->area) {
|
||||
dmab->dev.dev = NULL; /* make it anonymous */
|
||||
snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci));
|
||||
}
|
||||
if (dmab->area)
|
||||
snd_dma_free_pages(dmab);
|
||||
}
|
||||
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user