Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (549 commits) ALSA: hda - Fix ADC input-amp handling for Cx20549 codec ALSA: hda - Keep EAPD turned on for old Conexant chips ALSA: hda/realtek - Fix missing volume controls with ALC260 ASoC: wm8940: Properly set codec->dapm.bias_level ALSA: hda - Fix pin-config for ASUS W90V ALSA: hda - Fix surround/CLFE headphone and speaker pins order ALSA: hda - Fix typo ALSA: Update the sound git tree URL ALSA: HDA: Add new revision for ALC662 ASoC: max98095: Convert codec->hw_write to snd_soc_write ASoC: keep pointer to resource so it can be freed ASoC: sgtl5000: Fix wrong mask in some snd_soc_update_bits calls ASoC: wm8996: Fix wrong mask for setting WM8996_AIF_CLOCKING_2 ASoC: da7210: Add support for line out and DAC ASoC: da7210: Add support for DAPM ALSA: hda/realtek - Fix DAC assignments of multiple speakers ASoC: Use SGTL5000_LINREG_VDDD_MASK instead of hardcoded mask value ASoC: Set sgtl5000->ldo in ldo_regulator_register ASoC: wm8996: Use SND_SOC_DAPM_AIF_OUT for AIF2 Capture ASoC: wm8994: Use SND_SOC_DAPM_AIF_OUT for AIF3 Capture ...
This commit is contained in:
commit
68d99b2c8e
389 changed files with 25802 additions and 12244 deletions
|
@ -4288,7 +4288,7 @@ struct _snd_pcm_runtime {
|
|||
<![CDATA[
|
||||
struct snd_rawmidi *rmidi;
|
||||
snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags,
|
||||
irq, irq_flags, &rmidi);
|
||||
irq, &rmidi);
|
||||
]]>
|
||||
</programlisting>
|
||||
</informalexample>
|
||||
|
@ -4343,6 +4343,13 @@ struct _snd_pcm_runtime {
|
|||
by itself to start processing the output stream in the irq handler.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the MPU-401 interface shares its interrupt with the other logical
|
||||
devices on the card, set <constant>MPU401_INFO_IRQ_HOOK</constant>
|
||||
(see <link linkend="midi-interface-interrupt-handler"><citetitle>
|
||||
below</citetitle></link>).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Usually, the port address corresponds to the command port and
|
||||
port + 1 corresponds to the data port. If not, you may change
|
||||
|
@ -4375,14 +4382,12 @@ struct _snd_pcm_runtime {
|
|||
</para>
|
||||
|
||||
<para>
|
||||
The 6th argument specifies the irq number for UART. If the irq
|
||||
is already allocated, pass 0 to the 7th argument
|
||||
(<parameter>irq_flags</parameter>). Otherwise, pass the flags
|
||||
for irq allocation
|
||||
(<constant>SA_XXX</constant> bits) to it, and the irq will be
|
||||
reserved by the mpu401-uart layer. If the card doesn't generate
|
||||
UART interrupts, pass -1 as the irq number. Then a timer
|
||||
interrupt will be invoked for polling.
|
||||
The 6th argument specifies the ISA irq number that will be
|
||||
allocated. If no interrupt is to be allocated (because your
|
||||
code is already allocating a shared interrupt, or because the
|
||||
device does not use interrupts), pass -1 instead.
|
||||
For a MPU-401 device without an interrupt, a polling timer
|
||||
will be used instead.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
@ -4390,12 +4395,13 @@ struct _snd_pcm_runtime {
|
|||
<title>Interrupt Handler</title>
|
||||
<para>
|
||||
When the interrupt is allocated in
|
||||
<function>snd_mpu401_uart_new()</function>, the private
|
||||
interrupt handler is used, hence you don't have anything else to do
|
||||
than creating the mpu401 stuff. Otherwise, you have to call
|
||||
<function>snd_mpu401_uart_interrupt()</function> explicitly when
|
||||
a UART interrupt is invoked and checked in your own interrupt
|
||||
handler.
|
||||
<function>snd_mpu401_uart_new()</function>, an exclusive ISA
|
||||
interrupt handler is automatically used, hence you don't have
|
||||
anything else to do than creating the mpu401 stuff. Otherwise, you
|
||||
have to set <constant>MPU401_INFO_IRQ_HOOK</constant>, and call
|
||||
<function>snd_mpu401_uart_interrupt()</function> explicitly from your
|
||||
own interrupt handler when it has determined that a UART interrupt
|
||||
has occurred.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
* Freescale SGTL5000 Stereo Codec
|
||||
|
||||
Required properties:
|
||||
- compatible : "fsl,sgtl5000".
|
||||
|
||||
Example:
|
||||
|
||||
codec: sgtl5000@0a {
|
||||
compatible = "fsl,sgtl5000";
|
||||
reg = <0x0a>;
|
||||
};
|
18
Documentation/devicetree/bindings/sound/wm8510.txt
Normal file
18
Documentation/devicetree/bindings/sound/wm8510.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
WM8510 audio CODEC
|
||||
|
||||
This device supports both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8510"
|
||||
|
||||
- reg : the I2C address of the device for I2C, the chip select
|
||||
number for SPI.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8510@1a {
|
||||
compatible = "wlf,wm8510";
|
||||
reg = <0x1a>;
|
||||
};
|
16
Documentation/devicetree/bindings/sound/wm8523.txt
Normal file
16
Documentation/devicetree/bindings/sound/wm8523.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
WM8523 audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8523"
|
||||
|
||||
- reg : the I2C address of the device.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8523@1a {
|
||||
compatible = "wlf,wm8523";
|
||||
reg = <0x1a>;
|
||||
};
|
16
Documentation/devicetree/bindings/sound/wm8580.txt
Normal file
16
Documentation/devicetree/bindings/sound/wm8580.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
WM8580 audio CODEC
|
||||
|
||||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8580"
|
||||
|
||||
- reg : the I2C address of the device.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8580@1a {
|
||||
compatible = "wlf,wm8580";
|
||||
reg = <0x1a>;
|
||||
};
|
18
Documentation/devicetree/bindings/sound/wm8711.txt
Normal file
18
Documentation/devicetree/bindings/sound/wm8711.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
WM8711 audio CODEC
|
||||
|
||||
This device supports both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8711"
|
||||
|
||||
- reg : the I2C address of the device for I2C, the chip select
|
||||
number for SPI.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8711@1a {
|
||||
compatible = "wlf,wm8711";
|
||||
reg = <0x1a>;
|
||||
};
|
18
Documentation/devicetree/bindings/sound/wm8728.txt
Normal file
18
Documentation/devicetree/bindings/sound/wm8728.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
WM8728 audio CODEC
|
||||
|
||||
This device supports both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8728"
|
||||
|
||||
- reg : the I2C address of the device for I2C, the chip select
|
||||
number for SPI.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8728@1a {
|
||||
compatible = "wlf,wm8728";
|
||||
reg = <0x1a>;
|
||||
};
|
18
Documentation/devicetree/bindings/sound/wm8731.txt
Normal file
18
Documentation/devicetree/bindings/sound/wm8731.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
WM8731 audio CODEC
|
||||
|
||||
This device supports both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8731"
|
||||
|
||||
- reg : the I2C address of the device for I2C, the chip select
|
||||
number for SPI.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8731@1a {
|
||||
compatible = "wlf,wm8731";
|
||||
reg = <0x1a>;
|
||||
};
|
18
Documentation/devicetree/bindings/sound/wm8737.txt
Normal file
18
Documentation/devicetree/bindings/sound/wm8737.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
WM8737 audio CODEC
|
||||
|
||||
This device supports both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8737"
|
||||
|
||||
- reg : the I2C address of the device for I2C, the chip select
|
||||
number for SPI.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8737@1a {
|
||||
compatible = "wlf,wm8737";
|
||||
reg = <0x1a>;
|
||||
};
|
18
Documentation/devicetree/bindings/sound/wm8741.txt
Normal file
18
Documentation/devicetree/bindings/sound/wm8741.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
WM8741 audio CODEC
|
||||
|
||||
This device supports both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8741"
|
||||
|
||||
- reg : the I2C address of the device for I2C, the chip select
|
||||
number for SPI.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8741@1a {
|
||||
compatible = "wlf,wm8741";
|
||||
reg = <0x1a>;
|
||||
};
|
18
Documentation/devicetree/bindings/sound/wm8750.txt
Normal file
18
Documentation/devicetree/bindings/sound/wm8750.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
WM8750 and WM8987 audio CODECs
|
||||
|
||||
These devices support both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8750" or "wlf,wm8987"
|
||||
|
||||
- reg : the I2C address of the device for I2C, the chip select
|
||||
number for SPI.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8750@1a {
|
||||
compatible = "wlf,wm8750";
|
||||
reg = <0x1a>;
|
||||
};
|
18
Documentation/devicetree/bindings/sound/wm8753.txt
Normal file
18
Documentation/devicetree/bindings/sound/wm8753.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
WM8753 audio CODEC
|
||||
|
||||
This device supports both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8753"
|
||||
|
||||
- reg : the I2C address of the device for I2C, the chip select
|
||||
number for SPI.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8737@1a {
|
||||
compatible = "wlf,wm8753";
|
||||
reg = <0x1a>;
|
||||
};
|
16
Documentation/devicetree/bindings/sound/wm8770.txt
Normal file
16
Documentation/devicetree/bindings/sound/wm8770.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
WM8770 audio CODEC
|
||||
|
||||
This device supports SPI.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8770"
|
||||
|
||||
- reg : the chip select number.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8770@1 {
|
||||
compatible = "wlf,wm8770";
|
||||
reg = <1>;
|
||||
};
|
18
Documentation/devicetree/bindings/sound/wm8776.txt
Normal file
18
Documentation/devicetree/bindings/sound/wm8776.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
WM8776 audio CODEC
|
||||
|
||||
This device supports both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8776"
|
||||
|
||||
- reg : the I2C address of the device for I2C, the chip select
|
||||
number for SPI.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8776@1a {
|
||||
compatible = "wlf,wm8776";
|
||||
reg = <0x1a>;
|
||||
};
|
18
Documentation/devicetree/bindings/sound/wm8804.txt
Normal file
18
Documentation/devicetree/bindings/sound/wm8804.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
WM8804 audio CODEC
|
||||
|
||||
This device supports both I2C and SPI (configured with pin strapping
|
||||
on the board).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "wlf,wm8804"
|
||||
|
||||
- reg : the I2C address of the device for I2C, the chip select
|
||||
number for SPI.
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8804@1a {
|
||||
compatible = "wlf,wm8804";
|
||||
reg = <0x1a>;
|
||||
};
|
|
@ -886,6 +886,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
|||
disable)
|
||||
power_save_controller - Reset HD-audio controller in power-saving mode
|
||||
(default = on)
|
||||
align_buffer_size - Force rounding of buffer/period sizes to multiples
|
||||
of 128 bytes. This is more efficient in terms of memory
|
||||
access but isn't required by the HDA spec and prevents
|
||||
users from specifying exact period/buffer sizes.
|
||||
(default = on)
|
||||
snoop - Enable/disable snooping (default = on)
|
||||
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
|
|
|
@ -98,3 +98,19 @@ Conexant codecs
|
|||
|
||||
* Auto-Mute Mode
|
||||
See Reatek codecs.
|
||||
|
||||
|
||||
Analog codecs
|
||||
--------------
|
||||
|
||||
* Channel Mode
|
||||
This is an enum control to change the surround-channel setup,
|
||||
appears only when the surround channels are available.
|
||||
It gives the number of channels to be used, "2ch", "4ch" and "6ch".
|
||||
According to the configuration, this also controls the
|
||||
jack-retasking of multi-I/O jacks.
|
||||
|
||||
* Independent HP
|
||||
When this enum control is enabled, the headphone output is routed
|
||||
from an individual stream (the third PCM such as hw:0,2) instead of
|
||||
the primary stream.
|
||||
|
|
|
@ -29,9 +29,6 @@ ALC880
|
|||
|
||||
ALC260
|
||||
======
|
||||
hp HP machines
|
||||
hp-3013 HP machines (3013-variant)
|
||||
hp-dc7600 HP DC7600
|
||||
fujitsu Fujitsu S7020
|
||||
acer Acer TravelMate
|
||||
will Will laptops (PB V7900)
|
||||
|
@ -46,15 +43,10 @@ ALC260
|
|||
ALC262
|
||||
======
|
||||
fujitsu Fujitsu Laptop
|
||||
hp-bpc HP xw4400/6400/8400/9400 laptops
|
||||
hp-bpc-d7000 HP BPC D7000
|
||||
hp-tc-t5735 HP Thin Client T5735
|
||||
hp-rp5700 HP RP5700
|
||||
benq Benq ED8
|
||||
benq-t31 Benq T31
|
||||
hippo Hippo (ATI) with jack detection, Sony UX-90s
|
||||
hippo_1 Hippo (Benq) with jack detection
|
||||
sony-assamd Sony ASSAMD
|
||||
toshiba-s06 Toshiba S06
|
||||
toshiba-rx1 Toshiba RX1
|
||||
tyan Tyan Thunder n6650W (S2915-E)
|
||||
|
@ -66,43 +58,15 @@ ALC262
|
|||
|
||||
ALC267/268
|
||||
==========
|
||||
quanta-il1 Quanta IL1 mini-notebook
|
||||
3stack 3-stack model
|
||||
toshiba Toshiba A205
|
||||
acer Acer laptops
|
||||
acer-dmic Acer laptops with digital-mic
|
||||
acer-aspire Acer Aspire One
|
||||
dell Dell OEM laptops (Vostro 1200)
|
||||
zepto Zepto laptops
|
||||
test for testing/debugging purpose, almost all controls can
|
||||
adjusted. Appearing only when compiled with
|
||||
$CONFIG_SND_DEBUG=y
|
||||
auto auto-config reading BIOS (default)
|
||||
N/A
|
||||
|
||||
ALC269
|
||||
======
|
||||
basic Basic preset
|
||||
quanta Quanta FL1
|
||||
laptop-amic Laptops with analog-mic input
|
||||
laptop-dmic Laptops with digital-mic input
|
||||
fujitsu FSC Amilo
|
||||
lifebook Fujitsu Lifebook S6420
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC662/663/272
|
||||
==============
|
||||
3stack-dig 3-stack (2-channel) with SPDIF
|
||||
3stack-6ch 3-stack (6-channel)
|
||||
3stack-6ch-dig 3-stack (6-channel) with SPDIF
|
||||
5stack-dig 5-stack with SPDIF
|
||||
lenovo-101e Lenovo laptop
|
||||
eeepc-p701 ASUS Eeepc P701
|
||||
eeepc-ep20 ASUS Eeepc EP20
|
||||
ecs ECS/Foxconn mobo
|
||||
m51va ASUS M51VA
|
||||
g71v ASUS G71V
|
||||
h13 ASUS H13
|
||||
g50v ASUS G50V
|
||||
asus-mode1 ASUS
|
||||
asus-mode2 ASUS
|
||||
asus-mode3 ASUS
|
||||
|
@ -111,15 +75,10 @@ ALC662/663/272
|
|||
asus-mode6 ASUS
|
||||
asus-mode7 ASUS
|
||||
asus-mode8 ASUS
|
||||
dell Dell with ALC272
|
||||
dell-zm1 Dell ZM1 with ALC272
|
||||
samsung-nc10 Samsung NC10 mini notebook
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC680
|
||||
======
|
||||
base Base model (ASUS NX90)
|
||||
auto auto-config reading BIOS (default)
|
||||
N/A
|
||||
|
||||
ALC882/883/885/888/889
|
||||
======================
|
||||
|
@ -175,28 +134,11 @@ ALC882/883/885/888/889
|
|||
|
||||
ALC861/660
|
||||
==========
|
||||
3stack 3-jack
|
||||
3stack-dig 3-jack with SPDIF I/O
|
||||
6stack-dig 6-jack with SPDIF I/O
|
||||
3stack-660 3-jack (for ALC660)
|
||||
uniwill-m31 Uniwill M31 laptop
|
||||
toshiba Toshiba laptop support
|
||||
asus Asus laptop support
|
||||
asus-laptop ASUS F2/F3 laptops
|
||||
auto auto-config reading BIOS (default)
|
||||
N/A
|
||||
|
||||
ALC861VD/660VD
|
||||
==============
|
||||
3stack 3-jack
|
||||
3stack-dig 3-jack with SPDIF OUT
|
||||
6stack-dig 6-jack with SPDIF OUT
|
||||
3stack-660 3-jack (for ALC660VD)
|
||||
3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD)
|
||||
lenovo Lenovo 3000 C200
|
||||
dallas Dallas laptops
|
||||
hp HP TX1000
|
||||
asus-v1s ASUS V1Sn
|
||||
auto auto-config reading BIOS (default)
|
||||
N/A
|
||||
|
||||
CMI9880
|
||||
=======
|
||||
|
@ -289,7 +231,6 @@ Conexant 5051
|
|||
hp-dv6736 HP dv6736
|
||||
hp-f700 HP Compaq Presario F700
|
||||
ideapad Lenovo IdeaPad laptop
|
||||
lenovo-x200 Lenovo X200 laptop
|
||||
toshiba Toshiba Satellite M300
|
||||
|
||||
Conexant 5066
|
||||
|
|
|
@ -447,7 +447,10 @@ The file needs to have a line `[codec]`. The next line should contain
|
|||
three numbers indicating the codec vendor-id (0x12345678 in the
|
||||
example), the codec subsystem-id (0xabcd1234) and the address (2) of
|
||||
the codec. The rest patch entries are applied to this specified codec
|
||||
until another codec entry is given.
|
||||
until another codec entry is given. Passing 0 or a negative number to
|
||||
the first or the second value will make the check of the corresponding
|
||||
field be skipped. It'll be useful for really broken devices that don't
|
||||
initialize SSID properly.
|
||||
|
||||
The `[model]` line allows to change the model name of the each codec.
|
||||
In the example above, it will be changed to model=auto.
|
||||
|
@ -491,7 +494,7 @@ Also, the codec chip name can be rewritten via `[chip_name]` line.
|
|||
The hd-audio driver reads the file via request_firmware(). Thus,
|
||||
a patch file has to be located on the appropriate firmware path,
|
||||
typically, /lib/firmware. For example, when you pass the option
|
||||
`patch=hda-init.fw`, the file /lib/firmware/hda-init-fw must be
|
||||
`patch=hda-init.fw`, the file /lib/firmware/hda-init.fw must be
|
||||
present.
|
||||
|
||||
The patch module option is specific to each card instance, and you
|
||||
|
@ -524,6 +527,54 @@ power-saving. See /sys/module/snd_hda_intel/parameters/power_save to
|
|||
check the current value. If it's non-zero, the feature is turned on.
|
||||
|
||||
|
||||
Tracepoints
|
||||
~~~~~~~~~~~
|
||||
The hd-audio driver gives a few basic tracepoints.
|
||||
`hda:hda_send_cmd` traces each CORB write while `hda:hda_get_response`
|
||||
traces the response from RIRB (only when read from the codec driver).
|
||||
`hda:hda_bus_reset` traces the bus-reset due to fatal error, etc,
|
||||
`hda:hda_unsol_event` traces the unsolicited events, and
|
||||
`hda:hda_power_down` and `hda:hda_power_up` trace the power down/up
|
||||
via power-saving behavior.
|
||||
|
||||
Enabling all tracepoints can be done like
|
||||
------------------------------------------------------------------------
|
||||
# echo 1 > /sys/kernel/debug/tracing/events/hda/enable
|
||||
------------------------------------------------------------------------
|
||||
then after some commands, you can traces from
|
||||
/sys/kernel/debug/tracing/trace file. For example, when you want to
|
||||
trace what codec command is sent, enable the tracepoint like:
|
||||
------------------------------------------------------------------------
|
||||
# cat /sys/kernel/debug/tracing/trace
|
||||
# tracer: nop
|
||||
#
|
||||
# TASK-PID CPU# TIMESTAMP FUNCTION
|
||||
# | | | | |
|
||||
<...>-7807 [002] 105147.774889: hda_send_cmd: [0:0] val=e3a019
|
||||
<...>-7807 [002] 105147.774893: hda_send_cmd: [0:0] val=e39019
|
||||
<...>-7807 [002] 105147.999542: hda_send_cmd: [0:0] val=e3a01a
|
||||
<...>-7807 [002] 105147.999543: hda_send_cmd: [0:0] val=e3901a
|
||||
<...>-26764 [001] 349222.837143: hda_send_cmd: [0:0] val=e3a019
|
||||
<...>-26764 [001] 349222.837148: hda_send_cmd: [0:0] val=e39019
|
||||
<...>-26764 [001] 349223.058539: hda_send_cmd: [0:0] val=e3a01a
|
||||
<...>-26764 [001] 349223.058541: hda_send_cmd: [0:0] val=e3901a
|
||||
------------------------------------------------------------------------
|
||||
Here `[0:0]` indicates the card number and the codec address, and
|
||||
`val` shows the value sent to the codec, respectively. The value is
|
||||
a packed value, and you can decode it via hda-decode-verb program
|
||||
included in hda-emu package below. For example, the value e3a019 is
|
||||
to set the left output-amp value to 25.
|
||||
------------------------------------------------------------------------
|
||||
% hda-decode-verb 0xe3a019
|
||||
raw value = 0x00e3a019
|
||||
cid = 0, nid = 0x0e, verb = 0x3a0, parm = 0x19
|
||||
raw value: verb = 0x3a0, parm = 0x19
|
||||
verbname = set_amp_gain_mute
|
||||
amp raw val = 0xa019
|
||||
output, left, idx=0, mute=0, val=25
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
Development Tree
|
||||
~~~~~~~~~~~~~~~~
|
||||
The latest development codes for HD-audio are found on sound git tree:
|
||||
|
|
|
@ -529,6 +529,7 @@ S: Maintained
|
|||
F: drivers/infiniband/hw/amso1100/
|
||||
|
||||
ANALOG DEVICES INC ASOC CODEC DRIVERS
|
||||
M: Lars-Peter Clausen <lars@metafoo.de>
|
||||
L: device-drivers-devel@blackfin.uclinux.org
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
W: http://wiki.analog.com/
|
||||
|
@ -6038,7 +6039,7 @@ M: Jaroslav Kysela <perex@perex.cz>
|
|||
M: Takashi Iwai <tiwai@suse.de>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
W: http://www.alsa-project.org/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
|
||||
T: git git://git.alsa-project.org/alsa-kernel.git
|
||||
S: Maintained
|
||||
F: Documentation/sound/
|
||||
|
@ -7259,6 +7260,7 @@ T: git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
|
|||
W: http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices
|
||||
S: Supported
|
||||
F: Documentation/hwmon/wm83??
|
||||
F: arch/arm/mach-s3c64xx/mach-crag6410*
|
||||
F: drivers/leds/leds-wm83*.c
|
||||
F: drivers/input/misc/wm831x-on.c
|
||||
F: drivers/input/touchscreen/wm831x-ts.c
|
||||
|
|
|
@ -160,6 +160,11 @@ static void __init edb93xx_register_spi(void)
|
|||
/*************************************************************************
|
||||
* EDB93xx I2S
|
||||
*************************************************************************/
|
||||
static struct platform_device edb93xx_audio_device = {
|
||||
.name = "edb93xx-audio",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static int __init edb93xx_has_audio(void)
|
||||
{
|
||||
return (machine_is_edb9301() || machine_is_edb9302() ||
|
||||
|
@ -171,6 +176,7 @@ static void __init edb93xx_register_i2s(void)
|
|||
{
|
||||
if (edb93xx_has_audio()) {
|
||||
ep93xx_register_i2s();
|
||||
platform_device_register(&edb93xx_audio_device);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,17 @@ static struct i2c_board_info __initdata simone_i2c_board_info[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct platform_device simone_audio_device = {
|
||||
.name = "simone-audio",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static void __init simone_register_audio(void)
|
||||
{
|
||||
ep93xx_register_ac97();
|
||||
platform_device_register(&simone_audio_device);
|
||||
}
|
||||
|
||||
static void __init simone_init_machine(void)
|
||||
{
|
||||
ep93xx_init_devices();
|
||||
|
@ -61,7 +72,7 @@ static void __init simone_init_machine(void)
|
|||
ep93xx_register_fb(&simone_fb_info);
|
||||
ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
|
||||
ARRAY_SIZE(simone_i2c_board_info));
|
||||
ep93xx_register_ac97();
|
||||
simone_register_audio();
|
||||
}
|
||||
|
||||
MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
|
||||
|
|
|
@ -150,6 +150,17 @@ static struct ep93xxfb_mach_info __initdata snappercl15_fb_info = {
|
|||
.bpp = 16,
|
||||
};
|
||||
|
||||
static struct platform_device snappercl15_audio_device = {
|
||||
.name = "snappercl15-audio",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static void __init snappercl15_register_audio(void)
|
||||
{
|
||||
ep93xx_register_i2s();
|
||||
platform_device_register(&snappercl15_audio_device);
|
||||
}
|
||||
|
||||
static void __init snappercl15_init_machine(void)
|
||||
{
|
||||
ep93xx_init_devices();
|
||||
|
@ -157,7 +168,7 @@ static void __init snappercl15_init_machine(void)
|
|||
ep93xx_register_i2c(&snappercl15_i2c_gpio_data, snappercl15_i2c_data,
|
||||
ARRAY_SIZE(snappercl15_i2c_data));
|
||||
ep93xx_register_fb(&snappercl15_fb_info);
|
||||
ep93xx_register_i2s();
|
||||
snappercl15_register_audio();
|
||||
platform_device_register(&snappercl15_nand_device);
|
||||
}
|
||||
|
||||
|
|
|
@ -900,7 +900,6 @@ static struct twl4030_platform_data rx51_twldata __initdata = {
|
|||
};
|
||||
|
||||
static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = {
|
||||
.id = TPA6130A2,
|
||||
.power_gpio = 98,
|
||||
};
|
||||
|
||||
|
|
|
@ -329,6 +329,38 @@ static void omap_init_audio(void)
|
|||
static inline void omap_init_audio(void) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
|
||||
|
||||
static struct omap_device_pm_latency omap_mcpdm_latency[] = {
|
||||
{
|
||||
.deactivate_func = omap_device_idle_hwmods,
|
||||
.activate_func = omap_device_enable_hwmods,
|
||||
.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
|
||||
},
|
||||
};
|
||||
|
||||
static void omap_init_mcpdm(void)
|
||||
{
|
||||
struct omap_hwmod *oh;
|
||||
struct omap_device *od;
|
||||
|
||||
oh = omap_hwmod_lookup("mcpdm");
|
||||
if (!oh) {
|
||||
printk(KERN_ERR "Could not look up mcpdm hw_mod\n");
|
||||
return;
|
||||
}
|
||||
|
||||
od = omap_device_build("omap-mcpdm", -1, oh, NULL, 0,
|
||||
omap_mcpdm_latency,
|
||||
ARRAY_SIZE(omap_mcpdm_latency), 0);
|
||||
if (IS_ERR(od))
|
||||
printk(KERN_ERR "Could not build omap_device for omap-mcpdm-dai\n");
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_mcpdm(void) {}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
|
||||
|
||||
#include <plat/mcspi.h>
|
||||
|
@ -682,6 +714,7 @@ static int __init omap2_init_devices(void)
|
|||
* in alphabetical order so they're easier to sort through.
|
||||
*/
|
||||
omap_init_audio();
|
||||
omap_init_mcpdm();
|
||||
omap_init_camera();
|
||||
omap_init_mbox();
|
||||
omap_init_mcspi();
|
||||
|
|
|
@ -5430,7 +5430,7 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
|
|||
&omap44xx_mcbsp4_hwmod,
|
||||
|
||||
/* mcpdm class */
|
||||
/* &omap44xx_mcpdm_hwmod, */
|
||||
&omap44xx_mcpdm_hwmod,
|
||||
|
||||
/* mcspi class */
|
||||
&omap44xx_mcspi1_hwmod,
|
||||
|
|
|
@ -73,41 +73,6 @@ void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
|
||||
defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
|
||||
|
||||
static struct resource mcpdm_resources[] = {
|
||||
{
|
||||
.name = "mcpdm_mem",
|
||||
.start = OMAP44XX_MCPDM_BASE,
|
||||
.end = OMAP44XX_MCPDM_BASE + SZ_4K,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "mcpdm_irq",
|
||||
.start = OMAP44XX_IRQ_MCPDM,
|
||||
.end = OMAP44XX_IRQ_MCPDM,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device omap_mcpdm_device = {
|
||||
.name = "omap-mcpdm",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(mcpdm_resources),
|
||||
.resource = mcpdm_resources,
|
||||
};
|
||||
|
||||
static void omap_init_mcpdm(void)
|
||||
{
|
||||
(void) platform_device_register(&omap_mcpdm_device);
|
||||
}
|
||||
#else
|
||||
static inline void omap_init_mcpdm(void) {}
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
|
||||
defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
|
||||
|
||||
|
@ -290,7 +255,6 @@ static int __init omap_init_devices(void)
|
|||
* in alphabetical order so they're easier to sort through.
|
||||
*/
|
||||
omap_init_rng();
|
||||
omap_init_mcpdm();
|
||||
omap_init_uwire();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -422,6 +422,7 @@ static struct resource au1200_psc1_res[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/* AC97 or I2S device */
|
||||
static struct platform_device db1200_audio_dev = {
|
||||
/* name assigned later based on switch setting */
|
||||
.id = 1, /* PSC ID */
|
||||
|
@ -429,19 +430,32 @@ static struct platform_device db1200_audio_dev = {
|
|||
.resource = au1200_psc1_res,
|
||||
};
|
||||
|
||||
/* DB1200 ASoC card device */
|
||||
static struct platform_device db1200_sound_dev = {
|
||||
/* name assigned later based on switch setting */
|
||||
.id = 1, /* PSC ID */
|
||||
};
|
||||
|
||||
static struct platform_device db1200_stac_dev = {
|
||||
.name = "ac97-codec",
|
||||
.id = 1, /* on PSC1 */
|
||||
};
|
||||
|
||||
static struct platform_device db1200_audiodma_dev = {
|
||||
.name = "au1xpsc-pcm",
|
||||
.id = 1, /* PSC ID */
|
||||
};
|
||||
|
||||
static struct platform_device *db1200_devs[] __initdata = {
|
||||
NULL, /* PSC0, selected by S6.8 */
|
||||
&db1200_ide_dev,
|
||||
&db1200_eth_dev,
|
||||
&db1200_rtc_dev,
|
||||
&db1200_nand_dev,
|
||||
&db1200_audiodma_dev,
|
||||
&db1200_audio_dev,
|
||||
&db1200_stac_dev,
|
||||
&db1200_sound_dev,
|
||||
};
|
||||
|
||||
static int __init db1200_dev_init(void)
|
||||
|
@ -501,10 +515,12 @@ static int __init db1200_dev_init(void)
|
|||
if (sw == BCSR_SWITCHES_DIP_8) {
|
||||
bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX);
|
||||
db1200_audio_dev.name = "au1xpsc_i2s";
|
||||
db1200_sound_dev.name = "db1200-i2s";
|
||||
printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n");
|
||||
} else {
|
||||
bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0);
|
||||
db1200_audio_dev.name = "au1xpsc_ac97";
|
||||
db1200_sound_dev.name = "db1200-ac97";
|
||||
printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,11 @@
|
|||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/mach-au1x00/au1000.h>
|
||||
#include <asm/mach-au1x00/au1000_dma.h>
|
||||
#include <asm/mach-au1x00/au1xxx.h>
|
||||
#include <asm/mach-db1x00/bcsr.h>
|
||||
#include "../platform.h"
|
||||
|
@ -85,6 +88,45 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
static struct resource alchemy_ac97c_res[] = {
|
||||
[0] = {
|
||||
.start = AU1000_AC97_PHYS_ADDR,
|
||||
.end = AU1000_AC97_PHYS_ADDR + 0xfff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = DMA_ID_AC97C_TX,
|
||||
.end = DMA_ID_AC97C_TX,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = DMA_ID_AC97C_RX,
|
||||
.end = DMA_ID_AC97C_RX,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device alchemy_ac97c_dev = {
|
||||
.name = "alchemy-ac97c",
|
||||
.id = -1,
|
||||
.resource = alchemy_ac97c_res,
|
||||
.num_resources = ARRAY_SIZE(alchemy_ac97c_res),
|
||||
};
|
||||
|
||||
static struct platform_device alchemy_ac97c_dma_dev = {
|
||||
.name = "alchemy-pcm-dma",
|
||||
.id = 0,
|
||||
};
|
||||
|
||||
static struct platform_device db1x00_codec_dev = {
|
||||
.name = "ac97-codec",
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
static struct platform_device db1x00_audio_dev = {
|
||||
.name = "db1000-audio",
|
||||
};
|
||||
|
||||
static int __init db1xxx_dev_init(void)
|
||||
{
|
||||
#ifdef DB1XXX_HAS_PCMCIA
|
||||
|
@ -113,6 +155,12 @@ static int __init db1xxx_dev_init(void)
|
|||
1);
|
||||
#endif
|
||||
db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED);
|
||||
|
||||
platform_device_register(&db1x00_codec_dev);
|
||||
platform_device_register(&alchemy_ac97c_dma_dev);
|
||||
platform_device_register(&alchemy_ac97c_dev);
|
||||
platform_device_register(&db1x00_audio_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
device_initcall(db1xxx_dev_init);
|
||||
|
|
|
@ -74,12 +74,12 @@ static irqreturn_t twl6040_vib_irq_handler(int irq, void *data)
|
|||
if (status & TWL6040_VIBLOCDET) {
|
||||
dev_warn(info->dev, "Left Vibrator overcurrent detected\n");
|
||||
twl6040_clear_bits(twl6040, TWL6040_REG_VIBCTLL,
|
||||
TWL6040_VIBENAL);
|
||||
TWL6040_VIBENA);
|
||||
}
|
||||
if (status & TWL6040_VIBROCDET) {
|
||||
dev_warn(info->dev, "Right Vibrator overcurrent detected\n");
|
||||
twl6040_clear_bits(twl6040, TWL6040_REG_VIBCTLR,
|
||||
TWL6040_VIBENAR);
|
||||
TWL6040_VIBENA);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
@ -97,23 +97,23 @@ static void twl6040_vibra_enable(struct vibra_info *info)
|
|||
}
|
||||
|
||||
twl6040_power(info->twl6040, 1);
|
||||
if (twl6040->rev <= TWL6040_REV_ES1_1) {
|
||||
if (twl6040_get_revid(twl6040) <= TWL6040_REV_ES1_1) {
|
||||
/*
|
||||
* ERRATA: Disable overcurrent protection for at least
|
||||
* 3ms when enabling vibrator drivers to avoid false
|
||||
* overcurrent detection
|
||||
*/
|
||||
twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL,
|
||||
TWL6040_VIBENAL | TWL6040_VIBCTRLL);
|
||||
TWL6040_VIBENA | TWL6040_VIBCTRL);
|
||||
twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR,
|
||||
TWL6040_VIBENAR | TWL6040_VIBCTRLR);
|
||||
TWL6040_VIBENA | TWL6040_VIBCTRL);
|
||||
usleep_range(3000, 3500);
|
||||
}
|
||||
|
||||
twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL,
|
||||
TWL6040_VIBENAL);
|
||||
TWL6040_VIBENA);
|
||||
twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR,
|
||||
TWL6040_VIBENAR);
|
||||
TWL6040_VIBENA);
|
||||
|
||||
info->enabled = true;
|
||||
}
|
||||
|
@ -201,6 +201,13 @@ static int vibra_play(struct input_dev *input, void *data,
|
|||
struct vibra_info *info = input_get_drvdata(input);
|
||||
int ret;
|
||||
|
||||
/* Do not allow effect, while the routing is set to use audio */
|
||||
ret = twl6040_get_vibralr_status(info->twl6040);
|
||||
if (ret & TWL6040_VIBSEL) {
|
||||
dev_info(&input->dev, "Vibra is configured for audio\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
info->weak_speed = effect->u.rumble.weak_magnitude;
|
||||
info->strong_speed = effect->u.rumble.strong_magnitude;
|
||||
info->direction = effect->direction < EFFECT_DIR_180_DEG ? 1 : -1;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/twl6040.h>
|
||||
|
||||
static struct platform_device *twl6040_dev;
|
||||
#define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1)
|
||||
|
||||
int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
|
||||
{
|
||||
|
@ -42,10 +42,16 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
|
|||
u8 val = 0;
|
||||
|
||||
mutex_lock(&twl6040->io_mutex);
|
||||
ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&twl6040->io_mutex);
|
||||
return ret;
|
||||
/* Vibra control registers from cache */
|
||||
if (unlikely(reg == TWL6040_REG_VIBCTLL ||
|
||||
reg == TWL6040_REG_VIBCTLR)) {
|
||||
val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)];
|
||||
} else {
|
||||
ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&twl6040->io_mutex);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&twl6040->io_mutex);
|
||||
|
||||
|
@ -59,6 +65,9 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val)
|
|||
|
||||
mutex_lock(&twl6040->io_mutex);
|
||||
ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
|
||||
/* Cache the vibra control registers */
|
||||
if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR)
|
||||
twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val;
|
||||
mutex_unlock(&twl6040->io_mutex);
|
||||
|
||||
return ret;
|
||||
|
@ -203,11 +212,11 @@ static irqreturn_t twl6040_naudint_handler(int irq, void *data)
|
|||
if (intid & TWL6040_THINT) {
|
||||
status = twl6040_reg_read(twl6040, TWL6040_REG_STATUS);
|
||||
if (status & TWL6040_TSHUTDET) {
|
||||
dev_warn(&twl6040_dev->dev,
|
||||
dev_warn(twl6040->dev,
|
||||
"Thermal shutdown, powering-off");
|
||||
twl6040_power(twl6040, 0);
|
||||
} else {
|
||||
dev_warn(&twl6040_dev->dev,
|
||||
dev_warn(twl6040->dev,
|
||||
"Leaving thermal shutdown, powering-on");
|
||||
twl6040_power(twl6040, 1);
|
||||
}
|
||||
|
@ -227,7 +236,7 @@ static int twl6040_power_up_completion(struct twl6040 *twl6040,
|
|||
if (!time_left) {
|
||||
intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID);
|
||||
if (!(intid & TWL6040_READYINT)) {
|
||||
dev_err(&twl6040_dev->dev,
|
||||
dev_err(twl6040->dev,
|
||||
"timeout waiting for READYINT\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
@ -255,7 +264,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
|
|||
/* wait for power-up completion */
|
||||
ret = twl6040_power_up_completion(twl6040, naudint);
|
||||
if (ret) {
|
||||
dev_err(&twl6040_dev->dev,
|
||||
dev_err(twl6040->dev,
|
||||
"automatic power-down failed\n");
|
||||
twl6040->power_count = 0;
|
||||
goto out;
|
||||
|
@ -264,7 +273,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
|
|||
/* use manual power-up sequence */
|
||||
ret = twl6040_power_up(twl6040);
|
||||
if (ret) {
|
||||
dev_err(&twl6040_dev->dev,
|
||||
dev_err(twl6040->dev,
|
||||
"manual power-up failed\n");
|
||||
twl6040->power_count = 0;
|
||||
goto out;
|
||||
|
@ -276,7 +285,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
|
|||
} else {
|
||||
/* already powered-down */
|
||||
if (!twl6040->power_count) {
|
||||
dev_err(&twl6040_dev->dev,
|
||||
dev_err(twl6040->dev,
|
||||
"device is already powered-off\n");
|
||||
ret = -EPERM;
|
||||
goto out;
|
||||
|
@ -326,7 +335,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
|
|||
lppllctl &= ~TWL6040_LPLLFIN;
|
||||
break;
|
||||
default:
|
||||
dev_err(&twl6040_dev->dev,
|
||||
dev_err(twl6040->dev,
|
||||
"freq_out %d not supported\n", freq_out);
|
||||
ret = -EINVAL;
|
||||
goto pll_out;
|
||||
|
@ -347,7 +356,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
|
|||
hppllctl);
|
||||
break;
|
||||
default:
|
||||
dev_err(&twl6040_dev->dev,
|
||||
dev_err(twl6040->dev,
|
||||
"freq_in %d not supported\n", freq_in);
|
||||
ret = -EINVAL;
|
||||
goto pll_out;
|
||||
|
@ -356,7 +365,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
|
|||
case TWL6040_SYSCLK_SEL_HPPLL:
|
||||
/* high-performance PLL can provide only 19.2 MHz */
|
||||
if (freq_out != 19200000) {
|
||||
dev_err(&twl6040_dev->dev,
|
||||
dev_err(twl6040->dev,
|
||||
"freq_out %d not supported\n", freq_out);
|
||||
ret = -EINVAL;
|
||||
goto pll_out;
|
||||
|
@ -389,7 +398,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
|
|||
TWL6040_HPLLENA;
|
||||
break;
|
||||
default:
|
||||
dev_err(&twl6040_dev->dev,
|
||||
dev_err(twl6040->dev,
|
||||
"freq_in %d not supported\n", freq_in);
|
||||
ret = -EINVAL;
|
||||
goto pll_out;
|
||||
|
@ -406,7 +415,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
|
|||
twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl);
|
||||
break;
|
||||
default:
|
||||
dev_err(&twl6040_dev->dev, "unknown pll id %d\n", pll_id);
|
||||
dev_err(twl6040->dev, "unknown pll id %d\n", pll_id);
|
||||
ret = -EINVAL;
|
||||
goto pll_out;
|
||||
}
|
||||
|
@ -435,6 +444,18 @@ unsigned int twl6040_get_sysclk(struct twl6040 *twl6040)
|
|||
}
|
||||
EXPORT_SYMBOL(twl6040_get_sysclk);
|
||||
|
||||
/* Get the combined status of the vibra control register */
|
||||
int twl6040_get_vibralr_status(struct twl6040 *twl6040)
|
||||
{
|
||||
u8 status;
|
||||
|
||||
status = twl6040->vibra_ctrl_cache[0] | twl6040->vibra_ctrl_cache[1];
|
||||
status &= (TWL6040_VIBENA | TWL6040_VIBSEL);
|
||||
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL(twl6040_get_vibralr_status);
|
||||
|
||||
static struct resource twl6040_vibra_rsrc[] = {
|
||||
{
|
||||
.flags = IORESOURCE_IRQ,
|
||||
|
@ -471,9 +492,7 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, twl6040);
|
||||
|
||||
twl6040_dev = pdev;
|
||||
twl6040->dev = &pdev->dev;
|
||||
twl6040->audpwron = pdata->audpwron_gpio;
|
||||
twl6040->irq = pdata->naudint_irq;
|
||||
twl6040->irq_base = pdata->irq_base;
|
||||
|
||||
|
@ -483,6 +502,12 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
|
|||
|
||||
twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV);
|
||||
|
||||
/* ERRATA: Automatic power-up is not possible in ES1.0 */
|
||||
if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0)
|
||||
twl6040->audpwron = pdata->audpwron_gpio;
|
||||
else
|
||||
twl6040->audpwron = -EINVAL;
|
||||
|
||||
if (gpio_is_valid(twl6040->audpwron)) {
|
||||
ret = gpio_request(twl6040->audpwron, "audpwron");
|
||||
if (ret)
|
||||
|
@ -493,10 +518,6 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
|
|||
goto gpio2_err;
|
||||
}
|
||||
|
||||
/* ERRATA: Automatic power-up is not possible in ES1.0 */
|
||||
if (twl6040->rev == TWL6040_REV_ES1_0)
|
||||
twl6040->audpwron = -EINVAL;
|
||||
|
||||
/* codec interrupt */
|
||||
ret = twl6040_irq_init(twl6040);
|
||||
if (ret)
|
||||
|
@ -566,7 +587,6 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
|
|||
gpio1_err:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(twl6040);
|
||||
twl6040_dev = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -586,7 +606,6 @@ static int __devexit twl6040_remove(struct platform_device *pdev)
|
|||
mfd_remove_devices(&pdev->dev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(twl6040);
|
||||
twl6040_dev = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -167,6 +167,18 @@ static struct mfd_cell wm8994_devs[] = {
|
|||
* and should be handled via the standard regulator API supply
|
||||
* management.
|
||||
*/
|
||||
static const char *wm1811_main_supplies[] = {
|
||||
"DBVDD1",
|
||||
"DBVDD2",
|
||||
"DBVDD3",
|
||||
"DCVDD",
|
||||
"AVDD1",
|
||||
"AVDD2",
|
||||
"CPVDD",
|
||||
"SPKVDD1",
|
||||
"SPKVDD2",
|
||||
};
|
||||
|
||||
static const char *wm8994_main_supplies[] = {
|
||||
"DBVDD",
|
||||
"DCVDD",
|
||||
|
@ -329,6 +341,9 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
|
|||
}
|
||||
|
||||
switch (wm8994->type) {
|
||||
case WM1811:
|
||||
wm8994->num_supplies = ARRAY_SIZE(wm1811_main_supplies);
|
||||
break;
|
||||
case WM8994:
|
||||
wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies);
|
||||
break;
|
||||
|
@ -349,6 +364,10 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
|
|||
}
|
||||
|
||||
switch (wm8994->type) {
|
||||
case WM1811:
|
||||
for (i = 0; i < ARRAY_SIZE(wm1811_main_supplies); i++)
|
||||
wm8994->supplies[i].supply = wm1811_main_supplies[i];
|
||||
break;
|
||||
case WM8994:
|
||||
for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)
|
||||
wm8994->supplies[i].supply = wm8994_main_supplies[i];
|
||||
|
@ -382,6 +401,13 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
|
|||
goto err_enable;
|
||||
}
|
||||
switch (ret) {
|
||||
case 0x1811:
|
||||
devname = "WM1811";
|
||||
if (wm8994->type != WM1811)
|
||||
dev_warn(wm8994->dev, "Device registered as type %d\n",
|
||||
wm8994->type);
|
||||
wm8994->type = WM1811;
|
||||
break;
|
||||
case 0x8994:
|
||||
devname = "WM8994";
|
||||
if (wm8994->type != WM8994)
|
||||
|
@ -539,6 +565,7 @@ static int wm8994_i2c_remove(struct i2c_client *i2c)
|
|||
}
|
||||
|
||||
static const struct i2c_device_id wm8994_i2c_id[] = {
|
||||
{ "wm1811", WM1811 },
|
||||
{ "wm8994", WM8994 },
|
||||
{ "wm8958", WM8958 },
|
||||
{ }
|
||||
|
|
|
@ -1552,6 +1552,68 @@ int regulator_force_disable(struct regulator *regulator)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_force_disable);
|
||||
|
||||
static void regulator_disable_work(struct work_struct *work)
|
||||
{
|
||||
struct regulator_dev *rdev = container_of(work, struct regulator_dev,
|
||||
disable_work.work);
|
||||
int count, i, ret;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
|
||||
BUG_ON(!rdev->deferred_disables);
|
||||
|
||||
count = rdev->deferred_disables;
|
||||
rdev->deferred_disables = 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = _regulator_disable(rdev);
|
||||
if (ret != 0)
|
||||
rdev_err(rdev, "Deferred disable failed: %d\n", ret);
|
||||
}
|
||||
|
||||
mutex_unlock(&rdev->mutex);
|
||||
|
||||
if (rdev->supply) {
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = regulator_disable(rdev->supply);
|
||||
if (ret != 0) {
|
||||
rdev_err(rdev,
|
||||
"Supply disable failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* regulator_disable_deferred - disable regulator output with delay
|
||||
* @regulator: regulator source
|
||||
* @ms: miliseconds until the regulator is disabled
|
||||
*
|
||||
* Execute regulator_disable() on the regulator after a delay. This
|
||||
* is intended for use with devices that require some time to quiesce.
|
||||
*
|
||||
* NOTE: this will only disable the regulator output if no other consumer
|
||||
* devices have it enabled, the regulator device supports disabling and
|
||||
* machine constraints permit this operation.
|
||||
*/
|
||||
int regulator_disable_deferred(struct regulator *regulator, int ms)
|
||||
{
|
||||
struct regulator_dev *rdev = regulator->rdev;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
rdev->deferred_disables++;
|
||||
mutex_unlock(&rdev->mutex);
|
||||
|
||||
ret = schedule_delayed_work(&rdev->disable_work,
|
||||
msecs_to_jiffies(ms));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regulator_disable_deferred);
|
||||
|
||||
static int _regulator_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
/* If we don't know then assume that the regulator is always on */
|
||||
|
@ -2622,6 +2684,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
|||
INIT_LIST_HEAD(&rdev->consumer_list);
|
||||
INIT_LIST_HEAD(&rdev->list);
|
||||
BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
|
||||
INIT_DELAYED_WORK(&rdev->disable_work, regulator_disable_work);
|
||||
|
||||
/* preform any regulator specific init */
|
||||
if (init_data->regulator_init) {
|
||||
|
@ -2729,6 +2792,7 @@ void regulator_unregister(struct regulator_dev *rdev)
|
|||
#ifdef CONFIG_DEBUG_FS
|
||||
debugfs_remove_recursive(rdev->debugfs);
|
||||
#endif
|
||||
flush_work_sync(&rdev->disable_work.work);
|
||||
WARN_ON(rdev->open_count);
|
||||
unset_regulator_supplies(rdev);
|
||||
list_del(&rdev->list);
|
||||
|
|
|
@ -140,6 +140,14 @@ static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev,
|
|||
return (selector * 100000) + 900000;
|
||||
case WM8958:
|
||||
return (selector * 100000) + 1000000;
|
||||
case WM1811:
|
||||
switch (selector) {
|
||||
case 0:
|
||||
return -EINVAL;
|
||||
default:
|
||||
return (selector * 100000) + 950000;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -170,6 +178,11 @@ static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev,
|
|||
case WM8958:
|
||||
selector = (min_uV - 1000000) / 100000;
|
||||
break;
|
||||
case WM1811:
|
||||
selector = (min_uV - 950000) / 100000;
|
||||
if (selector == 0)
|
||||
selector = 1;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -815,6 +815,7 @@ struct input_keymap_entry {
|
|||
#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */
|
||||
#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */
|
||||
#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
|
||||
#define SW_LINEIN_INSERT 0x0d /* set = inserted */
|
||||
#define SW_MAX 0x0f
|
||||
#define SW_CNT (SW_MAX+1)
|
||||
|
||||
|
|
|
@ -68,11 +68,6 @@
|
|||
#define TWL6040_REG_ACCCTL 0x2D
|
||||
#define TWL6040_REG_STATUS 0x2E
|
||||
|
||||
#define TWL6040_CACHEREGNUM (TWL6040_REG_STATUS + 1)
|
||||
|
||||
#define TWL6040_VIOREGNUM 18
|
||||
#define TWL6040_VDDREGNUM 21
|
||||
|
||||
/* INTID (0x03) fields */
|
||||
|
||||
#define TWL6040_THINT 0x01
|
||||
|
@ -125,34 +120,24 @@
|
|||
#define TWL6040_LPLLFIN 0x08
|
||||
#define TWL6040_HPLLSEL 0x10
|
||||
|
||||
/* HSLCTL (0x10) fields */
|
||||
/* HSLCTL/R (0x10/0x11) fields */
|
||||
|
||||
#define TWL6040_HSDACMODEL 0x02
|
||||
#define TWL6040_HSDRVMODEL 0x08
|
||||
#define TWL6040_HSDACENA (1 << 0)
|
||||
#define TWL6040_HSDACMODE (1 << 1)
|
||||
#define TWL6040_HSDRVMODE (1 << 3)
|
||||
|
||||
/* HSRCTL (0x11) fields */
|
||||
/* VIBCTLL/R (0x18/0x1A) fields */
|
||||
|
||||
#define TWL6040_HSDACMODER 0x02
|
||||
#define TWL6040_HSDRVMODER 0x08
|
||||
#define TWL6040_VIBENA (1 << 0)
|
||||
#define TWL6040_VIBSEL (1 << 1)
|
||||
#define TWL6040_VIBCTRL (1 << 2)
|
||||
#define TWL6040_VIBCTRL_P (1 << 3)
|
||||
#define TWL6040_VIBCTRL_N (1 << 4)
|
||||
|
||||
/* VIBCTLL (0x18) fields */
|
||||
|
||||
#define TWL6040_VIBENAL 0x01
|
||||
#define TWL6040_VIBCTRLL 0x04
|
||||
#define TWL6040_VIBCTRLLP 0x08
|
||||
#define TWL6040_VIBCTRLLN 0x10
|
||||
|
||||
/* VIBDATL (0x19) fields */
|
||||
/* VIBDATL/R (0x19/0x1B) fields */
|
||||
|
||||
#define TWL6040_VIBDAT_MAX 0x64
|
||||
|
||||
/* VIBCTLR (0x1A) fields */
|
||||
|
||||
#define TWL6040_VIBENAR 0x01
|
||||
#define TWL6040_VIBCTRLR 0x04
|
||||
#define TWL6040_VIBCTRLRP 0x08
|
||||
#define TWL6040_VIBCTRLRN 0x10
|
||||
|
||||
/* GPOCTL (0x1E) fields */
|
||||
|
||||
#define TWL6040_GPO1 0x01
|
||||
|
@ -200,6 +185,7 @@ struct twl6040 {
|
|||
int audpwron;
|
||||
int power_count;
|
||||
int rev;
|
||||
u8 vibra_ctrl_cache[2];
|
||||
|
||||
int pll;
|
||||
unsigned int sysclk;
|
||||
|
@ -224,5 +210,13 @@ int twl6040_get_pll(struct twl6040 *twl6040);
|
|||
unsigned int twl6040_get_sysclk(struct twl6040 *twl6040);
|
||||
int twl6040_irq_init(struct twl6040 *twl6040);
|
||||
void twl6040_irq_exit(struct twl6040 *twl6040);
|
||||
/* Get the combined status of the vibra control register */
|
||||
int twl6040_get_vibralr_status(struct twl6040 *twl6040);
|
||||
|
||||
static inline int twl6040_get_revid(struct twl6040 *twl6040)
|
||||
{
|
||||
return twl6040->rev;
|
||||
}
|
||||
|
||||
|
||||
#endif /* End of __TWL6040_CODEC_H__ */
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
enum wm8994_type {
|
||||
WM8994 = 0,
|
||||
WM8958 = 1,
|
||||
WM1811 = 2,
|
||||
};
|
||||
|
||||
struct regulator_dev;
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
#define WM8994_DC_SERVO_2 0x55
|
||||
#define WM8994_DC_SERVO_4 0x57
|
||||
#define WM8994_DC_SERVO_READBACK 0x58
|
||||
#define WM8994_DC_SERVO_4E 0x59
|
||||
#define WM8994_ANALOGUE_HP_1 0x60
|
||||
#define WM8958_MIC_DETECT_1 0xD0
|
||||
#define WM8958_MIC_DETECT_2 0xD1
|
||||
|
@ -133,6 +134,8 @@
|
|||
#define WM8994_AIF1_DAC1_FILTERS_2 0x421
|
||||
#define WM8994_AIF1_DAC2_FILTERS_1 0x422
|
||||
#define WM8994_AIF1_DAC2_FILTERS_2 0x423
|
||||
#define WM8958_AIF1_DAC1_NOISE_GATE 0x430
|
||||
#define WM8958_AIF1_DAC2_NOISE_GATE 0x431
|
||||
#define WM8994_AIF1_DRC1_1 0x440
|
||||
#define WM8994_AIF1_DRC1_2 0x441
|
||||
#define WM8994_AIF1_DRC1_3 0x442
|
||||
|
@ -190,6 +193,7 @@
|
|||
#define WM8994_AIF2_ADC_FILTERS 0x510
|
||||
#define WM8994_AIF2_DAC_FILTERS_1 0x520
|
||||
#define WM8994_AIF2_DAC_FILTERS_2 0x521
|
||||
#define WM8958_AIF2_DAC_NOISE_GATE 0x530
|
||||
#define WM8994_AIF2_DRC_1 0x540
|
||||
#define WM8994_AIF2_DRC_2 0x541
|
||||
#define WM8994_AIF2_DRC_3 0x542
|
||||
|
@ -1920,6 +1924,44 @@
|
|||
#define WM8994_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
|
||||
#define WM8994_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
|
||||
|
||||
/*
|
||||
* R61 (0x3D) - MICBIAS1
|
||||
*/
|
||||
#define WM8958_MICB1_RATE 0x0020 /* MICB1_RATE */
|
||||
#define WM8958_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */
|
||||
#define WM8958_MICB1_RATE_SHIFT 5 /* MICB1_RATE */
|
||||
#define WM8958_MICB1_RATE_WIDTH 1 /* MICB1_RATE */
|
||||
#define WM8958_MICB1_MODE 0x0010 /* MICB1_MODE */
|
||||
#define WM8958_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */
|
||||
#define WM8958_MICB1_MODE_SHIFT 4 /* MICB1_MODE */
|
||||
#define WM8958_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
|
||||
#define WM8958_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */
|
||||
#define WM8958_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */
|
||||
#define WM8958_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */
|
||||
#define WM8958_MICB1_DISCH 0x0001 /* MICB1_DISCH */
|
||||
#define WM8958_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
|
||||
#define WM8958_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
|
||||
#define WM8958_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
|
||||
|
||||
/*
|
||||
* R62 (0x3E) - MICBIAS2
|
||||
*/
|
||||
#define WM8958_MICB2_RATE 0x0020 /* MICB2_RATE */
|
||||
#define WM8958_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */
|
||||
#define WM8958_MICB2_RATE_SHIFT 5 /* MICB2_RATE */
|
||||
#define WM8958_MICB2_RATE_WIDTH 1 /* MICB2_RATE */
|
||||
#define WM8958_MICB2_MODE 0x0010 /* MICB2_MODE */
|
||||
#define WM8958_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */
|
||||
#define WM8958_MICB2_MODE_SHIFT 4 /* MICB2_MODE */
|
||||
#define WM8958_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
|
||||
#define WM8958_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */
|
||||
#define WM8958_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */
|
||||
#define WM8958_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */
|
||||
#define WM8958_MICB2_DISCH 0x0001 /* MICB2_DISCH */
|
||||
#define WM8958_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
|
||||
#define WM8958_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
|
||||
#define WM8958_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
|
||||
|
||||
/*
|
||||
* R76 (0x4C) - Charge Pump (1)
|
||||
*/
|
||||
|
@ -2027,6 +2069,10 @@
|
|||
/*
|
||||
* R96 (0x60) - Analogue HP (1)
|
||||
*/
|
||||
#define WM1811_HPOUT1_ATTN 0x0100 /* HPOUT1_ATTN */
|
||||
#define WM1811_HPOUT1_ATTN_MASK 0x0100 /* HPOUT1_ATTN */
|
||||
#define WM1811_HPOUT1_ATTN_SHIFT 8 /* HPOUT1_ATTN */
|
||||
#define WM1811_HPOUT1_ATTN_WIDTH 1 /* HPOUT1_ATTN */
|
||||
#define WM8994_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
|
||||
#define WM8994_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
|
||||
#define WM8994_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
|
||||
|
@ -2948,6 +2994,34 @@
|
|||
#define WM8994_AIF1DAC2_3D_ENA_SHIFT 8 /* AIF1DAC2_3D_ENA */
|
||||
#define WM8994_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */
|
||||
|
||||
/*
|
||||
* R1072 (0x430) - AIF1 DAC1 Noise Gate
|
||||
*/
|
||||
#define WM8958_AIF1DAC1_NG_HLD_MASK 0x0060 /* AIF1DAC1_NG_HLD - [6:5] */
|
||||
#define WM8958_AIF1DAC1_NG_HLD_SHIFT 5 /* AIF1DAC1_NG_HLD - [6:5] */
|
||||
#define WM8958_AIF1DAC1_NG_HLD_WIDTH 2 /* AIF1DAC1_NG_HLD - [6:5] */
|
||||
#define WM8958_AIF1DAC1_NG_THR_MASK 0x000E /* AIF1DAC1_NG_THR - [3:1] */
|
||||
#define WM8958_AIF1DAC1_NG_THR_SHIFT 1 /* AIF1DAC1_NG_THR - [3:1] */
|
||||
#define WM8958_AIF1DAC1_NG_THR_WIDTH 3 /* AIF1DAC1_NG_THR - [3:1] */
|
||||
#define WM8958_AIF1DAC1_NG_ENA 0x0001 /* AIF1DAC1_NG_ENA */
|
||||
#define WM8958_AIF1DAC1_NG_ENA_MASK 0x0001 /* AIF1DAC1_NG_ENA */
|
||||
#define WM8958_AIF1DAC1_NG_ENA_SHIFT 0 /* AIF1DAC1_NG_ENA */
|
||||
#define WM8958_AIF1DAC1_NG_ENA_WIDTH 1 /* AIF1DAC1_NG_ENA */
|
||||
|
||||
/*
|
||||
* R1073 (0x431) - AIF1 DAC2 Noise Gate
|
||||
*/
|
||||
#define WM8958_AIF1DAC2_NG_HLD_MASK 0x0060 /* AIF1DAC2_NG_HLD - [6:5] */
|
||||
#define WM8958_AIF1DAC2_NG_HLD_SHIFT 5 /* AIF1DAC2_NG_HLD - [6:5] */
|
||||
#define WM8958_AIF1DAC2_NG_HLD_WIDTH 2 /* AIF1DAC2_NG_HLD - [6:5] */
|
||||
#define WM8958_AIF1DAC2_NG_THR_MASK 0x000E /* AIF1DAC2_NG_THR - [3:1] */
|
||||
#define WM8958_AIF1DAC2_NG_THR_SHIFT 1 /* AIF1DAC2_NG_THR - [3:1] */
|
||||
#define WM8958_AIF1DAC2_NG_THR_WIDTH 3 /* AIF1DAC2_NG_THR - [3:1] */
|
||||
#define WM8958_AIF1DAC2_NG_ENA 0x0001 /* AIF1DAC2_NG_ENA */
|
||||
#define WM8958_AIF1DAC2_NG_ENA_MASK 0x0001 /* AIF1DAC2_NG_ENA */
|
||||
#define WM8958_AIF1DAC2_NG_ENA_SHIFT 0 /* AIF1DAC2_NG_ENA */
|
||||
#define WM8958_AIF1DAC2_NG_ENA_WIDTH 1 /* AIF1DAC2_NG_ENA */
|
||||
|
||||
/*
|
||||
* R1088 (0x440) - AIF1 DRC1 (1)
|
||||
*/
|
||||
|
@ -3559,6 +3633,20 @@
|
|||
#define WM8994_AIF2DAC_3D_ENA_SHIFT 8 /* AIF2DAC_3D_ENA */
|
||||
#define WM8994_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */
|
||||
|
||||
/*
|
||||
* R1328 (0x530) - AIF2 DAC Noise Gate
|
||||
*/
|
||||
#define WM8958_AIF2DAC_NG_HLD_MASK 0x0060 /* AIF2DAC_NG_HLD - [6:5] */
|
||||
#define WM8958_AIF2DAC_NG_HLD_SHIFT 5 /* AIF2DAC_NG_HLD - [6:5] */
|
||||
#define WM8958_AIF2DAC_NG_HLD_WIDTH 2 /* AIF2DAC_NG_HLD - [6:5] */
|
||||
#define WM8958_AIF2DAC_NG_THR_MASK 0x000E /* AIF2DAC_NG_THR - [3:1] */
|
||||
#define WM8958_AIF2DAC_NG_THR_SHIFT 1 /* AIF2DAC_NG_THR - [3:1] */
|
||||
#define WM8958_AIF2DAC_NG_THR_WIDTH 3 /* AIF2DAC_NG_THR - [3:1] */
|
||||
#define WM8958_AIF2DAC_NG_ENA 0x0001 /* AIF2DAC_NG_ENA */
|
||||
#define WM8958_AIF2DAC_NG_ENA_MASK 0x0001 /* AIF2DAC_NG_ENA */
|
||||
#define WM8958_AIF2DAC_NG_ENA_SHIFT 0 /* AIF2DAC_NG_ENA */
|
||||
#define WM8958_AIF2DAC_NG_ENA_WIDTH 1 /* AIF2DAC_NG_ENA */
|
||||
|
||||
/*
|
||||
* R1344 (0x540) - AIF2 DRC (1)
|
||||
*/
|
||||
|
|
|
@ -141,6 +141,7 @@ int regulator_enable(struct regulator *regulator);
|
|||
int regulator_disable(struct regulator *regulator);
|
||||
int regulator_force_disable(struct regulator *regulator);
|
||||
int regulator_is_enabled(struct regulator *regulator);
|
||||
int regulator_disable_deferred(struct regulator *regulator, int ms);
|
||||
|
||||
int regulator_bulk_get(struct device *dev, int num_consumers,
|
||||
struct regulator_bulk_data *consumers);
|
||||
|
@ -211,6 +212,12 @@ static inline int regulator_disable(struct regulator *regulator)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_disable_deferred(struct regulator *regulator,
|
||||
int ms)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_is_enabled(struct regulator *regulator)
|
||||
{
|
||||
return 1;
|
||||
|
|
|
@ -199,6 +199,9 @@ struct regulator_dev {
|
|||
struct regulation_constraints *constraints;
|
||||
struct regulator *supply; /* for tree */
|
||||
|
||||
struct delayed_work disable_work;
|
||||
int deferred_disables;
|
||||
|
||||
void *reg_data; /* regulator_dev data */
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
|
|
@ -383,12 +383,6 @@ struct usb_endpoint_descriptor {
|
|||
#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
|
||||
#define USB_ENDPOINT_DIR_MASK 0x80
|
||||
|
||||
#define USB_ENDPOINT_SYNCTYPE 0x0c
|
||||
#define USB_ENDPOINT_SYNC_NONE (0 << 2)
|
||||
#define USB_ENDPOINT_SYNC_ASYNC (1 << 2)
|
||||
#define USB_ENDPOINT_SYNC_ADAPTIVE (2 << 2)
|
||||
#define USB_ENDPOINT_SYNC_SYNC (3 << 2)
|
||||
|
||||
#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
|
||||
#define USB_ENDPOINT_XFER_CONTROL 0
|
||||
#define USB_ENDPOINT_XFER_ISOC 1
|
||||
|
@ -396,6 +390,17 @@ struct usb_endpoint_descriptor {
|
|||
#define USB_ENDPOINT_XFER_INT 3
|
||||
#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
|
||||
|
||||
#define USB_ENDPOINT_SYNCTYPE 0x0c
|
||||
#define USB_ENDPOINT_SYNC_NONE (0 << 2)
|
||||
#define USB_ENDPOINT_SYNC_ASYNC (1 << 2)
|
||||
#define USB_ENDPOINT_SYNC_ADAPTIVE (2 << 2)
|
||||
#define USB_ENDPOINT_SYNC_SYNC (3 << 2)
|
||||
|
||||
#define USB_ENDPOINT_USAGE_MASK 0x30
|
||||
#define USB_ENDPOINT_USAGE_DATA 0x00
|
||||
#define USB_ENDPOINT_USAGE_FEEDBACK 0x10
|
||||
#define USB_ENDPOINT_USAGE_IMPLICIT_FB 0x20 /* Implicit feedback Data endpoint */
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
|
|
34
include/sound/adau1373.h
Normal file
34
include/sound/adau1373.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Analog Devices ADAU1373 Audio Codec drive
|
||||
*
|
||||
* Copyright 2011 Analog Devices Inc.
|
||||
* Author: Lars-Peter Clausen <lars@metafoo.de>
|
||||
*
|
||||
* Licensed under the GPL-2 or later.
|
||||
*/
|
||||
|
||||
#ifndef __SOUND_ADAU1373_H__
|
||||
#define __SOUND_ADAU1373_H__
|
||||
|
||||
enum adau1373_micbias_voltage {
|
||||
ADAU1373_MICBIAS_2_9V = 0,
|
||||
ADAU1373_MICBIAS_2_2V = 1,
|
||||
ADAU1373_MICBIAS_2_6V = 2,
|
||||
ADAU1373_MICBIAS_1_8V = 3,
|
||||
};
|
||||
|
||||
#define ADAU1373_DRC_SIZE 13
|
||||
|
||||
struct adau1373_platform_data {
|
||||
bool input_differential[4];
|
||||
bool lineout_differential;
|
||||
bool lineout_ground_sense;
|
||||
|
||||
unsigned int num_drc;
|
||||
uint8_t drc_setting[3][ADAU1373_DRC_SIZE];
|
||||
|
||||
enum adau1373_micbias_voltage micbias1;
|
||||
enum adau1373_micbias_voltage micbias2;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -706,7 +706,7 @@ struct snd_timer_tread {
|
|||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6)
|
||||
#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7)
|
||||
|
||||
struct snd_ctl_card_info {
|
||||
int card; /* card number */
|
||||
|
@ -803,6 +803,8 @@ struct snd_ctl_elem_info {
|
|||
unsigned int items; /* R: number of items */
|
||||
unsigned int item; /* W: item number */
|
||||
char name[64]; /* R: value name */
|
||||
__u64 names_ptr; /* W: names list (ELEM_ADD only) */
|
||||
unsigned int names_length;
|
||||
} enumerated;
|
||||
unsigned char reserved[128];
|
||||
} value;
|
||||
|
|
|
@ -62,7 +62,7 @@ static int snd_legacy_find_free_irq(int *irq_table)
|
|||
{
|
||||
while (*irq_table != -1) {
|
||||
if (!request_irq(*irq_table, snd_legacy_empty_irq_handler,
|
||||
IRQF_DISABLED | IRQF_PROBE_SHARED, "ALSA Test IRQ",
|
||||
IRQF_PROBE_SHARED, "ALSA Test IRQ",
|
||||
(void *) irq_table)) {
|
||||
free_irq(*irq_table, (void *) irq_table);
|
||||
return *irq_table;
|
||||
|
|
|
@ -42,6 +42,7 @@ enum snd_jack_types {
|
|||
SND_JACK_MECHANICAL = 0x0008, /* If detected separately */
|
||||
SND_JACK_VIDEOOUT = 0x0010,
|
||||
SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT,
|
||||
SND_JACK_LINEIN = 0x0020,
|
||||
|
||||
/* Kept separate from switches to facilitate implementation */
|
||||
SND_JACK_BTN_0 = 0x4000,
|
||||
|
|
|
@ -50,7 +50,10 @@
|
|||
#define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */
|
||||
#define MPU401_INFO_MMIO (1 << 3) /* MMIO access */
|
||||
#define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */
|
||||
#define MPU401_INFO_IRQ_HOOK (1 << 5) /* mpu401 irq handler is called
|
||||
from driver irq handler */
|
||||
#define MPU401_INFO_NO_ACK (1 << 6) /* No ACK cmd needed */
|
||||
#define MPU401_INFO_USE_TIMER (1 << 15) /* internal */
|
||||
|
||||
#define MPU401_MODE_BIT_INPUT 0
|
||||
#define MPU401_MODE_BIT_OUTPUT 1
|
||||
|
@ -73,8 +76,7 @@ struct snd_mpu401 {
|
|||
unsigned long port; /* base port of MPU-401 chip */
|
||||
unsigned long cport; /* port + 1 (usually) */
|
||||
struct resource *res; /* port resource */
|
||||
int irq; /* IRQ number of MPU-401 chip (-1 = poll) */
|
||||
int irq_flags;
|
||||
int irq; /* IRQ number of MPU-401 chip */
|
||||
|
||||
unsigned long mode; /* MPU401_MODE_XXXX */
|
||||
int timer_invoked;
|
||||
|
@ -131,7 +133,6 @@ int snd_mpu401_uart_new(struct snd_card *card,
|
|||
unsigned long port,
|
||||
unsigned int info_flags,
|
||||
int irq,
|
||||
int irq_flags,
|
||||
struct snd_rawmidi ** rrawmidi);
|
||||
|
||||
#endif /* __SOUND_MPU401_H */
|
||||
|
|
|
@ -825,6 +825,8 @@ int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime,
|
|||
int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
|
||||
unsigned int cond,
|
||||
snd_pcm_hw_param_t var);
|
||||
int snd_pcm_hw_rule_noresample(struct snd_pcm_runtime *runtime,
|
||||
unsigned int base_rate);
|
||||
int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime,
|
||||
unsigned int cond,
|
||||
int var,
|
||||
|
@ -1035,6 +1037,8 @@ static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area)
|
|||
atomic_dec(&substream->mmap_count);
|
||||
}
|
||||
|
||||
int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
|
||||
struct vm_area_struct *area);
|
||||
/* mmap for io-memory area */
|
||||
#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_ALPHA)
|
||||
#define SNDRV_PCM_INFO_MMAP_IOMEM SNDRV_PCM_INFO_MMAP
|
||||
|
|
16
include/sound/saif.h
Normal file
16
include/sound/saif.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SOUND_SAIF_H__
|
||||
#define __SOUND_SAIF_H__
|
||||
|
||||
struct mxs_saif_platform_data {
|
||||
int (*init) (void);
|
||||
int (*get_master_id) (unsigned int saif_id);
|
||||
};
|
||||
#endif
|
|
@ -24,13 +24,13 @@ struct snd_pcm_substream;
|
|||
* Describes the physical PCM data formating and clocking. Add new formats
|
||||
* to the end.
|
||||
*/
|
||||
#define SND_SOC_DAIFMT_I2S 0 /* I2S mode */
|
||||
#define SND_SOC_DAIFMT_RIGHT_J 1 /* Right Justified mode */
|
||||
#define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */
|
||||
#define SND_SOC_DAIFMT_DSP_A 3 /* L data MSB after FRM LRC */
|
||||
#define SND_SOC_DAIFMT_DSP_B 4 /* L data MSB during FRM LRC */
|
||||
#define SND_SOC_DAIFMT_AC97 5 /* AC97 */
|
||||
#define SND_SOC_DAIFMT_PDM 6 /* Pulse density modulation */
|
||||
#define SND_SOC_DAIFMT_I2S 1 /* I2S mode */
|
||||
#define SND_SOC_DAIFMT_RIGHT_J 2 /* Right Justified mode */
|
||||
#define SND_SOC_DAIFMT_LEFT_J 3 /* Left Justified mode */
|
||||
#define SND_SOC_DAIFMT_DSP_A 4 /* L data MSB after FRM LRC */
|
||||
#define SND_SOC_DAIFMT_DSP_B 5 /* L data MSB during FRM LRC */
|
||||
#define SND_SOC_DAIFMT_AC97 6 /* AC97 */
|
||||
#define SND_SOC_DAIFMT_PDM 7 /* Pulse density modulation */
|
||||
|
||||
/* left and right justified also known as MSB and LSB respectively */
|
||||
#define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J
|
||||
|
@ -42,8 +42,8 @@ struct snd_pcm_substream;
|
|||
* DAI bit clocks can be be gated (disabled) when the DAI is not
|
||||
* sending or receiving PCM data in a frame. This can be used to save power.
|
||||
*/
|
||||
#define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */
|
||||
#define SND_SOC_DAIFMT_GATED (1 << 4) /* clock is gated */
|
||||
#define SND_SOC_DAIFMT_CONT (1 << 4) /* continuous clock */
|
||||
#define SND_SOC_DAIFMT_GATED (2 << 4) /* clock is gated */
|
||||
|
||||
/*
|
||||
* DAI hardware signal inversions.
|
||||
|
@ -51,10 +51,10 @@ struct snd_pcm_substream;
|
|||
* Specifies whether the DAI can also support inverted clocks for the specified
|
||||
* format.
|
||||
*/
|
||||
#define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */
|
||||
#define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal BCLK + inv FRM */
|
||||
#define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert BCLK + nor FRM */
|
||||
#define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert BCLK + FRM */
|
||||
#define SND_SOC_DAIFMT_NB_NF (1 << 8) /* normal bit clock + frame */
|
||||
#define SND_SOC_DAIFMT_NB_IF (2 << 8) /* normal BCLK + inv FRM */
|
||||
#define SND_SOC_DAIFMT_IB_NF (3 << 8) /* invert BCLK + nor FRM */
|
||||
#define SND_SOC_DAIFMT_IB_IF (4 << 8) /* invert BCLK + FRM */
|
||||
|
||||
/*
|
||||
* DAI hardware clock masters.
|
||||
|
@ -63,10 +63,10 @@ struct snd_pcm_substream;
|
|||
* i.e. if the codec is clk and FRM master then the interface is
|
||||
* clk and frame slave.
|
||||
*/
|
||||
#define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & FRM master */
|
||||
#define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & FRM master */
|
||||
#define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */
|
||||
#define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & FRM slave */
|
||||
#define SND_SOC_DAIFMT_CBM_CFM (1 << 12) /* codec clk & FRM master */
|
||||
#define SND_SOC_DAIFMT_CBS_CFM (2 << 12) /* codec clk slave & FRM master */
|
||||
#define SND_SOC_DAIFMT_CBM_CFS (3 << 12) /* codec clk master & frame slave */
|
||||
#define SND_SOC_DAIFMT_CBS_CFS (4 << 12) /* codec clk & FRM slave */
|
||||
|
||||
#define SND_SOC_DAIFMT_FORMAT_MASK 0x000f
|
||||
#define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0
|
||||
|
@ -242,6 +242,9 @@ struct snd_soc_dai {
|
|||
void *playback_dma_data;
|
||||
void *capture_dma_data;
|
||||
|
||||
/* Symmetry data - only valid if symmetry is being enforced */
|
||||
unsigned int rate;
|
||||
|
||||
/* parent platform/codec */
|
||||
union {
|
||||
struct snd_soc_platform *platform;
|
||||
|
|
|
@ -381,6 +381,9 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
|
|||
int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
|
||||
const char *pin);
|
||||
|
||||
/* Mostly internal - should not normally be used */
|
||||
void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason);
|
||||
|
||||
/* dapm widget types */
|
||||
enum snd_soc_dapm_type {
|
||||
snd_soc_dapm_input = 0, /* input pin */
|
||||
|
@ -473,6 +476,8 @@ struct snd_soc_dapm_widget {
|
|||
unsigned char ext:1; /* has external widgets */
|
||||
unsigned char force:1; /* force state */
|
||||
unsigned char ignore_suspend:1; /* kept enabled over suspend */
|
||||
unsigned char new_power:1; /* power from this run */
|
||||
unsigned char power_checked:1; /* power checked this run */
|
||||
int subseq; /* sort within widget type */
|
||||
|
||||
int (*power_check)(struct snd_soc_dapm_widget *w);
|
||||
|
@ -492,6 +497,9 @@ struct snd_soc_dapm_widget {
|
|||
|
||||
/* used during DAPM updates */
|
||||
struct list_head power_list;
|
||||
struct list_head dirty;
|
||||
int inputs;
|
||||
int outputs;
|
||||
};
|
||||
|
||||
struct snd_soc_dapm_update {
|
||||
|
@ -524,6 +532,8 @@ struct snd_soc_dapm_context {
|
|||
enum snd_soc_bias_level target_bias_level;
|
||||
struct list_head list;
|
||||
|
||||
int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs_dapm;
|
||||
#endif
|
||||
|
@ -535,4 +545,10 @@ struct snd_soc_dapm_widget_list {
|
|||
struct snd_soc_dapm_widget *widgets[0];
|
||||
};
|
||||
|
||||
struct snd_soc_dapm_stats {
|
||||
int power_checks;
|
||||
int path_checks;
|
||||
int neighbour_checks;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/workqueue.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/control.h>
|
||||
|
@ -27,13 +28,20 @@
|
|||
/*
|
||||
* Convenience kcontrol builders
|
||||
*/
|
||||
#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \
|
||||
#define SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, xmax, xinvert) \
|
||||
((unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \
|
||||
.platform_max = xmax, .invert = xinvert})
|
||||
{.reg = xreg, .rreg = xreg, .shift = shift_left, \
|
||||
.rshift = shift_right, .max = xmax, .platform_max = xmax, \
|
||||
.invert = xinvert})
|
||||
#define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \
|
||||
SOC_DOUBLE_VALUE(xreg, xshift, xshift, xmax, xinvert)
|
||||
#define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \
|
||||
((unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .max = xmax, .platform_max = xmax, .invert = xinvert})
|
||||
#define SOC_DOUBLE_R_VALUE(xlreg, xrreg, xshift, xmax, xinvert) \
|
||||
((unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \
|
||||
.max = xmax, .platform_max = xmax, .invert = xinvert})
|
||||
#define SOC_SINGLE(xname, reg, shift, max, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
|
||||
|
@ -47,40 +55,36 @@
|
|||
.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
|
||||
.put = snd_soc_put_volsw, \
|
||||
.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
|
||||
#define SOC_DOUBLE(xname, xreg, shift_left, shift_right, xmax, xinvert) \
|
||||
#define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
|
||||
.put = snd_soc_put_volsw, \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .shift = shift_left, .rshift = shift_right, \
|
||||
.max = xmax, .platform_max = xmax, .invert = xinvert} }
|
||||
.private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
|
||||
max, invert) }
|
||||
#define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
|
||||
.info = snd_soc_info_volsw_2r, \
|
||||
.get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = reg_left, .rreg = reg_right, .shift = xshift, \
|
||||
.max = xmax, .platform_max = xmax, .invert = xinvert} }
|
||||
#define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \
|
||||
.info = snd_soc_info_volsw, \
|
||||
.get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
|
||||
.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
|
||||
xmax, xinvert) }
|
||||
#define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
|
||||
SNDRV_CTL_ELEM_ACCESS_READWRITE,\
|
||||
.tlv.p = (tlv_array), \
|
||||
.info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
|
||||
.put = snd_soc_put_volsw, \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .shift = shift_left, .rshift = shift_right,\
|
||||
.max = xmax, .platform_max = xmax, .invert = xinvert} }
|
||||
.private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \
|
||||
max, invert) }
|
||||
#define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
|
||||
SNDRV_CTL_ELEM_ACCESS_READWRITE,\
|
||||
.tlv.p = (tlv_array), \
|
||||
.info = snd_soc_info_volsw_2r, \
|
||||
.get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = reg_left, .rreg = reg_right, .shift = xshift, \
|
||||
.max = xmax, .platform_max = xmax, .invert = xinvert} }
|
||||
.info = snd_soc_info_volsw, \
|
||||
.get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
|
||||
.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
|
||||
xmax, xinvert) }
|
||||
#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
|
||||
|
@ -120,14 +124,13 @@
|
|||
.info = snd_soc_info_volsw, \
|
||||
.get = xhandler_get, .put = xhandler_put, \
|
||||
.private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
|
||||
#define SOC_DOUBLE_EXT(xname, xreg, shift_left, shift_right, xmax, xinvert,\
|
||||
#define SOC_DOUBLE_EXT(xname, reg, shift_left, shift_right, max, invert,\
|
||||
xhandler_get, xhandler_put) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
|
||||
.info = snd_soc_info_volsw, \
|
||||
.get = xhandler_get, .put = xhandler_put, \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .shift = shift_left, .rshift = shift_right, \
|
||||
.max = xmax, .platform_max = xmax, .invert = xinvert} }
|
||||
.private_value = \
|
||||
SOC_DOUBLE_VALUE(reg, shift_left, shift_right, max, invert) }
|
||||
#define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\
|
||||
xhandler_get, xhandler_put, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
|
@ -145,20 +148,18 @@
|
|||
.tlv.p = (tlv_array), \
|
||||
.info = snd_soc_info_volsw, \
|
||||
.get = xhandler_get, .put = xhandler_put, \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = xreg, .shift = shift_left, .rshift = shift_right, \
|
||||
.max = xmax, .platform_max = xmax, .invert = xinvert} }
|
||||
.private_value = SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, \
|
||||
xmax, xinvert) }
|
||||
#define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\
|
||||
xhandler_get, xhandler_put, tlv_array) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
|
||||
SNDRV_CTL_ELEM_ACCESS_READWRITE, \
|
||||
.tlv.p = (tlv_array), \
|
||||
.info = snd_soc_info_volsw_2r, \
|
||||
.info = snd_soc_info_volsw, \
|
||||
.get = xhandler_get, .put = xhandler_put, \
|
||||
.private_value = (unsigned long)&(struct soc_mixer_control) \
|
||||
{.reg = reg_left, .rreg = reg_right, .shift = xshift, \
|
||||
.max = xmax, .platform_max = xmax, .invert = xinvert} }
|
||||
.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
|
||||
xmax, xinvert) }
|
||||
#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
||||
.info = snd_soc_info_bool_ext, \
|
||||
|
@ -260,6 +261,7 @@ extern struct snd_ac97_bus_ops soc_ac97_ops;
|
|||
enum snd_soc_control_type {
|
||||
SND_SOC_I2C = 1,
|
||||
SND_SOC_SPI,
|
||||
SND_SOC_REGMAP,
|
||||
};
|
||||
|
||||
enum snd_soc_compress_type {
|
||||
|
@ -274,7 +276,7 @@ enum snd_soc_pcm_subclass {
|
|||
};
|
||||
|
||||
int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
|
||||
unsigned int freq, int dir);
|
||||
int source, unsigned int freq, int dir);
|
||||
int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
|
||||
unsigned int freq_in, unsigned int freq_out);
|
||||
|
||||
|
@ -391,12 +393,8 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
|
|||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
#define snd_soc_get_volsw_2r snd_soc_get_volsw
|
||||
#define snd_soc_put_volsw_2r snd_soc_put_volsw
|
||||
int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo);
|
||||
int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol,
|
||||
|
@ -576,9 +574,11 @@ struct snd_soc_codec {
|
|||
const void *reg_def_copy;
|
||||
const struct snd_soc_cache_ops *cache_ops;
|
||||
struct mutex cache_rw_mutex;
|
||||
int val_bytes;
|
||||
|
||||
/* dapm */
|
||||
struct snd_soc_dapm_context dapm;
|
||||
unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs_codec_root;
|
||||
|
@ -607,7 +607,7 @@ struct snd_soc_codec_driver {
|
|||
|
||||
/* codec wide operations */
|
||||
int (*set_sysclk)(struct snd_soc_codec *codec,
|
||||
int clk_id, unsigned int freq, int dir);
|
||||
int clk_id, int source, unsigned int freq, int dir);
|
||||
int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,
|
||||
unsigned int freq_in, unsigned int freq_out);
|
||||
|
||||
|
@ -619,7 +619,7 @@ struct snd_soc_codec_driver {
|
|||
int (*volatile_register)(struct snd_soc_codec *, unsigned int);
|
||||
int (*readable_register)(struct snd_soc_codec *, unsigned int);
|
||||
int (*writable_register)(struct snd_soc_codec *, unsigned int);
|
||||
short reg_cache_size;
|
||||
unsigned int reg_cache_size;
|
||||
short reg_cache_step;
|
||||
short reg_word_size;
|
||||
const void *reg_cache_default;
|
||||
|
@ -630,10 +630,14 @@ struct snd_soc_codec_driver {
|
|||
/* codec bias level */
|
||||
int (*set_bias_level)(struct snd_soc_codec *,
|
||||
enum snd_soc_bias_level level);
|
||||
bool idle_bias_off;
|
||||
|
||||
void (*seq_notifier)(struct snd_soc_dapm_context *,
|
||||
enum snd_soc_dapm_type, int);
|
||||
|
||||
/* codec stream completion event */
|
||||
int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
|
||||
|
||||
/* probe ordering - for components with runtime dependencies */
|
||||
int probe_order;
|
||||
int remove_order;
|
||||
|
@ -669,6 +673,9 @@ struct snd_soc_platform_driver {
|
|||
/* platform stream ops */
|
||||
struct snd_pcm_ops *ops;
|
||||
|
||||
/* platform stream completion event */
|
||||
int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
|
||||
|
||||
/* probe ordering - for components with runtime dependencies */
|
||||
int probe_order;
|
||||
int remove_order;
|
||||
|
@ -703,6 +710,8 @@ struct snd_soc_dai_link {
|
|||
const char *cpu_dai_name;
|
||||
const char *codec_dai_name;
|
||||
|
||||
unsigned int dai_fmt; /* format to set on init */
|
||||
|
||||
/* Keep DAI active over suspend */
|
||||
unsigned int ignore_suspend:1;
|
||||
|
||||
|
@ -815,9 +824,11 @@ struct snd_soc_card {
|
|||
struct list_head widgets;
|
||||
struct list_head paths;
|
||||
struct list_head dapm_list;
|
||||
struct list_head dapm_dirty;
|
||||
|
||||
/* Generic DAPM context for the card */
|
||||
struct snd_soc_dapm_context dapm;
|
||||
struct snd_soc_dapm_stats dapm_stats;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *debugfs_card_root;
|
||||
|
@ -840,8 +851,6 @@ struct snd_soc_pcm_runtime {
|
|||
unsigned int complete:1;
|
||||
unsigned int dev_registered:1;
|
||||
|
||||
/* Symmetry data - only valid if symmetry is being enforced */
|
||||
unsigned int rate;
|
||||
long pmdown_time;
|
||||
|
||||
/* runtime devices */
|
||||
|
@ -936,6 +945,18 @@ static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
|
|||
INIT_LIST_HEAD(&card->dapm_list);
|
||||
}
|
||||
|
||||
static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc)
|
||||
{
|
||||
if (mc->reg == mc->rreg && mc->shift == mc->rshift)
|
||||
return 0;
|
||||
/*
|
||||
* mc->reg == mc->rreg && mc->shift != mc->rshift, or
|
||||
* mc->reg != mc->rreg means that the control is
|
||||
* stereo (bits in one register or in two registers)
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
int snd_soc_util_init(void);
|
||||
void snd_soc_util_exit(void);
|
||||
|
||||
|
|
|
@ -23,13 +23,7 @@
|
|||
#ifndef TPA6130A2_PLAT_H
|
||||
#define TPA6130A2_PLAT_H
|
||||
|
||||
enum tpa_model {
|
||||
TPA6130A2,
|
||||
TPA6140A2,
|
||||
};
|
||||
|
||||
struct tpa6130a2_platform_data {
|
||||
enum tpa_model id;
|
||||
int power_gpio;
|
||||
};
|
||||
|
||||
|
|
27
include/sound/wm1250-ev1.h
Normal file
27
include/sound/wm1250-ev1.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* linux/sound/wm1250-ev1.h - Platform data for WM1250-EV1
|
||||
*
|
||||
* Copyright 2011 Wolfson Microelectronics. PLC.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_SND_WM1250_EV1_H
|
||||
#define __LINUX_SND_WM1250_EV1_H
|
||||
|
||||
#define WM1250_EV1_NUM_GPIOS 5
|
||||
|
||||
#define WM1250_EV1_GPIO_CLK_ENA 0
|
||||
#define WM1250_EV1_GPIO_CLK_SEL0 1
|
||||
#define WM1250_EV1_GPIO_CLK_SEL1 2
|
||||
#define WM1250_EV1_GPIO_OSR 3
|
||||
#define WM1250_EV1_GPIO_MASTER 4
|
||||
|
||||
|
||||
struct wm1250_ev1_pdata {
|
||||
int gpios[WM1250_EV1_NUM_GPIOS];
|
||||
};
|
||||
|
||||
#endif
|
59
include/sound/wm5100.h
Normal file
59
include/sound/wm5100.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* linux/sound/wm5100.h -- Platform data for WM5100
|
||||
*
|
||||
* Copyright 2011 Wolfson Microelectronics. PLC.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_SND_WM5100_H
|
||||
#define __LINUX_SND_WM5100_H
|
||||
|
||||
enum wm5100_in_mode {
|
||||
WM5100_IN_SE = 0,
|
||||
WM5100_IN_DIFF = 1,
|
||||
WM5100_IN_DMIC = 2,
|
||||
};
|
||||
|
||||
enum wm5100_dmic_sup {
|
||||
WM5100_DMIC_SUP_MICVDD = 0,
|
||||
WM5100_DMIC_SUP_MICBIAS1 = 1,
|
||||
WM5100_DMIC_SUP_MICBIAS2 = 2,
|
||||
WM5100_DMIC_SUP_MICBIAS3 = 3,
|
||||
};
|
||||
|
||||
enum wm5100_micdet_bias {
|
||||
WM5100_MICDET_MICBIAS1 = 0,
|
||||
WM5100_MICDET_MICBIAS2 = 1,
|
||||
WM5100_MICDET_MICBIAS3 = 2,
|
||||
};
|
||||
|
||||
struct wm5100_jack_mode {
|
||||
enum wm5100_micdet_bias bias;
|
||||
int hp_pol;
|
||||
int micd_src;
|
||||
};
|
||||
|
||||
#define WM5100_GPIO_SET 0x10000
|
||||
|
||||
struct wm5100_pdata {
|
||||
int reset; /** GPIO controlling /RESET, if any */
|
||||
int ldo_ena; /** GPIO controlling LODENA, if any */
|
||||
int hp_pol; /** GPIO controlling headset polarity, if any */
|
||||
int irq_flags;
|
||||
int gpio_base;
|
||||
|
||||
struct wm5100_jack_mode jack_modes[2];
|
||||
|
||||
/* Input pin mode selection */
|
||||
enum wm5100_in_mode in_mode[4];
|
||||
|
||||
/* DMIC supply selection */
|
||||
enum wm5100_dmic_sup dmic_sup[4];
|
||||
|
||||
int gpio_defaults[6];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -216,6 +216,31 @@ DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done,
|
|||
|
||||
);
|
||||
|
||||
TRACE_EVENT(snd_soc_dapm_walk_done,
|
||||
|
||||
TP_PROTO(struct snd_soc_card *card),
|
||||
|
||||
TP_ARGS(card),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string( name, card->name )
|
||||
__field( int, power_checks )
|
||||
__field( int, path_checks )
|
||||
__field( int, neighbour_checks )
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(name, card->name);
|
||||
__entry->power_checks = card->dapm_stats.power_checks;
|
||||
__entry->path_checks = card->dapm_stats.path_checks;
|
||||
__entry->neighbour_checks = card->dapm_stats.neighbour_checks;
|
||||
),
|
||||
|
||||
TP_printk("%s: checks %d power, %d path, %d neighbour",
|
||||
__get_str(name), (int)__entry->power_checks,
|
||||
(int)__entry->path_checks, (int)__entry->neighbour_checks)
|
||||
);
|
||||
|
||||
TRACE_EVENT(snd_soc_jack_irq,
|
||||
|
||||
TP_PROTO(const char *name),
|
||||
|
|
|
@ -1067,7 +1067,6 @@ static int onyx_i2c_probe(struct i2c_client *client,
|
|||
printk(KERN_DEBUG PFX "created and attached onyx instance\n");
|
||||
return 0;
|
||||
fail:
|
||||
i2c_set_clientdata(client, NULL);
|
||||
kfree(onyx);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -1112,8 +1111,7 @@ static int onyx_i2c_remove(struct i2c_client *client)
|
|||
|
||||
aoa_codec_unregister(&onyx->codec);
|
||||
of_node_put(onyx->codec.node);
|
||||
if (onyx->codec_info)
|
||||
kfree(onyx->codec_info);
|
||||
kfree(onyx->codec_info);
|
||||
kfree(onyx);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -443,7 +443,7 @@ static int aaci_pcm_open(struct snd_pcm_substream *substream)
|
|||
mutex_lock(&aaci->irq_lock);
|
||||
if (!aaci->users++) {
|
||||
ret = request_irq(aaci->dev->irq[0], aaci_irq,
|
||||
IRQF_SHARED | IRQF_DISABLED, DRIVER_NAME, aaci);
|
||||
IRQF_SHARED, DRIVER_NAME, aaci);
|
||||
if (ret != 0)
|
||||
aaci->users--;
|
||||
}
|
||||
|
|
|
@ -359,7 +359,7 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
|
|||
if (ret)
|
||||
goto err_clk2;
|
||||
|
||||
ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL);
|
||||
ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL);
|
||||
if (ret < 0)
|
||||
goto err_irq;
|
||||
|
||||
|
|
|
@ -989,7 +989,6 @@ struct user_element {
|
|||
void *tlv_data; /* TLV data */
|
||||
unsigned long tlv_data_size; /* TLV data size */
|
||||
void *priv_data; /* private data (like strings for enumerated type) */
|
||||
unsigned long priv_data_size; /* size of private data in bytes */
|
||||
};
|
||||
|
||||
static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol,
|
||||
|
@ -1001,6 +1000,28 @@ static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int snd_ctl_elem_user_enum_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
struct user_element *ue = kcontrol->private_data;
|
||||
const char *names;
|
||||
unsigned int item;
|
||||
|
||||
item = uinfo->value.enumerated.item;
|
||||
|
||||
*uinfo = ue->info;
|
||||
|
||||
item = min(item, uinfo->value.enumerated.items - 1);
|
||||
uinfo->value.enumerated.item = item;
|
||||
|
||||
names = ue->priv_data;
|
||||
for (; item > 0; --item)
|
||||
names += strlen(names) + 1;
|
||||
strcpy(uinfo->value.enumerated.name, names);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
@ -1055,11 +1076,46 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
|
|||
return change;
|
||||
}
|
||||
|
||||
static int snd_ctl_elem_init_enum_names(struct user_element *ue)
|
||||
{
|
||||
char *names, *p;
|
||||
size_t buf_len, name_len;
|
||||
unsigned int i;
|
||||
|
||||
if (ue->info.value.enumerated.names_length > 64 * 1024)
|
||||
return -EINVAL;
|
||||
|
||||
names = memdup_user(
|
||||
(const void __user *)ue->info.value.enumerated.names_ptr,
|
||||
ue->info.value.enumerated.names_length);
|
||||
if (IS_ERR(names))
|
||||
return PTR_ERR(names);
|
||||
|
||||
/* check that there are enough valid names */
|
||||
buf_len = ue->info.value.enumerated.names_length;
|
||||
p = names;
|
||||
for (i = 0; i < ue->info.value.enumerated.items; ++i) {
|
||||
name_len = strnlen(p, buf_len);
|
||||
if (name_len == 0 || name_len >= 64 || name_len == buf_len) {
|
||||
kfree(names);
|
||||
return -EINVAL;
|
||||
}
|
||||
p += name_len + 1;
|
||||
buf_len -= name_len + 1;
|
||||
}
|
||||
|
||||
ue->priv_data = names;
|
||||
ue->info.value.enumerated.names_ptr = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol)
|
||||
{
|
||||
struct user_element *ue = kcontrol->private_data;
|
||||
if (ue->tlv_data)
|
||||
kfree(ue->tlv_data);
|
||||
|
||||
kfree(ue->tlv_data);
|
||||
kfree(ue->priv_data);
|
||||
kfree(ue);
|
||||
}
|
||||
|
||||
|
@ -1072,8 +1128,8 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
|||
long private_size;
|
||||
struct user_element *ue;
|
||||
int idx, err;
|
||||
|
||||
if (card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
|
||||
if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
return -ENOMEM;
|
||||
if (info->count < 1)
|
||||
return -EINVAL;
|
||||
|
@ -1101,7 +1157,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
|||
memcpy(&kctl.id, &info->id, sizeof(info->id));
|
||||
kctl.count = info->owner ? info->owner : 1;
|
||||
access |= SNDRV_CTL_ELEM_ACCESS_USER;
|
||||
kctl.info = snd_ctl_elem_user_info;
|
||||
if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED)
|
||||
kctl.info = snd_ctl_elem_user_enum_info;
|
||||
else
|
||||
kctl.info = snd_ctl_elem_user_info;
|
||||
if (access & SNDRV_CTL_ELEM_ACCESS_READ)
|
||||
kctl.get = snd_ctl_elem_user_get;
|
||||
if (access & SNDRV_CTL_ELEM_ACCESS_WRITE)
|
||||
|
@ -1122,6 +1181,11 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
|||
if (info->count > 64)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
|
||||
private_size = sizeof(unsigned int);
|
||||
if (info->count > 128 || info->value.enumerated.items == 0)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case SNDRV_CTL_ELEM_TYPE_BYTES:
|
||||
private_size = sizeof(unsigned char);
|
||||
if (info->count > 512)
|
||||
|
@ -1143,9 +1207,17 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
|||
ue->info.access = 0;
|
||||
ue->elem_data = (char *)ue + sizeof(*ue);
|
||||
ue->elem_data_size = private_size;
|
||||
if (ue->info.type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) {
|
||||
err = snd_ctl_elem_init_enum_names(ue);
|
||||
if (err < 0) {
|
||||
kfree(ue);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
kctl.private_free = snd_ctl_elem_user_free;
|
||||
_kctl = snd_ctl_new(&kctl, access);
|
||||
if (_kctl == NULL) {
|
||||
kfree(ue->priv_data);
|
||||
kfree(ue);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
|
@ -83,6 +83,8 @@ struct snd_ctl_elem_info32 {
|
|||
u32 items;
|
||||
u32 item;
|
||||
char name[64];
|
||||
u64 names_ptr;
|
||||
u32 names_length;
|
||||
} enumerated;
|
||||
unsigned char reserved[128];
|
||||
} value;
|
||||
|
@ -372,6 +374,8 @@ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
|
|||
&data32->value.enumerated,
|
||||
sizeof(data->value.enumerated)))
|
||||
goto error;
|
||||
data->value.enumerated.names_ptr =
|
||||
(uintptr_t)compat_ptr(data->value.enumerated.names_ptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -30,6 +30,7 @@ static int jack_switch_types[] = {
|
|||
SW_LINEOUT_INSERT,
|
||||
SW_JACK_PHYSICAL_INSERT,
|
||||
SW_VIDEOOUT_INSERT,
|
||||
SW_LINEIN_INSERT,
|
||||
};
|
||||
|
||||
static int snd_jack_dev_free(struct snd_device *device)
|
||||
|
|
|
@ -499,7 +499,7 @@ static struct snd_kcontrol *snd_mixer_oss_test_id(struct snd_mixer_oss *mixer, c
|
|||
|
||||
memset(&id, 0, sizeof(id));
|
||||
id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
|
||||
strcpy(id.name, name);
|
||||
strlcpy(id.name, name, sizeof(id.name));
|
||||
id.index = index;
|
||||
return snd_ctl_find_id(card, &id);
|
||||
}
|
||||
|
|
|
@ -1399,6 +1399,32 @@ int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
|
|||
|
||||
EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
|
||||
|
||||
static int snd_pcm_hw_rule_noresample_func(struct snd_pcm_hw_params *params,
|
||||
struct snd_pcm_hw_rule *rule)
|
||||
{
|
||||
unsigned int base_rate = (unsigned int)(uintptr_t)rule->private;
|
||||
struct snd_interval *rate;
|
||||
|
||||
rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
|
||||
return snd_interval_list(rate, 1, &base_rate, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_pcm_hw_rule_noresample - add a rule to allow disabling hw resampling
|
||||
* @runtime: PCM runtime instance
|
||||
* @base_rate: the rate at which the hardware does not resample
|
||||
*/
|
||||
int snd_pcm_hw_rule_noresample(struct snd_pcm_runtime *runtime,
|
||||
unsigned int base_rate)
|
||||
{
|
||||
return snd_pcm_hw_rule_add(runtime, SNDRV_PCM_HW_PARAMS_NORESAMPLE,
|
||||
SNDRV_PCM_HW_PARAM_RATE,
|
||||
snd_pcm_hw_rule_noresample_func,
|
||||
(void *)(uintptr_t)base_rate,
|
||||
SNDRV_PCM_HW_PARAM_RATE, -1);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_hw_rule_noresample);
|
||||
|
||||
static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
|
||||
snd_pcm_hw_param_t var)
|
||||
{
|
||||
|
|
|
@ -2058,16 +2058,12 @@ EXPORT_SYMBOL(snd_pcm_open_substream);
|
|||
|
||||
static int snd_pcm_open_file(struct file *file,
|
||||
struct snd_pcm *pcm,
|
||||
int stream,
|
||||
struct snd_pcm_file **rpcm_file)
|
||||
int stream)
|
||||
{
|
||||
struct snd_pcm_file *pcm_file;
|
||||
struct snd_pcm_substream *substream;
|
||||
int err;
|
||||
|
||||
if (rpcm_file)
|
||||
*rpcm_file = NULL;
|
||||
|
||||
err = snd_pcm_open_substream(pcm, stream, file, &substream);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
@ -2083,8 +2079,7 @@ static int snd_pcm_open_file(struct file *file,
|
|||
substream->pcm_release = pcm_release_private;
|
||||
}
|
||||
file->private_data = pcm_file;
|
||||
if (rpcm_file)
|
||||
*rpcm_file = pcm_file;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2113,7 +2108,6 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file)
|
|||
static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
|
||||
{
|
||||
int err;
|
||||
struct snd_pcm_file *pcm_file;
|
||||
wait_queue_t wait;
|
||||
|
||||
if (pcm == NULL) {
|
||||
|
@ -2131,7 +2125,7 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
|
|||
add_wait_queue(&pcm->open_wait, &wait);
|
||||
mutex_lock(&pcm->open_mutex);
|
||||
while (1) {
|
||||
err = snd_pcm_open_file(file, pcm, stream, &pcm_file);
|
||||
err = snd_pcm_open_file(file, pcm, stream);
|
||||
if (err >= 0)
|
||||
break;
|
||||
if (err == -EAGAIN) {
|
||||
|
@ -3156,8 +3150,8 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
|
|||
/*
|
||||
* mmap the DMA buffer on RAM
|
||||
*/
|
||||
static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
|
||||
struct vm_area_struct *area)
|
||||
int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
|
||||
struct vm_area_struct *area)
|
||||
{
|
||||
area->vm_flags |= VM_RESERVED;
|
||||
#ifdef ARCH_HAS_DMA_MMAP_COHERENT
|
||||
|
@ -3177,6 +3171,7 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
|
|||
area->vm_ops = &snd_pcm_vm_ops_data_fault;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap);
|
||||
|
||||
/*
|
||||
* mmap the DMA buffer on I/O memory area
|
||||
|
@ -3242,7 +3237,7 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
|
|||
if (substream->ops->mmap)
|
||||
err = substream->ops->mmap(substream, area);
|
||||
else
|
||||
err = snd_pcm_default_mmap(substream, area);
|
||||
err = snd_pcm_lib_default_mmap(substream, area);
|
||||
if (!err)
|
||||
atomic_inc(&substream->mmap_count);
|
||||
return err;
|
||||
|
|
|
@ -575,7 +575,8 @@ static void loopback_runtime_free(struct snd_pcm_runtime *runtime)
|
|||
static int loopback_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
|
||||
return snd_pcm_lib_alloc_vmalloc_buffer(substream,
|
||||
params_buffer_bytes(params));
|
||||
}
|
||||
|
||||
static int loopback_hw_free(struct snd_pcm_substream *substream)
|
||||
|
@ -587,7 +588,7 @@ static int loopback_hw_free(struct snd_pcm_substream *substream)
|
|||
mutex_lock(&dpcm->loopback->cable_lock);
|
||||
cable->valid &= ~(1 << substream->stream);
|
||||
mutex_unlock(&dpcm->loopback->cable_lock);
|
||||
return snd_pcm_lib_free_pages(substream);
|
||||
return snd_pcm_lib_free_vmalloc_buffer(substream);
|
||||
}
|
||||
|
||||
static unsigned int get_cable_index(struct snd_pcm_substream *substream)
|
||||
|
@ -740,6 +741,8 @@ static struct snd_pcm_ops loopback_playback_ops = {
|
|||
.prepare = loopback_prepare,
|
||||
.trigger = loopback_trigger,
|
||||
.pointer = loopback_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
static struct snd_pcm_ops loopback_capture_ops = {
|
||||
|
@ -751,6 +754,8 @@ static struct snd_pcm_ops loopback_capture_ops = {
|
|||
.prepare = loopback_prepare,
|
||||
.trigger = loopback_trigger,
|
||||
.pointer = loopback_pointer,
|
||||
.page = snd_pcm_lib_get_vmalloc_page,
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
static int __devinit loopback_pcm_new(struct loopback *loopback,
|
||||
|
@ -771,10 +776,6 @@ static int __devinit loopback_pcm_new(struct loopback *loopback,
|
|||
strcpy(pcm->name, "Loopback PCM");
|
||||
|
||||
loopback->pcm[device] = pcm;
|
||||
|
||||
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
|
||||
snd_dma_continuous_data(GFP_KERNEL),
|
||||
0, 2 * 1024 * 1024);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1153,7 +1153,7 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
|
|||
"0x%x done\n", (unsigned int)ml403_ac97cr->port);
|
||||
/* get irq */
|
||||
irq = platform_get_irq(pfdev, 0);
|
||||
if (request_irq(irq, snd_ml403_ac97cr_irq, IRQF_DISABLED,
|
||||
if (request_irq(irq, snd_ml403_ac97cr_irq, 0,
|
||||
dev_name(&pfdev->dev), (void *)ml403_ac97cr)) {
|
||||
snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
|
||||
"unable to grab IRQ %d\n",
|
||||
|
@ -1166,7 +1166,7 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
|
|||
"request (playback) irq %d done\n",
|
||||
ml403_ac97cr->irq);
|
||||
irq = platform_get_irq(pfdev, 1);
|
||||
if (request_irq(irq, snd_ml403_ac97cr_irq, IRQF_DISABLED,
|
||||
if (request_irq(irq, snd_ml403_ac97cr_irq, 0,
|
||||
dev_name(&pfdev->dev), (void *)ml403_ac97cr)) {
|
||||
snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
|
||||
"unable to grab IRQ %d\n",
|
||||
|
|
|
@ -86,8 +86,7 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard)
|
|||
}
|
||||
|
||||
err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev], 0,
|
||||
irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0,
|
||||
NULL);
|
||||
irq[dev], NULL);
|
||||
if (err < 0) {
|
||||
printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
|
||||
goto _err;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Routines for control of MPU-401 in UART mode
|
||||
*
|
||||
* MPU-401 supports UART mode which is not capable generate transmit
|
||||
* interrupts thus output is done via polling. Also, if irq < 0, then
|
||||
* interrupts thus output is done via polling. Without interrupt,
|
||||
* input is done also via polling. Do not expect good performance.
|
||||
*
|
||||
*
|
||||
|
@ -374,7 +374,7 @@ snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
|
|||
/* first time - flush FIFO */
|
||||
while (max-- > 0)
|
||||
mpu->read(mpu, MPU401D(mpu));
|
||||
if (mpu->irq < 0)
|
||||
if (mpu->info_flags & MPU401_INFO_USE_TIMER)
|
||||
snd_mpu401_uart_add_timer(mpu, 1);
|
||||
}
|
||||
|
||||
|
@ -383,7 +383,7 @@ snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
|
|||
snd_mpu401_uart_input_read(mpu);
|
||||
spin_unlock_irqrestore(&mpu->input_lock, flags);
|
||||
} else {
|
||||
if (mpu->irq < 0)
|
||||
if (mpu->info_flags & MPU401_INFO_USE_TIMER)
|
||||
snd_mpu401_uart_remove_timer(mpu, 1);
|
||||
clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode);
|
||||
}
|
||||
|
@ -496,7 +496,7 @@ static struct snd_rawmidi_ops snd_mpu401_uart_input =
|
|||
static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
|
||||
{
|
||||
struct snd_mpu401 *mpu = rmidi->private_data;
|
||||
if (mpu->irq_flags && mpu->irq >= 0)
|
||||
if (mpu->irq >= 0)
|
||||
free_irq(mpu->irq, (void *) mpu);
|
||||
release_and_free_resource(mpu->res);
|
||||
kfree(mpu);
|
||||
|
@ -509,8 +509,7 @@ static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
|
|||
* @hardware: the hardware type, MPU401_HW_XXXX
|
||||
* @port: the base address of MPU401 port
|
||||
* @info_flags: bitflags MPU401_INFO_XXX
|
||||
* @irq: the irq number, -1 if no interrupt for mpu
|
||||
* @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved.
|
||||
* @irq: the ISA irq number, -1 if not to be allocated
|
||||
* @rrawmidi: the pointer to store the new rawmidi instance
|
||||
*
|
||||
* Creates a new MPU-401 instance.
|
||||
|
@ -525,7 +524,7 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
|
|||
unsigned short hardware,
|
||||
unsigned long port,
|
||||
unsigned int info_flags,
|
||||
int irq, int irq_flags,
|
||||
int irq,
|
||||
struct snd_rawmidi ** rrawmidi)
|
||||
{
|
||||
struct snd_mpu401 *mpu;
|
||||
|
@ -577,8 +576,8 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
|
|||
mpu->cport = port + 2;
|
||||
else
|
||||
mpu->cport = port + 1;
|
||||
if (irq >= 0 && irq_flags) {
|
||||
if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags,
|
||||
if (irq >= 0) {
|
||||
if (request_irq(irq, snd_mpu401_uart_interrupt, 0,
|
||||
"MPU401 UART", (void *) mpu)) {
|
||||
snd_printk(KERN_ERR "mpu401_uart: "
|
||||
"unable to grab IRQ %d\n", irq);
|
||||
|
@ -586,9 +585,10 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
|
|||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
if (irq < 0 && !(info_flags & MPU401_INFO_IRQ_HOOK))
|
||||
info_flags |= MPU401_INFO_USE_TIMER;
|
||||
mpu->info_flags = info_flags;
|
||||
mpu->irq = irq;
|
||||
mpu->irq_flags = irq_flags;
|
||||
if (card->shortname[0])
|
||||
snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI",
|
||||
card->shortname);
|
||||
|
|
|
@ -589,7 +589,7 @@ static int __devinit snd_mtpav_get_ISA(struct mtpav * mcard)
|
|||
return -EBUSY;
|
||||
}
|
||||
mcard->port = port;
|
||||
if (request_irq(irq, snd_mtpav_irqh, IRQF_DISABLED, "MOTU MTPAV", mcard)) {
|
||||
if (request_irq(irq, snd_mtpav_irqh, 0, "MOTU MTPAV", mcard)) {
|
||||
snd_printk(KERN_ERR "MTVAP IRQ %d busy\n", irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
|
|
@ -816,7 +816,7 @@ static int __devinit snd_uart16550_create(struct snd_card *card,
|
|||
|
||||
if (irq >= 0 && irq != SNDRV_AUTO_IRQ) {
|
||||
if (request_irq(irq, snd_uart16550_interrupt,
|
||||
IRQF_DISABLED, "Serial MIDI", uart)) {
|
||||
0, "Serial MIDI", uart)) {
|
||||
snd_printk(KERN_WARNING
|
||||
"irq %d busy. Using Polling.\n", irq);
|
||||
} else {
|
||||
|
|
|
@ -51,7 +51,6 @@ struct isight {
|
|||
struct fw_unit *unit;
|
||||
struct fw_device *device;
|
||||
u64 audio_base;
|
||||
struct fw_address_handler iris_handler;
|
||||
struct snd_pcm_substream *pcm;
|
||||
struct mutex mutex;
|
||||
struct iso_packets_buffer buffer;
|
||||
|
|
|
@ -778,9 +778,10 @@ static int __devexit fwspk_remove(struct device *dev)
|
|||
{
|
||||
struct fwspk *fwspk = dev_get_drvdata(dev);
|
||||
|
||||
mutex_lock(&fwspk->mutex);
|
||||
amdtp_out_stream_pcm_abort(&fwspk->stream);
|
||||
snd_card_disconnect(fwspk->card);
|
||||
|
||||
mutex_lock(&fwspk->mutex);
|
||||
fwspk_stop_stream(fwspk);
|
||||
mutex_unlock(&fwspk->mutex);
|
||||
|
||||
|
@ -796,8 +797,8 @@ static void fwspk_bus_reset(struct fw_unit *unit)
|
|||
fcp_bus_reset(fwspk->unit);
|
||||
|
||||
if (cmp_connection_update(&fwspk->connection) < 0) {
|
||||
mutex_lock(&fwspk->mutex);
|
||||
amdtp_out_stream_pcm_abort(&fwspk->stream);
|
||||
mutex_lock(&fwspk->mutex);
|
||||
fwspk_stop_stream(fwspk);
|
||||
mutex_unlock(&fwspk->mutex);
|
||||
return;
|
||||
|
|
|
@ -204,7 +204,7 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard
|
|||
|
||||
if (mpu_port[dev] > 0) {
|
||||
if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
|
||||
mpu_port[dev], 0, mpu_irq[dev], IRQF_DISABLED,
|
||||
mpu_port[dev], 0, mpu_irq[dev],
|
||||
NULL) < 0)
|
||||
printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n", mpu_port[dev]);
|
||||
}
|
||||
|
|
|
@ -595,7 +595,7 @@ int __devinit snd_ad1816a_create(struct snd_card *card,
|
|||
snd_ad1816a_free(chip);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (request_irq(irq, snd_ad1816a_interrupt, IRQF_DISABLED, "AD1816A", (void *) chip)) {
|
||||
if (request_irq(irq, snd_ad1816a_interrupt, 0, "AD1816A", (void *) chip)) {
|
||||
snd_printk(KERN_ERR "ad1816a: can't grab IRQ %d\n", irq);
|
||||
snd_ad1816a_free(chip);
|
||||
return -EBUSY;
|
||||
|
|
|
@ -256,7 +256,6 @@ static int __devinit snd_card_als100_probe(int dev,
|
|||
mpu_type,
|
||||
mpu_port[dev], 0,
|
||||
mpu_irq[dev],
|
||||
mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
|
||||
NULL) < 0)
|
||||
snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]);
|
||||
}
|
||||
|
|
|
@ -234,8 +234,7 @@ static int __devinit snd_card_azt2320_probe(int dev,
|
|||
if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
|
||||
if (snd_mpu401_uart_new(card, 0, MPU401_HW_AZT2320,
|
||||
mpu_port[dev], 0,
|
||||
mpu_irq[dev], IRQF_DISABLED,
|
||||
NULL) < 0)
|
||||
mpu_irq[dev], NULL) < 0)
|
||||
snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]);
|
||||
}
|
||||
|
||||
|
|
|
@ -597,7 +597,7 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
|
|||
if (mpuport[dev] != SNDRV_AUTO_PORT) {
|
||||
if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
|
||||
mpuport[dev], 0, mpuirq[dev],
|
||||
IRQF_DISABLED, NULL) < 0)
|
||||
NULL) < 0)
|
||||
printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n",
|
||||
mpuport[dev]);
|
||||
}
|
||||
|
|
|
@ -131,7 +131,6 @@ static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n)
|
|||
mpu_irq[n] = -1;
|
||||
if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232,
|
||||
mpu_port[n], 0, mpu_irq[n],
|
||||
mpu_irq[n] >= 0 ? IRQF_DISABLED : 0,
|
||||
NULL) < 0)
|
||||
dev_warn(dev, "MPU401 not detected\n");
|
||||
}
|
||||
|
|
|
@ -449,8 +449,7 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
|
|||
mpu_irq[dev] = -1;
|
||||
if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232,
|
||||
mpu_port[dev], 0,
|
||||
mpu_irq[dev],
|
||||
mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, NULL) < 0)
|
||||
mpu_irq[dev], NULL) < 0)
|
||||
printk(KERN_WARNING IDENT ": MPU401 not detected\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n)
|
|||
chip->mpu_port > 0) {
|
||||
error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
|
||||
chip->mpu_port, 0,
|
||||
mpu_irq[n], IRQF_DISABLED, NULL);
|
||||
mpu_irq[n], NULL);
|
||||
if (error < 0)
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -661,7 +661,7 @@ int snd_es1688_create(struct snd_card *card,
|
|||
snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) {
|
||||
if (request_irq(irq, snd_es1688_interrupt, 0, "ES1688", (void *) chip)) {
|
||||
snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
|
|
@ -1805,7 +1805,7 @@ static int __devinit snd_es18xx_new_device(struct snd_card *card,
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (request_irq(irq, snd_es18xx_interrupt, IRQF_DISABLED, "ES18xx",
|
||||
if (request_irq(irq, snd_es18xx_interrupt, 0, "ES18xx",
|
||||
(void *) card)) {
|
||||
snd_es18xx_free(card);
|
||||
snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq);
|
||||
|
@ -2160,8 +2160,8 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
|
|||
|
||||
if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
|
||||
err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
|
||||
mpu_port[dev], 0,
|
||||
irq[dev], 0, &chip->rmidi);
|
||||
mpu_port[dev], MPU401_INFO_IRQ_HOOK,
|
||||
-1, &chip->rmidi);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -585,8 +585,7 @@ static int __devinit snd_galaxy_probe(struct device *dev, unsigned int n)
|
|||
|
||||
if (mpu_port[n] >= 0) {
|
||||
err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
|
||||
mpu_port[n], 0, mpu_irq[n],
|
||||
IRQF_DISABLED, NULL);
|
||||
mpu_port[n], 0, mpu_irq[n], NULL);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ int snd_gus_create(struct snd_card *card,
|
|||
snd_gus_free(gus);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (irq >= 0 && request_irq(irq, snd_gus_interrupt, IRQF_DISABLED, "GUS GF1", (void *) gus)) {
|
||||
if (irq >= 0 && request_irq(irq, snd_gus_interrupt, 0, "GUS GF1", (void *) gus)) {
|
||||
snd_printk(KERN_ERR "gus: can't grab irq %d\n", irq);
|
||||
snd_gus_free(gus);
|
||||
return -EBUSY;
|
||||
|
|
|
@ -317,8 +317,7 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
|
|||
|
||||
if (es1688->mpu_port >= 0x300) {
|
||||
error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
|
||||
es1688->mpu_port, 0,
|
||||
mpu_irq[n], IRQF_DISABLED, NULL);
|
||||
es1688->mpu_port, 0, mpu_irq[n], NULL);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -291,7 +291,7 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
|
|||
goto _err;
|
||||
}
|
||||
|
||||
if (request_irq(xirq, snd_gusmax_interrupt, IRQF_DISABLED, "GUS MAX", (void *)maxcard)) {
|
||||
if (request_irq(xirq, snd_gusmax_interrupt, 0, "GUS MAX", (void *)maxcard)) {
|
||||
snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
|
||||
err = -EBUSY;
|
||||
goto _err;
|
||||
|
|
|
@ -684,7 +684,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
|
|||
if ((err = snd_gus_initialize(gus)) < 0)
|
||||
return err;
|
||||
|
||||
if (request_irq(xirq, snd_interwave_interrupt, IRQF_DISABLED,
|
||||
if (request_irq(xirq, snd_interwave_interrupt, 0,
|
||||
"InterWave", iwcard)) {
|
||||
snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
|
||||
return -EBUSY;
|
||||
|
|
|
@ -600,7 +600,7 @@ static int __devinit snd_msnd_attach(struct snd_card *card)
|
|||
mpu_io[0],
|
||||
MPU401_MODE_INPUT |
|
||||
MPU401_MODE_OUTPUT,
|
||||
mpu_irq[0], IRQF_DISABLED,
|
||||
mpu_irq[0],
|
||||
&chip->rmidi);
|
||||
if (err < 0) {
|
||||
printk(KERN_ERR LOGNAME
|
||||
|
|
|
@ -667,7 +667,7 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev)
|
|||
err = snd_opl3sa2_detect(card);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = request_irq(xirq, snd_opl3sa2_interrupt, IRQF_DISABLED,
|
||||
err = request_irq(xirq, snd_opl3sa2_interrupt, 0,
|
||||
"OPL3-SA2", card);
|
||||
if (err) {
|
||||
snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq);
|
||||
|
@ -707,8 +707,9 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev)
|
|||
}
|
||||
if (midi_port[dev] >= 0x300 && midi_port[dev] < 0x340) {
|
||||
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2,
|
||||
midi_port[dev], 0,
|
||||
xirq, 0, &chip->rmidi)) < 0)
|
||||
midi_port[dev],
|
||||
MPU401_INFO_IRQ_HOOK, -1,
|
||||
&chip->rmidi)) < 0)
|
||||
return err;
|
||||
}
|
||||
sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
|
||||
|
|
|
@ -1377,8 +1377,7 @@ static int __devinit snd_miro_probe(struct snd_card *card)
|
|||
rmidi = NULL;
|
||||
else {
|
||||
error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
|
||||
mpu_port, 0, miro->mpu_irq, IRQF_DISABLED,
|
||||
&rmidi);
|
||||
mpu_port, 0, miro->mpu_irq, &rmidi);
|
||||
if (error < 0)
|
||||
snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
|
||||
mpu_port);
|
||||
|
|
|
@ -892,7 +892,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
|||
#endif
|
||||
#ifdef OPTi93X
|
||||
error = request_irq(irq, snd_opti93x_interrupt,
|
||||
IRQF_DISABLED, DEV_NAME" - WSS", chip);
|
||||
0, DEV_NAME" - WSS", chip);
|
||||
if (error < 0) {
|
||||
snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", irq);
|
||||
return error;
|
||||
|
@ -914,7 +914,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
|||
rmidi = NULL;
|
||||
else {
|
||||
error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
|
||||
mpu_port, 0, mpu_irq, IRQF_DISABLED, &rmidi);
|
||||
mpu_port, 0, mpu_irq, &rmidi);
|
||||
if (error)
|
||||
snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
|
||||
mpu_port);
|
||||
|
|
|
@ -322,7 +322,6 @@ static int __devinit snd_jazz16_probe(struct device *devptr, unsigned int dev)
|
|||
MPU401_HW_MPU401,
|
||||
mpu_port[dev], 0,
|
||||
mpu_irq[dev],
|
||||
mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
|
||||
NULL) < 0)
|
||||
snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n",
|
||||
mpu_port[dev]);
|
||||
|
|
|
@ -394,8 +394,9 @@ static int __devinit snd_sb16_probe(struct snd_card *card, int dev)
|
|||
|
||||
if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) {
|
||||
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB,
|
||||
chip->mpu_port, 0,
|
||||
xirq, 0, &chip->rmidi)) < 0)
|
||||
chip->mpu_port,
|
||||
MPU401_INFO_IRQ_HOOK, -1,
|
||||
&chip->rmidi)) < 0)
|
||||
return err;
|
||||
chip->rmidi_callback = snd_mpu401_uart_interrupt;
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ int snd_sbdsp_create(struct snd_card *card,
|
|||
if (request_irq(irq, irq_handler,
|
||||
(hardware == SB_HW_ALS4000 ||
|
||||
hardware == SB_HW_CS5530) ?
|
||||
IRQF_SHARED : IRQF_DISABLED,
|
||||
IRQF_SHARED : 0,
|
||||
"SoundBlaster", (void *) chip)) {
|
||||
snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq);
|
||||
snd_sbdsp_free(chip);
|
||||
|
|
|
@ -658,8 +658,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
|
|||
if (snd_mpu401_uart_new(card, 0,
|
||||
MPU401_HW_MPU401,
|
||||
mpu_port[dev], 0,
|
||||
mpu_irq[dev], IRQF_DISABLED,
|
||||
NULL) < 0)
|
||||
mpu_irq[dev], NULL) < 0)
|
||||
snd_printk(KERN_ERR "no MPU-401 device at 0x%lx ?\n",
|
||||
mpu_port[dev]);
|
||||
}
|
||||
|
|
|
@ -825,8 +825,7 @@ static int __devinit create_mpu401(struct snd_card *card, int devnum,
|
|||
int err;
|
||||
|
||||
err = snd_mpu401_uart_new(card, devnum, MPU401_HW_MPU401, port,
|
||||
MPU401_INFO_INTEGRATED, irq, IRQF_DISABLED,
|
||||
&rawmidi);
|
||||
MPU401_INFO_INTEGRATED, irq, &rawmidi);
|
||||
if (err == 0) {
|
||||
struct snd_mpu401 *mpu = rawmidi->private_data;
|
||||
mpu->open_input = mpu401_open;
|
||||
|
|
|
@ -418,7 +418,7 @@ snd_wavefront_probe (struct snd_card *card, int dev)
|
|||
return -EBUSY;
|
||||
}
|
||||
if (request_irq(ics2115_irq[dev], snd_wavefront_ics2115_interrupt,
|
||||
IRQF_DISABLED, "ICS2115", acard)) {
|
||||
0, "ICS2115", acard)) {
|
||||
snd_printk(KERN_ERR "unable to use ICS2115 IRQ %d\n", ics2115_irq[dev]);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
@ -449,8 +449,7 @@ snd_wavefront_probe (struct snd_card *card, int dev)
|
|||
if (cs4232_mpu_port[dev] > 0 && cs4232_mpu_port[dev] != SNDRV_AUTO_PORT) {
|
||||
err = snd_mpu401_uart_new(card, midi_dev, MPU401_HW_CS4232,
|
||||
cs4232_mpu_port[dev], 0,
|
||||
cs4232_mpu_irq[dev], IRQF_DISABLED,
|
||||
NULL);
|
||||
cs4232_mpu_irq[dev], NULL);
|
||||
if (err < 0) {
|
||||
snd_printk (KERN_ERR "can't allocate CS4232 MPU-401 device\n");
|
||||
return err;
|
||||
|
|
|
@ -1833,7 +1833,7 @@ int snd_wss_create(struct snd_card *card,
|
|||
}
|
||||
chip->cport = cport;
|
||||
if (!(hwshare & WSS_HWSHARE_IRQ))
|
||||
if (request_irq(irq, snd_wss_interrupt, IRQF_DISABLED,
|
||||
if (request_irq(irq, snd_wss_interrupt, 0,
|
||||
"WSS", (void *) chip)) {
|
||||
snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq);
|
||||
snd_wss_free(chip);
|
||||
|
|
|
@ -23,12 +23,15 @@ config SND_SGI_HAL2
|
|||
|
||||
|
||||
config SND_AU1X00
|
||||
tristate "Au1x00 AC97 Port Driver"
|
||||
tristate "Au1x00 AC97 Port Driver (DEPRECATED)"
|
||||
depends on SOC_AU1000 || SOC_AU1100 || SOC_AU1500
|
||||
select SND_PCM
|
||||
select SND_AC97_CODEC
|
||||
help
|
||||
ALSA Sound driver for the Au1x00's AC97 port.
|
||||
|
||||
Newer drivers for ASoC are available, please do not use
|
||||
this driver as it will be removed in the future.
|
||||
|
||||
endif # SND_MIPS
|
||||
|
||||
|
|
|
@ -465,13 +465,13 @@ snd_au1000_pcm_new(struct snd_au1000 *au1000)
|
|||
|
||||
flags = claim_dma_lock();
|
||||
if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX,
|
||||
"AC97 TX", au1000_dma_interrupt, IRQF_DISABLED,
|
||||
"AC97 TX", au1000_dma_interrupt, 0,
|
||||
au1000->stream[PLAYBACK])) < 0) {
|
||||
release_dma_lock(flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
if ((au1000->stream[CAPTURE]->dma = request_au1000_dma(DMA_ID_AC97C_RX,
|
||||
"AC97 RX", au1000_dma_interrupt, IRQF_DISABLED,
|
||||
"AC97 RX", au1000_dma_interrupt, 0,
|
||||
au1000->stream[CAPTURE])) < 0){
|
||||
release_dma_lock(flags);
|
||||
return -EBUSY;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue