mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 22:00:53 +07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/perex/alsa
* git://git.kernel.org/pub/scm/linux/kernel/git/perex/alsa: (124 commits) [ALSA] version 1.0.11rc4 [PATCH] Intruduce DMA_28BIT_MASK [ALSA] hda-codec - Add support for ASUS P4GPL-X [ALSA] hda-codec - Add support for HP nx9420 laptop [ALSA] Fix memory leaks in error path of control.c [ALSA] AMD Au1x00: AC'97 controller is memory mapped [ALSA] AMD Au1x00: fix DMA init/cleanup [ALSA] hda-codec - Fix generic auto-configurator [ALSA] hda-codec - Fix BIOS auto-configuration [ALSA] Fixes typos in Audiophile-USB.txt [ALSA] ice1712 - typo fixes for dxr_enable module option [ALSA] AMD Au1x00: make driver build after cleanup [ALSA] ice1712 - Fix wrong value types for enum items [ALSA] fix resource leak in usbmixer [ALSA] Fix gus_pcm dereference before NULL [ALSA] Fix seq_clientmgr dereferences before NULL check [ALSA] hda-codec - Fix for Samsung R65 and ASUS A6J [ALSA] hda-codec - Add support for VAIO FE550G and SZ110 [ALSA] usb-audio: add Maya44 mixer control names [ALSA] usb-audio: add Casio PL-40R support ...
This commit is contained in:
commit
1c2e02750b
@ -513,6 +513,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-ens1371
|
||||
------------------
|
||||
|
||||
@ -526,6 +528,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-es968
|
||||
----------------
|
||||
|
||||
@ -671,6 +675,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
|
||||
model - force the model name
|
||||
position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
|
||||
single_cmd - Use single immediate commands to communicate with
|
||||
codecs (for debugging only)
|
||||
|
||||
This module supports one card and autoprobe.
|
||||
|
||||
@ -694,13 +700,34 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
asus 3-jack
|
||||
uniwill 3-jack
|
||||
F1734 2-jack
|
||||
lg LG laptop (m1 express dual)
|
||||
test for testing/debugging purpose, almost all controls can be
|
||||
adjusted. Appearing only when compiled with
|
||||
$CONFIG_SND_DEBUG=y
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC260
|
||||
hp HP machines
|
||||
fujitsu Fujitsu S7020
|
||||
acer Acer TravelMate
|
||||
basic fixed pin assignment (old default model)
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC262
|
||||
fujitsu Fujitsu Laptop
|
||||
basic fixed pin assignment w/o SPDIF
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC882/883/885
|
||||
3stack-dig 3-jack with SPDIF I/O
|
||||
6stck-dig 6-jack digital with SPDIF I/O
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
ALC861
|
||||
3stack 3-jack
|
||||
3stack-dig 3-jack with SPDIF I/O
|
||||
6stack-dig 6-jack with SPDIF I/O
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
CMI9880
|
||||
minimal 3-jack in back
|
||||
@ -710,6 +737,28 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
allout 5-jack in back, 2-jack in front, SPDIF out
|
||||
auto auto-config reading BIOS (default)
|
||||
|
||||
AD1981
|
||||
basic 3-jack (default)
|
||||
hp HP nx6320
|
||||
|
||||
AD1986A
|
||||
6stack 6-jack, separate surrounds (default)
|
||||
3stack 3-stack, shared surrounds
|
||||
laptop 2-channel only (FSC V2060, Samsung M50)
|
||||
laptop-eapd 2-channel with EAPD (Samsung R65, ASUS A6J)
|
||||
|
||||
AD1988
|
||||
6stack 6-jack
|
||||
6stack-dig ditto with SPDIF
|
||||
3stack 3-jack
|
||||
3stack-dig ditto with SPDIF
|
||||
laptop 3-jack with hp-jack automute
|
||||
laptop-dig ditto with SPDIF
|
||||
auto auto-confgi reading BIOS (default)
|
||||
|
||||
STAC7661(?)
|
||||
vaio Setup for VAIO FE550G/SZ110
|
||||
|
||||
If the default configuration doesn't work and one of the above
|
||||
matches with your device, report it together with the PCI
|
||||
subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel
|
||||
@ -723,6 +772,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
(Usually SD_LPLIB register is more accurate than the
|
||||
position buffer.)
|
||||
|
||||
NB: If you get many "azx_get_response timeout" messages at
|
||||
loading, it's likely a problem of interrupts (e.g. ACPI irq
|
||||
routing). Try to boot with options like "pci=noacpi". Also, you
|
||||
can try "single_cmd=1" module option. This will switch the
|
||||
communication method between HDA controller and codecs to the
|
||||
single immediate commands instead of CORB/RIRB. Basically, the
|
||||
single command mode is provided only for BIOS, and you won't get
|
||||
unsolicited events, too. But, at least, this works independently
|
||||
from the irq. Remember this is a last resort, and should be
|
||||
avoided as much as possible...
|
||||
|
||||
The power-management is supported.
|
||||
|
||||
Module snd-hdsp
|
||||
@ -802,6 +862,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
------------------
|
||||
|
||||
Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards.
|
||||
* MidiMan M Audio Revolution 5.1
|
||||
* MidiMan M Audio Revolution 7.1
|
||||
* AMP Ltd AUDIO2000
|
||||
* TerraTec Aureon 5.1 Sky
|
||||
@ -810,6 +871,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
* TerraTec Phase 22
|
||||
* TerraTec Phase 28
|
||||
* AudioTrak Prodigy 7.1
|
||||
* AudioTrak Prodigy 7.1LT
|
||||
* AudioTrak Prodigy 192
|
||||
* Pontis MS300
|
||||
* Albatron K8X800 Pro II
|
||||
@ -820,9 +882,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
* Shuttle SN25P
|
||||
|
||||
model - Use the given board model, one of the following:
|
||||
revo71, amp2000, prodigy71, prodigy192, aureon51,
|
||||
aureon71, universe, k8x800, phase22, phase28, ms300,
|
||||
av710
|
||||
revo51, revo71, amp2000, prodigy71, prodigy71lt,
|
||||
prodigy192, aureon51, aureon71, universe,
|
||||
k8x800, phase22, phase28, ms300, av710
|
||||
|
||||
This module supports multiple cards and autoprobe.
|
||||
|
||||
@ -1353,6 +1415,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
|
||||
|
||||
vid - Vendor ID for the device (optional)
|
||||
pid - Product ID for the device (optional)
|
||||
device_setup - Device specific magic number (optional)
|
||||
- Influence depends on the device
|
||||
- Default: 0x0000
|
||||
|
||||
This module supports multiple devices, autoprobe and hotplugging.
|
||||
|
||||
|
333
Documentation/sound/alsa/Audiophile-Usb.txt
Normal file
333
Documentation/sound/alsa/Audiophile-Usb.txt
Normal file
@ -0,0 +1,333 @@
|
||||
Guide to using M-Audio Audiophile USB with ALSA and Jack v1.2
|
||||
========================================================
|
||||
|
||||
Thibault Le Meur <Thibault.LeMeur@supelec.fr>
|
||||
|
||||
This document is a guide to using the M-Audio Audiophile USB (tm) device with
|
||||
ALSA and JACK.
|
||||
|
||||
1 - Audiophile USB Specs and correct usage
|
||||
==========================================
|
||||
This part is a reminder of important facts about the functions and limitations
|
||||
of the device.
|
||||
|
||||
The device has 4 audio interfaces, and 2 MIDI ports:
|
||||
* Analog Stereo Input (Ai)
|
||||
- This port supports 2 pairs of line-level audio inputs (1/4" TS and RCA)
|
||||
- When the 1/4" TS (jack) connectors are connected, the RCA connectors
|
||||
are disabled
|
||||
* Analog Stereo Output (Ao)
|
||||
* Digital Stereo Input (Di)
|
||||
* Digital Stereo Output (Do)
|
||||
* Midi In (Mi)
|
||||
* Midi Out (Mo)
|
||||
|
||||
The internal DAC/ADC has the following caracteristics:
|
||||
* sample depth of 16 or 24 bits
|
||||
* sample rate from 8kHz to 96kHz
|
||||
* Two ports can't use different sample depths at the same time.Moreover, the
|
||||
Audiophile USB documentation gives the following Warning: "Please exit any
|
||||
audio application running before switching between bit depths"
|
||||
|
||||
Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be
|
||||
activated at the same time depending on the audio mode selected:
|
||||
* 16-bit/48kHz ==> 4 channels in/ 4 channels out
|
||||
- Ai+Ao+Di+Do
|
||||
* 24-bit/48kHz ==> 4 channels in/2 channels out,
|
||||
or 2 channels in/4 channels out
|
||||
- Ai+Ao+Do or Ai+Di+Ao or Ai+Di+Do or Di+Ao+Do
|
||||
* 24-bit/96kHz ==> 2 channels in, or 2 channels out (half duplex only)
|
||||
- Ai or Ao or Di or Do
|
||||
|
||||
Important facts about the Digital interface:
|
||||
--------------------------------------------
|
||||
* The Do port additionnaly supports surround-encoded AC-3 and DTS passthrough,
|
||||
though I haven't tested it under linux
|
||||
- Note that in this setup only the Do interface can be enabled
|
||||
* Apart from recording an audio digital stream, enabling the Di port is a way
|
||||
to synchronize the device to an external sample clock
|
||||
- As a consequence, the Di port must be enable only if an active Digital
|
||||
source is connected
|
||||
- Enabling Di when no digital source is connected can result in a
|
||||
synchronization error (for instance sound played at an odd sample rate)
|
||||
|
||||
|
||||
2 - Audiophile USB support in ALSA
|
||||
==================================
|
||||
|
||||
2.1 - MIDI ports
|
||||
----------------
|
||||
The Audiophile USB MIDI ports will be automatically supported once the
|
||||
following modules have been loaded:
|
||||
* snd-usb-audio
|
||||
* snd-seq
|
||||
* snd-seq-midi
|
||||
|
||||
No additionnal setting is required.
|
||||
|
||||
2.2 - Audio ports
|
||||
-----------------
|
||||
|
||||
Audio functions of the Audiophile USB device are handled by the snd-usb-audio
|
||||
module. This module can work in a default mode (without any device-specific
|
||||
parameter), or in an advanced mode with the device-specific parameter called
|
||||
"device_setup".
|
||||
|
||||
2.2.1 - Default Alsa driver mode
|
||||
|
||||
The default behaviour of the snd-usb-audio driver is to parse the device
|
||||
capabilities at startup and enable all functions inside the device (including
|
||||
all ports at any sample rates and any sample depths supported). This approach
|
||||
has the advantage to let the driver easily switch from sample rates/depths
|
||||
automatically according to the need of the application claiming the device.
|
||||
|
||||
In this case the Audiophile ports are mapped to alsa pcm devices in the
|
||||
following way (I suppose the device's index is 1):
|
||||
* hw:1,0 is Ao in playback and Di in capture
|
||||
* hw:1,1 is Do in playback and Ai in capture
|
||||
* hw:1,2 is Do in AC3/DTS passthrough mode
|
||||
|
||||
You must note as well that the device uses Big Endian byte encoding so that
|
||||
supported audio format are S16_BE for 16-bit depth modes and S24_3BE for
|
||||
24-bits depth mode. One exception is the hw:1,2 port which is Little Endian
|
||||
compliant and thus uses S16_LE.
|
||||
|
||||
Examples:
|
||||
* playing a S24_3BE encoded raw file to the Ao port
|
||||
% aplay -D hw:1,0 -c2 -t raw -r48000 -fS24_3BE test.raw
|
||||
* recording a S24_3BE encoded raw file from the Ai port
|
||||
% arecord -D hw:1,1 -c2 -t raw -r48000 -fS24_3BE test.raw
|
||||
* playing a S16_BE encoded raw file to the Do port
|
||||
% aplay -D hw:1,1 -c2 -t raw -r48000 -fS16_BE test.raw
|
||||
|
||||
If you're happy with the default Alsa driver setup and don't experience any
|
||||
issue with this mode, then you can skip the following chapter.
|
||||
|
||||
2.2.2 - Advanced module setup
|
||||
|
||||
Due to the hardware constraints described above, the device initialization made
|
||||
by the Alsa driver in default mode may result in a corrupted state of the
|
||||
device. For instance, a particularly annoying issue is that the sound captured
|
||||
from the Ai port sounds distorted (as if boosted with an excessive high volume
|
||||
gain).
|
||||
|
||||
For people having this problem, the snd-usb-audio module has a new module
|
||||
parameter called "device_setup".
|
||||
|
||||
2.2.2.1 - Initializing the working mode of the Audiohile USB
|
||||
|
||||
As far as the Audiohile USB device is concerned, this value let the user
|
||||
specify:
|
||||
* the sample depth
|
||||
* the sample rate
|
||||
* whether the Di port is used or not
|
||||
|
||||
Here is a list of supported device_setup values for this device:
|
||||
* device_setup=0x00 (or omitted)
|
||||
- Alsa driver default mode
|
||||
- maintains backward compatibility with setups that do not use this
|
||||
parameter by not introducing any change
|
||||
- results sometimes in corrupted sound as decribed earlier
|
||||
* device_setup=0x01
|
||||
- 16bits 48kHz mode with Di disabled
|
||||
- Ai,Ao,Do can be used at the same time
|
||||
- hw:1,0 is not available in capture mode
|
||||
- hw:1,2 is not available
|
||||
* device_setup=0x11
|
||||
- 16bits 48kHz mode with Di enabled
|
||||
- Ai,Ao,Di,Do can be used at the same time
|
||||
- hw:1,0 is available in capture mode
|
||||
- hw:1,2 is not available
|
||||
* device_setup=0x09
|
||||
- 24bits 48kHz mode with Di disabled
|
||||
- Ai,Ao,Do can be used at the same time
|
||||
- hw:1,0 is not available in capture mode
|
||||
- hw:1,2 is not available
|
||||
* device_setup=0x19
|
||||
- 24bits 48kHz mode with Di enabled
|
||||
- 3 ports from {Ai,Ao,Di,Do} can be used at the same time
|
||||
- hw:1,0 is available in capture mode and an active digital source must be
|
||||
connected to Di
|
||||
- hw:1,2 is not available
|
||||
* device_setup=0x0D or 0x10
|
||||
- 24bits 96kHz mode
|
||||
- Di is enabled by default for this mode but does not need to be connected
|
||||
to an active source
|
||||
- Only 1 port from {Ai,Ao,Di,Do} can be used at the same time
|
||||
- hw:1,0 is available in captured mode
|
||||
- hw:1,2 is not available
|
||||
* device_setup=0x03
|
||||
- 16bits 48kHz mode with only the Do port enabled
|
||||
- AC3 with DTS passthru (not tested)
|
||||
- Caution with this setup the Do port is mapped to the pcm device hw:1,0
|
||||
|
||||
2.2.2.2 - Setting and switching configurations with the device_setup parameter
|
||||
|
||||
The parameter can be given:
|
||||
* By manually probing the device (as root):
|
||||
# modprobe -r snd-usb-audio
|
||||
# modprobe snd-usb-audio index=1 device_setup=0x09
|
||||
* Or while configuring the modules options in your modules configuration file
|
||||
- For Fedora distributions, edit the /etc/modprobe.conf file:
|
||||
alias snd-card-1 snd-usb-audio
|
||||
options snd-usb-audio index=1 device_setup=0x09
|
||||
|
||||
IMPORTANT NOTE WHEN SWITCHING CONFIGURATION:
|
||||
-------------------------------------------
|
||||
* You may need to _first_ intialize the module with the correct device_setup
|
||||
parameter and _only_after_ turn on the Audiophile USB device
|
||||
* This is especially true when switching the sample depth:
|
||||
- first trun off the device
|
||||
- de-register the snd-usb-audio module
|
||||
- change the device_setup parameter (by either manually reprobing the module
|
||||
or changing modprobe.conf)
|
||||
- turn on the device
|
||||
|
||||
2.2.2.3 - Audiophile USB's device_setup structure
|
||||
|
||||
If you want to understand the device_setup magic numbers for the Audiophile
|
||||
USB, you need some very basic understanding of binary computation. However,
|
||||
this is not required to use the parameter and you may skip thi section.
|
||||
|
||||
The device_setup is one byte long and its structure is the following:
|
||||
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| b7| b6| b5| b4| b3| b2| b1| b0|
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| 0 | 0 | 0 | Di|24B|96K|DTS|SET|
|
||||
+---+---+---+---+---+---+---+---+
|
||||
|
||||
Where:
|
||||
* b0 is the "SET" bit
|
||||
- it MUST be set if device_setup is initialized
|
||||
* b1 is the "DTS" bit
|
||||
- it is set only for Digital output with DTS/AC3
|
||||
- this setup is not tested
|
||||
* b2 is the Rate selection flag
|
||||
- When set to "1" the rate range is 48.1-96kHz
|
||||
- Otherwise the sample rate range is 8-48kHz
|
||||
* b3 is the bit depth selection flag
|
||||
- When set to "1" samples are 24bits long
|
||||
- Otherwise they are 16bits long
|
||||
- Note that b2 implies b3 as the 96kHz mode is only supported for 24 bits
|
||||
samples
|
||||
* b4 is the Digital input flag
|
||||
- When set to "1" the device assumes that an active digital source is
|
||||
connected
|
||||
- You shouldn't enable Di if no source is seen on the port (this leads to
|
||||
synchronization issues)
|
||||
- b4 is implied by b2 (since only one port is enabled at a time no synch
|
||||
error can occur)
|
||||
* b5 to b7 are reserved for future uses, and must be set to "0"
|
||||
- might become Ao, Do, Ai, for b7, b6, b4 respectively
|
||||
|
||||
Caution:
|
||||
* there is no check on the value you will give to device_setup
|
||||
- for instance choosing 0x05 (16bits 96kHz) will fail back to 0x09 since
|
||||
b2 implies b3. But _there_will_be_no_warning_ in /var/log/messages
|
||||
* Hardware constraints due to the USB bus limitation aren't checked
|
||||
- choosing b2 will prepare all interfaces for 24bits/96kHz but you'll
|
||||
only be able to use one at the same time
|
||||
|
||||
2.2.3 - USB implementation details for this device
|
||||
|
||||
You may safely skip this section if you're not interrested in driver
|
||||
development.
|
||||
|
||||
This section describes some internals aspect of the device and summarize the
|
||||
data I got by usb-snooping the windows and linux drivers.
|
||||
|
||||
The M-Audio Audiophile USB has 7 USB Interfaces:
|
||||
a "USB interface":
|
||||
* USB Interface nb.0
|
||||
* USB Interface nb.1
|
||||
- Audio Control function
|
||||
* USB Interface nb.2
|
||||
- Analog Output
|
||||
* USB Interface nb.3
|
||||
- Digital Output
|
||||
* USB Interface nb.4
|
||||
- Analog Input
|
||||
* USB Interface nb.5
|
||||
- Digital Input
|
||||
* USB Interface nb.6
|
||||
- MIDI interface compliant with the MIDIMAN quirk
|
||||
|
||||
Each interface has 5 altsettings (AltSet 1,2,3,4,5) except:
|
||||
* Interface 3 (Digital Out) has an extra Alset nb.6
|
||||
* Interface 5 (Digital In) does not have Alset nb.3 and 5
|
||||
|
||||
Here is a short description of the AltSettings capabilities:
|
||||
* AltSettings 1 corresponds to
|
||||
- 24-bit depth, 48.1-96kHz sample mode
|
||||
- Adaptive playback (Ao and Do), Synch capture (Ai), or Asynch capture (Di)
|
||||
* AltSettings 2 corresponds to
|
||||
- 24-bit depth, 8-48kHz sample mode
|
||||
- Asynch capture and playback (Ao,Ai,Do,Di)
|
||||
* AltSettings 3 corresponds to
|
||||
- 24-bit depth, 8-48kHz sample mode
|
||||
- Synch capture (Ai) and Adaptive playback (Ao,Do)
|
||||
* AltSettings 4 corresponds to
|
||||
- 16-bit depth, 8-48kHz sample mode
|
||||
- Asynch capture and playback (Ao,Ai,Do,Di)
|
||||
* AltSettings 5 corresponds to
|
||||
- 16-bit depth, 8-48kHz sample mode
|
||||
- Synch capture (Ai) and Adaptive playback (Ao,Do)
|
||||
* AltSettings 6 corresponds to
|
||||
- 16-bit depth, 8-48kHz sample mode
|
||||
- Synch playback (Do), audio format type III IEC1937_AC-3
|
||||
|
||||
In order to ensure a correct intialization of the device, the driver
|
||||
_must_know_ how the device will be used:
|
||||
* if DTS is choosen, only Interface 2 with AltSet nb.6 must be
|
||||
registered
|
||||
* if 96KHz only AltSets nb.1 of each interface must be selected
|
||||
* if samples are using 24bits/48KHz then AltSet 2 must me used if
|
||||
Digital input is connected, and only AltSet nb.3 if Digital input
|
||||
is not connected
|
||||
* if samples are using 16bits/48KHz then AltSet 4 must me used if
|
||||
Digital input is connected, and only AltSet nb.5 if Digital input
|
||||
is not connected
|
||||
|
||||
When device_setup is given as a parameter to the snd-usb-audio module, the
|
||||
parse_audio_enpoint function uses a quirk called
|
||||
"audiophile_skip_setting_quirk" in order to prevent AltSettings not
|
||||
corresponding to device_setup from being registered in the driver.
|
||||
|
||||
3 - Audiophile USB and Jack support
|
||||
===================================
|
||||
|
||||
This section deals with support of the Audiophile USB device in Jack.
|
||||
The main issue regarding this support is that the device is Big Endian
|
||||
compliant.
|
||||
|
||||
3.1 - Using the plug alsa plugin
|
||||
--------------------------------
|
||||
|
||||
Jack doesn't directly support big endian devices. Thus, one way to have support
|
||||
for this device with Alsa is to use the Alsa "plug" converter.
|
||||
|
||||
For instance here is one way to run Jack with 2 playback channels on Ao and 2
|
||||
capture channels from Ai:
|
||||
% jackd -R -dalsa -dplughw:1 -r48000 -p256 -n2 -D -Cplughw:1,1
|
||||
|
||||
|
||||
However you may see the following warning message:
|
||||
"You appear to be using the ALSA software "plug" layer, probably a result of
|
||||
using the "default" ALSA device. This is less efficient than it could be.
|
||||
Consider using a hardware device instead rather than using the plug layer."
|
||||
|
||||
|
||||
3.2 - Patching alsa to use direct pcm device
|
||||
-------------------------------------------
|
||||
A patch for Jack by Andreas Steinmetz adds support for Big Endian devices.
|
||||
However it has not been included in the CVS tree.
|
||||
|
||||
You can find it at the following URL:
|
||||
http://sourceforge.net/tracker/index.php?func=detail&aid=1289682&group_id=39687&
|
||||
atid=425939
|
||||
|
||||
After having applied the patch you can run jackd with the following command
|
||||
line:
|
||||
% jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1
|
||||
|
@ -1834,7 +1834,7 @@
|
||||
mychip_set_sample_format(chip, runtime->format);
|
||||
mychip_set_sample_rate(chip, runtime->rate);
|
||||
mychip_set_channels(chip, runtime->channels);
|
||||
mychip_set_dma_setup(chip, runtime->dma_area,
|
||||
mychip_set_dma_setup(chip, runtime->dma_addr,
|
||||
chip->buffer_size,
|
||||
chip->period_size);
|
||||
return 0;
|
||||
@ -3388,7 +3388,7 @@ struct _snd_pcm_runtime {
|
||||
.name = "PCM Playback Switch",
|
||||
.index = 0,
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
|
||||
.private_values = 0xffff,
|
||||
.private_value = 0xffff,
|
||||
.info = my_control_info,
|
||||
.get = my_control_get,
|
||||
.put = my_control_put
|
||||
@ -3449,7 +3449,7 @@ struct _snd_pcm_runtime {
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <structfield>private_values</structfield> field contains
|
||||
The <structfield>private_value</structfield> field contains
|
||||
an arbitrary long integer value for this record. When using
|
||||
generic <structfield>info</structfield>,
|
||||
<structfield>get</structfield> and
|
||||
|
@ -157,14 +157,14 @@ static struct platform_device smc91x_device = {
|
||||
.resource = smc91x_resources,
|
||||
};
|
||||
|
||||
static int mst_audio_startup(snd_pcm_substream_t *substream, void *priv)
|
||||
static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv)
|
||||
{
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mst_audio_shutdown(snd_pcm_substream_t *substream, void *priv)
|
||||
static void mst_audio_shutdown(struct snd_pcm_substream *substream, void *priv)
|
||||
{
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
|
||||
|
@ -63,7 +63,7 @@ struct cx88_audio_dev {
|
||||
/* audio controls */
|
||||
int irq;
|
||||
|
||||
snd_card_t *card;
|
||||
struct snd_card *card;
|
||||
|
||||
spinlock_t reg_lock;
|
||||
|
||||
@ -82,7 +82,7 @@ struct cx88_audio_dev {
|
||||
struct cx88_buffer *buf;
|
||||
|
||||
long opened;
|
||||
snd_pcm_substream_t *substream;
|
||||
struct snd_pcm_substream *substream;
|
||||
|
||||
};
|
||||
typedef struct cx88_audio_dev snd_cx88_card_t;
|
||||
@ -96,7 +96,7 @@ typedef struct cx88_audio_dev snd_cx88_card_t;
|
||||
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
|
||||
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
|
||||
static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
|
||||
static snd_card_t *snd_cx88_cards[SNDRV_CARDS];
|
||||
static struct snd_card *snd_cx88_cards[SNDRV_CARDS];
|
||||
|
||||
module_param_array(enable, bool, NULL, 0444);
|
||||
MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
|
||||
@ -320,7 +320,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip)
|
||||
/*
|
||||
* Digital hardware definition
|
||||
*/
|
||||
static snd_pcm_hardware_t snd_cx88_digital_hw = {
|
||||
static struct snd_pcm_hardware snd_cx88_digital_hw = {
|
||||
.info = SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
@ -342,16 +342,16 @@ static snd_pcm_hardware_t snd_cx88_digital_hw = {
|
||||
/*
|
||||
* audio pcm capture runtime free
|
||||
*/
|
||||
static void snd_card_cx88_runtime_free(snd_pcm_runtime_t *runtime)
|
||||
static void snd_card_cx88_runtime_free(struct snd_pcm_runtime *runtime)
|
||||
{
|
||||
}
|
||||
/*
|
||||
* audio pcm capture open callback
|
||||
*/
|
||||
static int snd_cx88_pcm_open(snd_pcm_substream_t *substream)
|
||||
static int snd_cx88_pcm_open(struct snd_pcm_substream *substream)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
|
||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
int err;
|
||||
|
||||
if (test_and_set_bit(0, &chip->opened))
|
||||
@ -380,7 +380,7 @@ static int snd_cx88_pcm_open(snd_pcm_substream_t *substream)
|
||||
/*
|
||||
* audio close callback
|
||||
*/
|
||||
static int snd_cx88_close(snd_pcm_substream_t *substream)
|
||||
static int snd_cx88_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
|
||||
|
||||
@ -393,8 +393,8 @@ static int snd_cx88_close(snd_pcm_substream_t *substream)
|
||||
/*
|
||||
* hw_params callback
|
||||
*/
|
||||
static int snd_cx88_hw_params(snd_pcm_substream_t * substream,
|
||||
snd_pcm_hw_params_t * hw_params)
|
||||
static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
|
||||
struct snd_pcm_hw_params * hw_params)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
|
||||
struct cx88_buffer *buf;
|
||||
@ -453,7 +453,7 @@ static int snd_cx88_hw_params(snd_pcm_substream_t * substream,
|
||||
/*
|
||||
* hw free callback
|
||||
*/
|
||||
static int snd_cx88_hw_free(snd_pcm_substream_t * substream)
|
||||
static int snd_cx88_hw_free(struct snd_pcm_substream * substream)
|
||||
{
|
||||
|
||||
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
|
||||
@ -469,7 +469,7 @@ static int snd_cx88_hw_free(snd_pcm_substream_t * substream)
|
||||
/*
|
||||
* prepare callback
|
||||
*/
|
||||
static int snd_cx88_prepare(snd_pcm_substream_t *substream)
|
||||
static int snd_cx88_prepare(struct snd_pcm_substream *substream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -478,7 +478,7 @@ static int snd_cx88_prepare(snd_pcm_substream_t *substream)
|
||||
/*
|
||||
* trigger callback
|
||||
*/
|
||||
static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)
|
||||
static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
|
||||
int err;
|
||||
@ -505,10 +505,10 @@ static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd)
|
||||
/*
|
||||
* pointer callback
|
||||
*/
|
||||
static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream)
|
||||
static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
|
||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
|
||||
if (chip->read_count) {
|
||||
chip->read_count -= snd_pcm_lib_period_bytes(substream);
|
||||
@ -525,7 +525,7 @@ static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream)
|
||||
/*
|
||||
* operators
|
||||
*/
|
||||
static snd_pcm_ops_t snd_cx88_pcm_ops = {
|
||||
static struct snd_pcm_ops snd_cx88_pcm_ops = {
|
||||
.open = snd_cx88_pcm_open,
|
||||
.close = snd_cx88_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
@ -542,7 +542,7 @@ static snd_pcm_ops_t snd_cx88_pcm_ops = {
|
||||
static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
|
||||
{
|
||||
int err;
|
||||
snd_pcm_t *pcm;
|
||||
struct snd_pcm *pcm;
|
||||
|
||||
err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
|
||||
if (err < 0)
|
||||
@ -557,7 +557,8 @@ static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
|
||||
/****************************************************************************
|
||||
CONTROL INTERFACE
|
||||
****************************************************************************/
|
||||
static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
|
||||
static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *info)
|
||||
{
|
||||
info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
info->count = 1;
|
||||
@ -568,7 +569,8 @@ static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_i
|
||||
}
|
||||
|
||||
/* OK - TODO: test it */
|
||||
static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
|
||||
static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *value)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
struct cx88_core *core=chip->core;
|
||||
@ -579,7 +581,8 @@ static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_va
|
||||
}
|
||||
|
||||
/* OK - TODO: test it */
|
||||
static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
|
||||
static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *value)
|
||||
{
|
||||
snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
struct cx88_core *core=chip->core;
|
||||
@ -595,7 +598,7 @@ static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_va
|
||||
return v != old_control;
|
||||
}
|
||||
|
||||
static snd_kcontrol_new_t snd_cx88_capture_volume = {
|
||||
static struct snd_kcontrol_new snd_cx88_capture_volume = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Capture Volume",
|
||||
.info = snd_cx88_capture_volume_info,
|
||||
@ -641,7 +644,7 @@ static int snd_cx88_free(snd_cx88_card_t *chip)
|
||||
/*
|
||||
* Component Destructor
|
||||
*/
|
||||
static void snd_cx88_dev_free(snd_card_t * card)
|
||||
static void snd_cx88_dev_free(struct snd_card * card)
|
||||
{
|
||||
snd_cx88_card_t *chip = card->private_data;
|
||||
|
||||
@ -654,8 +657,9 @@ static void snd_cx88_dev_free(snd_card_t * card)
|
||||
*/
|
||||
|
||||
static int devno;
|
||||
static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
|
||||
snd_cx88_card_t **rchip)
|
||||
static int __devinit snd_cx88_create(struct snd_card *card,
|
||||
struct pci_dev *pci,
|
||||
snd_cx88_card_t **rchip)
|
||||
{
|
||||
snd_cx88_card_t *chip;
|
||||
struct cx88_core *core;
|
||||
@ -726,7 +730,7 @@ static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci,
|
||||
static int __devinit cx88_audio_initdev(struct pci_dev *pci,
|
||||
const struct pci_device_id *pci_id)
|
||||
{
|
||||
snd_card_t *card;
|
||||
struct snd_card *card;
|
||||
snd_cx88_card_t *chip;
|
||||
int err;
|
||||
|
||||
|
@ -71,7 +71,7 @@ MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s).");
|
||||
*/
|
||||
|
||||
typedef struct snd_card_saa7134 {
|
||||
snd_card_t *card;
|
||||
struct snd_card *card;
|
||||
spinlock_t mixer_lock;
|
||||
int mixer_volume[MIXER_ADDR_LAST+1][2];
|
||||
int capture_source[MIXER_ADDR_LAST+1][2];
|
||||
@ -95,10 +95,10 @@ typedef struct snd_card_saa7134_pcm {
|
||||
|
||||
spinlock_t lock;
|
||||
|
||||
snd_pcm_substream_t *substream;
|
||||
struct snd_pcm_substream *substream;
|
||||
} snd_card_saa7134_pcm_t;
|
||||
|
||||
static snd_card_t *snd_saa7134_cards[SNDRV_CARDS];
|
||||
static struct snd_card *snd_saa7134_cards[SNDRV_CARDS];
|
||||
|
||||
|
||||
/*
|
||||
@ -251,10 +251,10 @@ static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
|
||||
*
|
||||
*/
|
||||
|
||||
static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
|
||||
static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream,
|
||||
int cmd)
|
||||
{
|
||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_card_saa7134_pcm_t *pcm = runtime->private_data;
|
||||
struct saa7134_dev *dev=pcm->dev;
|
||||
int err = 0;
|
||||
@ -332,9 +332,9 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
|
||||
*
|
||||
*/
|
||||
|
||||
static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
|
||||
static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream)
|
||||
{
|
||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
int bswap, sign;
|
||||
u32 fmt, control;
|
||||
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
|
||||
@ -421,9 +421,10 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
|
||||
*
|
||||
*/
|
||||
|
||||
static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
|
||||
static snd_pcm_uframes_t
|
||||
snd_card_saa7134_capture_pointer(struct snd_pcm_substream * substream)
|
||||
{
|
||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_card_saa7134_pcm_t *pcm = runtime->private_data;
|
||||
struct saa7134_dev *dev=pcm->dev;
|
||||
|
||||
@ -441,7 +442,7 @@ static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t *
|
||||
* ALSA hardware capabilities definition
|
||||
*/
|
||||
|
||||
static snd_pcm_hardware_t snd_card_saa7134_capture =
|
||||
static struct snd_pcm_hardware snd_card_saa7134_capture =
|
||||
{
|
||||
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_BLOCK_TRANSFER |
|
||||
@ -464,7 +465,7 @@ static snd_pcm_hardware_t snd_card_saa7134_capture =
|
||||
.periods_max = 1024,
|
||||
};
|
||||
|
||||
static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
|
||||
static void snd_card_saa7134_runtime_free(struct snd_pcm_runtime *runtime)
|
||||
{
|
||||
snd_card_saa7134_pcm_t *pcm = runtime->private_data;
|
||||
|
||||
@ -481,8 +482,8 @@ static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
|
||||
*
|
||||
*/
|
||||
|
||||
static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
|
||||
snd_pcm_hw_params_t * hw_params)
|
||||
static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
|
||||
struct snd_pcm_hw_params * hw_params)
|
||||
{
|
||||
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
|
||||
struct saa7134_dev *dev;
|
||||
@ -561,7 +562,7 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
|
||||
*
|
||||
*/
|
||||
|
||||
static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
|
||||
static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)
|
||||
{
|
||||
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
|
||||
struct saa7134_dev *dev;
|
||||
@ -587,7 +588,7 @@ static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
|
||||
*
|
||||
*/
|
||||
|
||||
static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
|
||||
static int snd_card_saa7134_capture_close(struct snd_pcm_substream * substream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -602,9 +603,9 @@ static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
|
||||
*
|
||||
*/
|
||||
|
||||
static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
|
||||
static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream)
|
||||
{
|
||||
snd_pcm_runtime_t *runtime = substream->runtime;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_card_saa7134_pcm_t *pcm;
|
||||
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
|
||||
struct saa7134_dev *dev = saa7134->dev;
|
||||
@ -640,7 +641,7 @@ static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
|
||||
* ALSA capture callbacks definition
|
||||
*/
|
||||
|
||||
static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
|
||||
static struct snd_pcm_ops snd_card_saa7134_capture_ops = {
|
||||
.open = snd_card_saa7134_capture_open,
|
||||
.close = snd_card_saa7134_capture_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
@ -661,7 +662,7 @@ static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
|
||||
|
||||
static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
|
||||
{
|
||||
snd_pcm_t *pcm;
|
||||
struct snd_pcm *pcm;
|
||||
int err;
|
||||
|
||||
if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
|
||||
@ -679,7 +680,8 @@ static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
|
||||
.get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
|
||||
.private_value = addr }
|
||||
|
||||
static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
|
||||
static int snd_saa7134_volume_info(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_info * uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->count = 2;
|
||||
@ -688,7 +690,8 @@ static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
|
||||
static int snd_saa7134_volume_get(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_value * ucontrol)
|
||||
{
|
||||
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
int addr = kcontrol->private_value;
|
||||
@ -698,7 +701,8 @@ static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
|
||||
static int snd_saa7134_volume_put(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_value * ucontrol)
|
||||
{
|
||||
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
int change, addr = kcontrol->private_value;
|
||||
@ -729,7 +733,8 @@ static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
|
||||
.get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
|
||||
.private_value = addr }
|
||||
|
||||
static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
|
||||
static int snd_saa7134_capsrc_info(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_info * uinfo)
|
||||
{
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
|
||||
uinfo->count = 2;
|
||||
@ -738,7 +743,8 @@ static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
|
||||
static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_value * ucontrol)
|
||||
{
|
||||
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
int addr = kcontrol->private_value;
|
||||
@ -751,7 +757,8 @@ static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
|
||||
static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol,
|
||||
struct snd_ctl_elem_value * ucontrol)
|
||||
{
|
||||
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
int change, addr = kcontrol->private_value;
|
||||
@ -828,7 +835,7 @@ static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
|
||||
return change;
|
||||
}
|
||||
|
||||
static snd_kcontrol_new_t snd_saa7134_controls[] = {
|
||||
static struct snd_kcontrol_new snd_saa7134_controls[] = {
|
||||
SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
|
||||
SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
|
||||
SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
|
||||
@ -847,7 +854,7 @@ SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
|
||||
|
||||
static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
|
||||
{
|
||||
snd_card_t *card = chip->card;
|
||||
struct snd_card *card = chip->card;
|
||||
unsigned int idx;
|
||||
int err;
|
||||
|
||||
@ -861,7 +868,7 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void snd_saa7134_free(snd_card_t * card)
|
||||
static void snd_saa7134_free(struct snd_card * card)
|
||||
{
|
||||
snd_card_saa7134_t *chip = card->private_data;
|
||||
|
||||
@ -888,7 +895,7 @@ static void snd_saa7134_free(snd_card_t * card)
|
||||
static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
|
||||
{
|
||||
|
||||
snd_card_t *card;
|
||||
struct snd_card *card;
|
||||
snd_card_saa7134_t *chip;
|
||||
int err;
|
||||
|
||||
|
@ -397,7 +397,7 @@ struct saa7134_dmasound {
|
||||
unsigned int read_offset;
|
||||
unsigned int read_count;
|
||||
void * priv_data;
|
||||
snd_pcm_substream_t *substream;
|
||||
struct snd_pcm_substream *substream;
|
||||
};
|
||||
|
||||
/* IR input */
|
||||
|
@ -6,8 +6,8 @@
|
||||
#include <sound/pcm.h>
|
||||
|
||||
typedef struct {
|
||||
int (*startup)(snd_pcm_substream_t *, void *);
|
||||
void (*shutdown)(snd_pcm_substream_t *, void *);
|
||||
int (*startup)(struct snd_pcm_substream *, void *);
|
||||
void (*shutdown)(struct snd_pcm_substream *, void *);
|
||||
void (*suspend)(void *);
|
||||
void (*resume)(void *);
|
||||
void *priv;
|
||||
|
@ -20,6 +20,7 @@ enum dma_data_direction {
|
||||
#define DMA_31BIT_MASK 0x000000007fffffffULL
|
||||
#define DMA_30BIT_MASK 0x000000003fffffffULL
|
||||
#define DMA_29BIT_MASK 0x000000001fffffffULL
|
||||
#define DMA_28BIT_MASK 0x000000000fffffffULL
|
||||
|
||||
#include <asm/dma-mapping.h>
|
||||
|
||||
|
@ -433,6 +433,12 @@ struct snd_ac97_bus {
|
||||
struct snd_info_entry *proc;
|
||||
};
|
||||
|
||||
/* static resolution table */
|
||||
struct snd_ac97_res_table {
|
||||
unsigned short reg; /* register */
|
||||
unsigned short bits; /* resolution bitmask */
|
||||
};
|
||||
|
||||
struct snd_ac97_template {
|
||||
void *private_data;
|
||||
void (*private_free) (struct snd_ac97 *ac97);
|
||||
@ -440,8 +446,7 @@ struct snd_ac97_template {
|
||||
unsigned short num; /* number of codec: 0 = primary, 1 = secondary */
|
||||
unsigned short addr; /* physical address of codec [0-3] */
|
||||
unsigned int scaps; /* driver capabilities */
|
||||
unsigned int limited_regs; /* allow limited registers only */
|
||||
DECLARE_BITMAP(reg_accessed, 0x80); /* bit flags */
|
||||
const struct snd_ac97_res_table *res_table; /* static resolution */
|
||||
};
|
||||
|
||||
struct snd_ac97 {
|
||||
@ -456,20 +461,20 @@ struct snd_ac97 {
|
||||
struct snd_info_entry *proc_regs;
|
||||
unsigned short subsystem_vendor;
|
||||
unsigned short subsystem_device;
|
||||
struct semaphore reg_mutex;
|
||||
struct semaphore page_mutex; /* mutex for AD18xx multi-codecs and paging (2.3) */
|
||||
struct mutex reg_mutex;
|
||||
struct mutex page_mutex; /* mutex for AD18xx multi-codecs and paging (2.3) */
|
||||
unsigned short num; /* number of codec: 0 = primary, 1 = secondary */
|
||||
unsigned short addr; /* physical address of codec [0-3] */
|
||||
unsigned int id; /* identification of codec */
|
||||
unsigned short caps; /* capabilities (register 0) */
|
||||
unsigned short ext_id; /* extended feature identification (register 28) */
|
||||
unsigned short ext_mid; /* extended modem ID (register 3C) */
|
||||
const struct snd_ac97_res_table *res_table; /* static resolution */
|
||||
unsigned int scaps; /* driver capabilities */
|
||||
unsigned int flags; /* specific code */
|
||||
unsigned int rates[6]; /* see AC97_RATES_* defines */
|
||||
unsigned int spdif_status;
|
||||
unsigned short regs[0x80]; /* register cache */
|
||||
unsigned int limited_regs; /* allow limited registers only */
|
||||
DECLARE_BITMAP(reg_accessed, 0x80); /* bit flags */
|
||||
union { /* vendor specific code */
|
||||
struct {
|
||||
|
@ -154,7 +154,7 @@ struct snd_ad1848 {
|
||||
#endif
|
||||
|
||||
spinlock_t reg_lock;
|
||||
struct semaphore open_mutex;
|
||||
struct mutex open_mutex;
|
||||
};
|
||||
|
||||
/* exported functions */
|
||||
|
@ -71,7 +71,7 @@ struct snd_ak4531 {
|
||||
void (*private_free) (struct snd_ak4531 *ak4531);
|
||||
/* --- */
|
||||
unsigned char regs[0x20];
|
||||
struct semaphore reg_mutex;
|
||||
struct mutex reg_mutex;
|
||||
};
|
||||
|
||||
int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531,
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/sched.h> /* wake_up() */
|
||||
#include <asm/semaphore.h> /* struct semaphore */
|
||||
#include <linux/mutex.h> /* struct mutex */
|
||||
#include <linux/rwsem.h> /* struct rw_semaphore */
|
||||
#include <linux/workqueue.h> /* struct workqueue_struct */
|
||||
#include <linux/pm.h> /* pm_message_t */
|
||||
@ -137,7 +137,7 @@ struct snd_card {
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
unsigned int power_state; /* power state */
|
||||
struct semaphore power_lock; /* power lock */
|
||||
struct mutex power_lock; /* power lock */
|
||||
wait_queue_head_t power_sleep;
|
||||
#endif
|
||||
|
||||
@ -150,12 +150,12 @@ struct snd_card {
|
||||
#ifdef CONFIG_PM
|
||||
static inline void snd_power_lock(struct snd_card *card)
|
||||
{
|
||||
down(&card->power_lock);
|
||||
mutex_lock(&card->power_lock);
|
||||
}
|
||||
|
||||
static inline void snd_power_unlock(struct snd_card *card)
|
||||
{
|
||||
up(&card->power_lock);
|
||||
mutex_unlock(&card->power_lock);
|
||||
}
|
||||
|
||||
static inline unsigned int snd_power_get_state(struct snd_card *card)
|
||||
|
@ -248,8 +248,8 @@ struct snd_cs4231 {
|
||||
unsigned int c_dma_size;
|
||||
|
||||
spinlock_t reg_lock;
|
||||
struct semaphore mce_mutex;
|
||||
struct semaphore open_mutex;
|
||||
struct mutex mce_mutex;
|
||||
struct mutex open_mutex;
|
||||
|
||||
int (*rate_constraint) (struct snd_pcm_runtime *runtime);
|
||||
void (*set_playback_format) (struct snd_cs4231 *chip, struct snd_pcm_hw_params *hw_params, unsigned char pdfr);
|
||||
|
@ -1711,7 +1711,7 @@ struct snd_cs46xx {
|
||||
int current_gpio;
|
||||
#endif
|
||||
#ifdef CONFIG_SND_CS46XX_NEW_DSP
|
||||
struct semaphore spos_mutex;
|
||||
struct mutex spos_mutex;
|
||||
|
||||
struct dsp_spos_instance * dsp_spos_instance;
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <sound/pcm-indirect.h>
|
||||
#include <sound/timer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/* ------------------- DEFINES -------------------- */
|
||||
@ -1022,7 +1023,7 @@ struct snd_emu10k1_fx8010 {
|
||||
int gpr_size; /* size of allocated GPR controls */
|
||||
int gpr_count; /* count of used kcontrols */
|
||||
struct list_head gpr_ctl; /* GPR controls */
|
||||
struct semaphore lock;
|
||||
struct mutex lock;
|
||||
struct snd_emu10k1_fx8010_pcm pcm[8];
|
||||
spinlock_t irq_lock;
|
||||
struct snd_emu10k1_fx8010_irq *irq_handlers;
|
||||
@ -1122,7 +1123,6 @@ struct snd_emu10k1 {
|
||||
spinlock_t reg_lock;
|
||||
spinlock_t emu_lock;
|
||||
spinlock_t voice_lock;
|
||||
struct semaphore ptb_lock;
|
||||
|
||||
struct snd_emu10k1_voice voices[NUM_G];
|
||||
struct snd_emu10k1_voice p16v_voices[4];
|
||||
|
@ -113,7 +113,7 @@ struct snd_emux {
|
||||
struct snd_emux_voice *voices; /* Voices (EMU 'channel') */
|
||||
int use_time; /* allocation counter */
|
||||
spinlock_t voice_lock; /* Lock for voice access */
|
||||
struct semaphore register_mutex;
|
||||
struct mutex register_mutex;
|
||||
int client; /* For the sequencer client */
|
||||
int ports[SNDRV_EMUX_MAX_PORTS]; /* The ports for this device */
|
||||
struct snd_emux_port *portptrs[SNDRV_EMUX_MAX_PORTS];
|
||||
|
@ -209,7 +209,7 @@ struct snd_gf1_mem {
|
||||
struct snd_gf1_bank_info banks_16[4];
|
||||
struct snd_gf1_mem_block *first;
|
||||
struct snd_gf1_mem_block *last;
|
||||
struct semaphore memory_mutex;
|
||||
struct mutex memory_mutex;
|
||||
};
|
||||
|
||||
struct snd_gf1_dma_block {
|
||||
@ -467,8 +467,8 @@ struct snd_gus_card {
|
||||
spinlock_t dma_lock;
|
||||
spinlock_t pcm_volume_level_lock;
|
||||
spinlock_t uart_cmd_lock;
|
||||
struct semaphore dma_mutex;
|
||||
struct semaphore register_mutex;
|
||||
struct mutex dma_mutex;
|
||||
struct mutex register_mutex;
|
||||
};
|
||||
|
||||
/* I/O functions for GF1/InterWave chip - gus_io.c */
|
||||
|
@ -60,7 +60,7 @@ struct snd_hwdep {
|
||||
void *private_data;
|
||||
void (*private_free) (struct snd_hwdep *hwdep);
|
||||
|
||||
struct semaphore open_mutex;
|
||||
struct mutex open_mutex;
|
||||
int used;
|
||||
unsigned int dsp_loaded;
|
||||
unsigned int exclusive: 1;
|
||||
|
@ -55,7 +55,7 @@ struct snd_i2c_bus {
|
||||
struct snd_card *card; /* card which I2C belongs to */
|
||||
char name[32]; /* some useful label */
|
||||
|
||||
struct semaphore lock_mutex;
|
||||
struct mutex lock_mutex;
|
||||
|
||||
struct snd_i2c_bus *master; /* master bus when SCK/SCL is shared */
|
||||
struct list_head buses; /* master: slave buses sharing SCK/SCL, slave: link list */
|
||||
@ -84,17 +84,17 @@ int snd_i2c_device_free(struct snd_i2c_device *device);
|
||||
static inline void snd_i2c_lock(struct snd_i2c_bus *bus)
|
||||
{
|
||||
if (bus->master)
|
||||
down(&bus->master->lock_mutex);
|
||||
mutex_lock(&bus->master->lock_mutex);
|
||||
else
|
||||
down(&bus->lock_mutex);
|
||||
mutex_lock(&bus->lock_mutex);
|
||||
}
|
||||
|
||||
static inline void snd_i2c_unlock(struct snd_i2c_bus *bus)
|
||||
{
|
||||
if (bus->master)
|
||||
up(&bus->master->lock_mutex);
|
||||
mutex_unlock(&bus->master->lock_mutex);
|
||||
else
|
||||
up(&bus->lock_mutex);
|
||||
mutex_unlock(&bus->lock_mutex);
|
||||
}
|
||||
|
||||
int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count);
|
||||
|
@ -84,7 +84,7 @@ struct snd_info_entry {
|
||||
void *private_data;
|
||||
void (*private_free)(struct snd_info_entry *entry);
|
||||
struct proc_dir_entry *p;
|
||||
struct semaphore access;
|
||||
struct mutex access;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
|
||||
|
@ -61,7 +61,7 @@ struct snd_mixer_oss {
|
||||
unsigned int active_index);
|
||||
void *private_data_recsrc;
|
||||
void (*private_free_recsrc)(struct snd_mixer_oss *mixer);
|
||||
struct semaphore reg_mutex;
|
||||
struct mutex reg_mutex;
|
||||
struct snd_info_entry *proc_entry;
|
||||
int oss_dev_alloc;
|
||||
/* --- */
|
||||
|
@ -53,6 +53,7 @@
|
||||
|
||||
#include "driver.h"
|
||||
#include <linux/time.h>
|
||||
#include <linux/mutex.h>
|
||||
#include "core.h"
|
||||
#include "hwdep.h"
|
||||
#include "timer.h"
|
||||
@ -312,7 +313,7 @@ struct snd_opl3 {
|
||||
int sys_timer_status; /* system timer run status */
|
||||
spinlock_t sys_timer_lock; /* Lock for system timer access */
|
||||
#endif
|
||||
struct semaphore access_mutex; /* locking */
|
||||
struct mutex access_mutex; /* locking */
|
||||
};
|
||||
|
||||
/* opl3.c */
|
||||
|
@ -420,7 +420,7 @@ struct snd_pcm {
|
||||
char id[64];
|
||||
char name[80];
|
||||
struct snd_pcm_str streams[2];
|
||||
struct semaphore open_mutex;
|
||||
struct mutex open_mutex;
|
||||
wait_queue_head_t open_wait;
|
||||
void *private_data;
|
||||
void (*private_free) (struct snd_pcm *pcm);
|
||||
|
@ -56,8 +56,10 @@ struct snd_pcm_oss_runtime {
|
||||
size_t mmap_bytes;
|
||||
char *buffer; /* vmallocated period */
|
||||
size_t buffer_used; /* used length from period buffer */
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
struct snd_pcm_plugin *plugin_first;
|
||||
struct snd_pcm_plugin *plugin_last;
|
||||
#endif
|
||||
unsigned int prev_hw_ptr_interrupt;
|
||||
};
|
||||
|
||||
@ -73,7 +75,7 @@ struct snd_pcm_oss_substream {
|
||||
|
||||
struct snd_pcm_oss_stream {
|
||||
struct snd_pcm_oss_setup *setup_list; /* setup list */
|
||||
struct semaphore setup_mutex;
|
||||
struct mutex setup_mutex;
|
||||
struct snd_info_entry *proc_entry;
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/wait.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
|
||||
#include "seq_device.h"
|
||||
@ -130,7 +130,7 @@ struct snd_rawmidi {
|
||||
void *private_data;
|
||||
void (*private_free) (struct snd_rawmidi *rmidi);
|
||||
|
||||
struct semaphore open_mutex;
|
||||
struct mutex open_mutex;
|
||||
wait_queue_head_t open_wait;
|
||||
|
||||
struct snd_info_entry *dev;
|
||||
|
@ -158,7 +158,7 @@ struct snd_sb_csp {
|
||||
struct snd_kcontrol *qsound_switch;
|
||||
struct snd_kcontrol *qsound_space;
|
||||
|
||||
struct semaphore access_mutex; /* locking */
|
||||
struct mutex access_mutex; /* locking */
|
||||
};
|
||||
|
||||
int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep);
|
||||
|
@ -64,7 +64,7 @@ struct snd_seq_kinstr_list {
|
||||
|
||||
spinlock_t lock;
|
||||
spinlock_t ops_lock;
|
||||
struct semaphore ops_mutex;
|
||||
struct mutex ops_mutex;
|
||||
unsigned long ops_flags;
|
||||
};
|
||||
|
||||
|
@ -93,7 +93,7 @@ struct snd_sf_list {
|
||||
int sample_locked; /* locked time for sample */
|
||||
struct snd_sf_callback callback; /* callback functions */
|
||||
int presets_locked;
|
||||
struct semaphore presets_mutex;
|
||||
struct mutex presets_mutex;
|
||||
spinlock_t lock;
|
||||
struct snd_util_memhdr *memhdr;
|
||||
};
|
||||
|
@ -1,5 +1,7 @@
|
||||
#ifndef __SOUND_UTIL_MEM_H
|
||||
#define __SOUND_UTIL_MEM_H
|
||||
|
||||
#include <linux/mutex.h>
|
||||
/*
|
||||
* Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
|
||||
*
|
||||
@ -40,7 +42,7 @@ struct snd_util_memhdr {
|
||||
int nblocks; /* # of allocated blocks */
|
||||
unsigned int used; /* used memory size */
|
||||
int block_extra_size; /* extra data size of chunk */
|
||||
struct semaphore block_mutex; /* lock */
|
||||
struct mutex block_mutex; /* lock */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1,3 +1,3 @@
|
||||
/* include/version.h. Generated by configure. */
|
||||
#define CONFIG_SND_VERSION "1.0.11rc2"
|
||||
#define CONFIG_SND_DATE " (Wed Jan 04 08:57:20 2006 UTC)"
|
||||
#define CONFIG_SND_VERSION "1.0.11rc4"
|
||||
#define CONFIG_SND_DATE " (Wed Mar 22 10:27:24 2006 UTC)"
|
||||
|
@ -206,7 +206,7 @@ struct vx_core {
|
||||
int audio_monitor[4]; /* playback hw-monitor level */
|
||||
unsigned char audio_monitor_active[4]; /* playback hw-monitor mute/unmute */
|
||||
|
||||
struct semaphore mixer_mutex;
|
||||
struct mutex mixer_mutex;
|
||||
|
||||
const struct firmware *firmware[4]; /* loaded firmware data */
|
||||
};
|
||||
|
@ -269,9 +269,10 @@ struct snd_ymfpci_pcm {
|
||||
enum snd_ymfpci_pcm_type type;
|
||||
struct snd_pcm_substream *substream;
|
||||
struct snd_ymfpci_voice *voices[2]; /* playback only */
|
||||
unsigned int running: 1;
|
||||
unsigned int output_front: 1;
|
||||
unsigned int output_rear: 1;
|
||||
unsigned int running: 1,
|
||||
output_front: 1,
|
||||
output_rear: 1,
|
||||
swap_rear: 1;
|
||||
unsigned int update_pcm_vol;
|
||||
u32 period_size; /* cached from runtime->period_size */
|
||||
u32 buffer_size; /* cached from runtime->buffer_size */
|
||||
@ -344,6 +345,7 @@ struct snd_ymfpci {
|
||||
struct snd_kcontrol *spdif_pcm_ctl;
|
||||
int mode_dup4ch;
|
||||
int rear_opened;
|
||||
int rear_swap;
|
||||
int spdif_opened;
|
||||
struct {
|
||||
u16 left;
|
||||
@ -376,7 +378,7 @@ int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
|
||||
int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
|
||||
int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
|
||||
int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
|
||||
int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch);
|
||||
int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch, int rear_swap);
|
||||
int snd_ymfpci_timer(struct snd_ymfpci *chip, int device);
|
||||
|
||||
#endif /* __SOUND_YMFPCI_H */
|
||||
|
@ -73,7 +73,7 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned
|
||||
if (ac97->num >= 4)
|
||||
return;
|
||||
|
||||
down(&aaci->ac97_sem);
|
||||
mutex_lock(&aaci->ac97_sem);
|
||||
|
||||
aaci_ac97_select_codec(aaci, ac97);
|
||||
|
||||
@ -91,7 +91,7 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned
|
||||
v = readl(aaci->base + AACI_SLFR);
|
||||
} while (v & (SLFR_1TXB|SLFR_2TXB));
|
||||
|
||||
up(&aaci->ac97_sem);
|
||||
mutex_unlock(&aaci->ac97_sem);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -105,7 +105,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
|
||||
if (ac97->num >= 4)
|
||||
return ~0;
|
||||
|
||||
down(&aaci->ac97_sem);
|
||||
mutex_lock(&aaci->ac97_sem);
|
||||
|
||||
aaci_ac97_select_codec(aaci, ac97);
|
||||
|
||||
@ -145,7 +145,7 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
|
||||
v = ~0;
|
||||
}
|
||||
|
||||
up(&aaci->ac97_sem);
|
||||
mutex_unlock(&aaci->ac97_sem);
|
||||
return v;
|
||||
}
|
||||
|
||||
@ -783,7 +783,7 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev)
|
||||
card->shortname, dev->res.start, dev->irq[0]);
|
||||
|
||||
aaci = card->private_data;
|
||||
init_MUTEX(&aaci->ac97_sem);
|
||||
mutex_init(&aaci->ac97_sem);
|
||||
spin_lock_init(&aaci->lock);
|
||||
aaci->card = card;
|
||||
aaci->dev = dev;
|
||||
|
@ -227,7 +227,7 @@ struct aaci {
|
||||
unsigned int fifosize;
|
||||
|
||||
/* AC'97 */
|
||||
struct semaphore ac97_sem;
|
||||
struct mutex ac97_sem;
|
||||
ac97_bus_t *ac97_bus;
|
||||
|
||||
u32 maincr;
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <sound/initval.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
#include <asm/arch/audio.h>
|
||||
@ -33,7 +33,7 @@
|
||||
#include "pxa2xx-pcm.h"
|
||||
|
||||
|
||||
static DECLARE_MUTEX(car_mutex);
|
||||
static DEFINE_MUTEX(car_mutex);
|
||||
static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
|
||||
static volatile long gsr_bits;
|
||||
|
||||
@ -52,7 +52,7 @@ static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg
|
||||
unsigned short val = -1;
|
||||
volatile u32 *reg_addr;
|
||||
|
||||
down(&car_mutex);
|
||||
mutex_lock(&car_mutex);
|
||||
|
||||
/* set up primary or secondary codec space */
|
||||
reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
|
||||
@ -79,7 +79,7 @@ static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg
|
||||
/* but we've just started another cycle... */
|
||||
wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
|
||||
|
||||
out: up(&car_mutex);
|
||||
out: mutex_unlock(&car_mutex);
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigne
|
||||
{
|
||||
volatile u32 *reg_addr;
|
||||
|
||||
down(&car_mutex);
|
||||
mutex_lock(&car_mutex);
|
||||
|
||||
/* set up primary or secondary codec space */
|
||||
reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
|
||||
@ -101,7 +101,7 @@ static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigne
|
||||
printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
|
||||
__FUNCTION__, reg, GSR | gsr_bits);
|
||||
|
||||
up(&car_mutex);
|
||||
mutex_unlock(&car_mutex);
|
||||
}
|
||||
|
||||
static void pxa2xx_ac97_reset(struct snd_ac97 *ac97)
|
||||
|
@ -73,6 +73,15 @@ config SND_PCM_OSS
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called snd-pcm-oss.
|
||||
|
||||
config SND_PCM_OSS_PLUGINS
|
||||
bool "OSS PCM (digital audio) API - Include plugin system"
|
||||
depends on SND_PCM_OSS
|
||||
default y
|
||||
help
|
||||
If you disable this option, the ALSA's OSS PCM API will not
|
||||
support conversion of channels, formats and rates. It will
|
||||
behave like most of new OSS/Free drivers in 2.4/2.6 kernels.
|
||||
|
||||
config SND_SEQUENCER_OSS
|
||||
bool "OSS Sequencer API"
|
||||
depends on SND && SND_SEQUENCER
|
||||
@ -130,6 +139,15 @@ config SND_SUPPORT_OLD_API
|
||||
Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3
|
||||
or older).
|
||||
|
||||
config SND_VERBOSE_PROCFS
|
||||
bool "Verbose procfs contents"
|
||||
depends on SND
|
||||
default y
|
||||
help
|
||||
Say Y here to include code for verbose procfs contents (provides
|
||||
usefull information to developers when a problem occurs). On the
|
||||
other side, it makes the ALSA subsystem larger.
|
||||
|
||||
config SND_VERBOSE_PRINTK
|
||||
bool "Verbose printk"
|
||||
depends on SND
|
||||
|
@ -309,28 +309,29 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
||||
{
|
||||
struct snd_ctl_elem_id id;
|
||||
unsigned int idx;
|
||||
int err = -EINVAL;
|
||||
|
||||
snd_assert(card != NULL, return -EINVAL);
|
||||
if (! kcontrol)
|
||||
return -EINVAL;
|
||||
snd_assert(kcontrol->info != NULL, return -EINVAL);
|
||||
return err;
|
||||
snd_assert(card != NULL, goto error);
|
||||
snd_assert(kcontrol->info != NULL, goto error);
|
||||
id = kcontrol->id;
|
||||
down_write(&card->controls_rwsem);
|
||||
if (snd_ctl_find_id(card, &id)) {
|
||||
up_write(&card->controls_rwsem);
|
||||
snd_ctl_free_one(kcontrol);
|
||||
snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n",
|
||||
id.iface,
|
||||
id.device,
|
||||
id.subdevice,
|
||||
id.name,
|
||||
id.index);
|
||||
return -EBUSY;
|
||||
err = -EBUSY;
|
||||
goto error;
|
||||
}
|
||||
if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
|
||||
up_write(&card->controls_rwsem);
|
||||
snd_ctl_free_one(kcontrol);
|
||||
return -ENOMEM;
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
list_add_tail(&kcontrol->list, &card->controls);
|
||||
card->controls_count += kcontrol->count;
|
||||
@ -340,6 +341,10 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
||||
for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
snd_ctl_free_one(kcontrol);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -658,7 +663,11 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
|
||||
|
||||
if (copy_from_user(&info, _info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
result = snd_ctl_elem_info(ctl, &info);
|
||||
snd_power_lock(ctl->card);
|
||||
result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL);
|
||||
if (result >= 0)
|
||||
result = snd_ctl_elem_info(ctl, &info);
|
||||
snd_power_unlock(ctl->card);
|
||||
if (result >= 0)
|
||||
if (copy_to_user(_info, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
@ -708,7 +717,11 @@ static int snd_ctl_elem_read_user(struct snd_card *card,
|
||||
kfree(control);
|
||||
return -EFAULT;
|
||||
}
|
||||
result = snd_ctl_elem_read(card, control);
|
||||
snd_power_lock(card);
|
||||
result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
|
||||
if (result >= 0)
|
||||
result = snd_ctl_elem_read(card, control);
|
||||
snd_power_unlock(card);
|
||||
if (result >= 0)
|
||||
if (copy_to_user(_control, control, sizeof(*control)))
|
||||
result = -EFAULT;
|
||||
@ -758,6 +771,7 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
|
||||
struct snd_ctl_elem_value __user *_control)
|
||||
{
|
||||
struct snd_ctl_elem_value *control;
|
||||
struct snd_card *card;
|
||||
int result;
|
||||
|
||||
control = kmalloc(sizeof(*control), GFP_KERNEL);
|
||||
@ -767,7 +781,12 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
|
||||
kfree(control);
|
||||
return -EFAULT;
|
||||
}
|
||||
result = snd_ctl_elem_write(file->card, file, control);
|
||||
card = file->card;
|
||||
snd_power_lock(card);
|
||||
result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
|
||||
if (result >= 0)
|
||||
result = snd_ctl_elem_write(card, file, control);
|
||||
snd_power_unlock(card);
|
||||
if (result >= 0)
|
||||
if (copy_to_user(_control, control, sizeof(*control)))
|
||||
result = -EFAULT;
|
||||
|
@ -107,7 +107,13 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
|
||||
*/
|
||||
if (get_user(data->value.enumerated.item, &data32->value.enumerated.item))
|
||||
goto error;
|
||||
err = snd_ctl_elem_info(ctl, data);
|
||||
|
||||
snd_power_lock(ctl->card);
|
||||
err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL);
|
||||
if (err >= 0)
|
||||
err = snd_ctl_elem_info(ctl, data);
|
||||
snd_power_unlock(ctl->card);
|
||||
|
||||
if (err < 0)
|
||||
goto error;
|
||||
/* restore info to 32bit */
|
||||
@ -286,9 +292,14 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card,
|
||||
|
||||
if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
|
||||
goto error;
|
||||
if ((err = snd_ctl_elem_read(card, data)) < 0)
|
||||
goto error;
|
||||
err = copy_ctl_value_to_user(data32, data, type, count);
|
||||
|
||||
snd_power_lock(card);
|
||||
err = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
|
||||
if (err >= 0)
|
||||
err = snd_ctl_elem_read(card, data);
|
||||
snd_power_unlock(card);
|
||||
if (err >= 0)
|
||||
err = copy_ctl_value_to_user(data32, data, type, count);
|
||||
error:
|
||||
kfree(data);
|
||||
return err;
|
||||
@ -298,17 +309,23 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
|
||||
struct snd_ctl_elem_value32 __user *data32)
|
||||
{
|
||||
struct snd_ctl_elem_value *data;
|
||||
struct snd_card *card = file->card;
|
||||
int err, type, count;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
if ((err = copy_ctl_value_from_user(file->card, data, data32, &type, &count)) < 0)
|
||||
if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
|
||||
goto error;
|
||||
if ((err = snd_ctl_elem_write(file->card, file, data)) < 0)
|
||||
goto error;
|
||||
err = copy_ctl_value_to_user(data32, data, type, count);
|
||||
|
||||
snd_power_lock(card);
|
||||
err = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL);
|
||||
if (err >= 0)
|
||||
err = snd_ctl_elem_write(card, file, data);
|
||||
snd_power_unlock(card);
|
||||
if (err >= 0)
|
||||
err = copy_ctl_value_to_user(data32, data, type, count);
|
||||
error:
|
||||
kfree(data);
|
||||
return err;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/control.h>
|
||||
#include <sound/minors.h>
|
||||
@ -36,7 +37,7 @@ MODULE_DESCRIPTION("Hardware dependent layer");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static LIST_HEAD(snd_hwdep_devices);
|
||||
static DECLARE_MUTEX(register_mutex);
|
||||
static DEFINE_MUTEX(register_mutex);
|
||||
|
||||
static int snd_hwdep_free(struct snd_hwdep *hwdep);
|
||||
static int snd_hwdep_dev_free(struct snd_device *device);
|
||||
@ -111,7 +112,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
|
||||
|
||||
init_waitqueue_entry(&wait, current);
|
||||
add_wait_queue(&hw->open_wait, &wait);
|
||||
down(&hw->open_mutex);
|
||||
mutex_lock(&hw->open_mutex);
|
||||
while (1) {
|
||||
if (hw->exclusive && hw->used > 0) {
|
||||
err = -EBUSY;
|
||||
@ -128,9 +129,9 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
|
||||
} else
|
||||
break;
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
up(&hw->open_mutex);
|
||||
mutex_unlock(&hw->open_mutex);
|
||||
schedule();
|
||||
down(&hw->open_mutex);
|
||||
mutex_lock(&hw->open_mutex);
|
||||
if (signal_pending(current)) {
|
||||
err = -ERESTARTSYS;
|
||||
break;
|
||||
@ -147,7 +148,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
|
||||
hw->ops.release(hw, file);
|
||||
}
|
||||
}
|
||||
up(&hw->open_mutex);
|
||||
mutex_unlock(&hw->open_mutex);
|
||||
if (err < 0)
|
||||
module_put(hw->card->module);
|
||||
return err;
|
||||
@ -157,7 +158,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file)
|
||||
{
|
||||
int err = -ENXIO;
|
||||
struct snd_hwdep *hw = file->private_data;
|
||||
down(&hw->open_mutex);
|
||||
mutex_lock(&hw->open_mutex);
|
||||
if (hw->ops.release) {
|
||||
err = hw->ops.release(hw, file);
|
||||
wake_up(&hw->open_wait);
|
||||
@ -165,7 +166,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file)
|
||||
if (hw->used > 0)
|
||||
hw->used--;
|
||||
snd_card_file_remove(hw->card, file);
|
||||
up(&hw->open_mutex);
|
||||
mutex_unlock(&hw->open_mutex);
|
||||
module_put(hw->card->module);
|
||||
return err;
|
||||
}
|
||||
@ -272,7 +273,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
|
||||
|
||||
if (get_user(device, (int __user *)arg))
|
||||
return -EFAULT;
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
device = device < 0 ? 0 : device + 1;
|
||||
while (device < SNDRV_MINOR_HWDEPS) {
|
||||
if (snd_hwdep_search(card, device))
|
||||
@ -281,7 +282,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
|
||||
}
|
||||
if (device >= SNDRV_MINOR_HWDEPS)
|
||||
device = -1;
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (put_user(device, (int __user *)arg))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
@ -294,13 +295,13 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
|
||||
|
||||
if (get_user(device, &info->device))
|
||||
return -EFAULT;
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
hwdep = snd_hwdep_search(card, device);
|
||||
if (hwdep)
|
||||
err = snd_hwdep_info(hwdep, info);
|
||||
else
|
||||
err = -ENXIO;
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@ -375,7 +376,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
|
||||
return err;
|
||||
}
|
||||
init_waitqueue_head(&hwdep->open_wait);
|
||||
init_MUTEX(&hwdep->open_mutex);
|
||||
mutex_init(&hwdep->open_mutex);
|
||||
*rhwdep = hwdep;
|
||||
return 0;
|
||||
}
|
||||
@ -401,9 +402,9 @@ static int snd_hwdep_dev_register(struct snd_device *device)
|
||||
int err;
|
||||
char name[32];
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
if (snd_hwdep_search(hwdep->card, hwdep->device)) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
list_add_tail(&hwdep->list, &snd_hwdep_devices);
|
||||
@ -414,7 +415,7 @@ static int snd_hwdep_dev_register(struct snd_device *device)
|
||||
snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n",
|
||||
hwdep->card->number, hwdep->device);
|
||||
list_del(&hwdep->list);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
}
|
||||
#ifdef CONFIG_SND_OSSEMUL
|
||||
@ -434,7 +435,7 @@ static int snd_hwdep_dev_register(struct snd_device *device)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -443,9 +444,9 @@ static int snd_hwdep_dev_unregister(struct snd_device *device)
|
||||
struct snd_hwdep *hwdep = device->device_data;
|
||||
|
||||
snd_assert(hwdep != NULL, return -ENXIO);
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
#ifdef CONFIG_SND_OSSEMUL
|
||||
@ -454,7 +455,7 @@ static int snd_hwdep_dev_unregister(struct snd_device *device)
|
||||
#endif
|
||||
snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device);
|
||||
list_del(&hwdep->list);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return snd_hwdep_free(hwdep);
|
||||
}
|
||||
|
||||
@ -469,13 +470,13 @@ static void snd_hwdep_proc_read(struct snd_info_entry *entry,
|
||||
struct list_head *p;
|
||||
struct snd_hwdep *hwdep;
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
list_for_each(p, &snd_hwdep_devices) {
|
||||
hwdep = list_entry(p, struct snd_hwdep, list);
|
||||
snd_iprintf(buffer, "%02i-%02i: %s\n",
|
||||
hwdep->card->number, hwdep->device, hwdep->name);
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
}
|
||||
|
||||
static struct snd_info_entry *snd_hwdep_proc_entry;
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <sound/version.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/devfs_fs_kernel.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/*
|
||||
@ -68,7 +69,7 @@ int snd_info_check_reserved_words(const char *str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static DECLARE_MUTEX(info_mutex);
|
||||
static DEFINE_MUTEX(info_mutex);
|
||||
|
||||
struct snd_info_private_data {
|
||||
struct snd_info_buffer *rbuffer;
|
||||
@ -265,11 +266,11 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
|
||||
struct proc_dir_entry *p;
|
||||
int mode, err;
|
||||
|
||||
down(&info_mutex);
|
||||
mutex_lock(&info_mutex);
|
||||
p = PDE(inode);
|
||||
entry = p == NULL ? NULL : (struct snd_info_entry *)p->data;
|
||||
if (entry == NULL || entry->disconnected) {
|
||||
up(&info_mutex);
|
||||
mutex_unlock(&info_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!try_module_get(entry->module)) {
|
||||
@ -361,13 +362,13 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
|
||||
break;
|
||||
}
|
||||
file->private_data = data;
|
||||
up(&info_mutex);
|
||||
mutex_unlock(&info_mutex);
|
||||
if (entry->content == SNDRV_INFO_CONTENT_TEXT &&
|
||||
(mode == O_RDONLY || mode == O_RDWR)) {
|
||||
if (entry->c.text.read) {
|
||||
down(&entry->access);
|
||||
mutex_lock(&entry->access);
|
||||
entry->c.text.read(entry, data->rbuffer);
|
||||
up(&entry->access);
|
||||
mutex_unlock(&entry->access);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -375,7 +376,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
|
||||
__error:
|
||||
module_put(entry->module);
|
||||
__error1:
|
||||
up(&info_mutex);
|
||||
mutex_unlock(&info_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -747,7 +748,7 @@ static struct snd_info_entry *snd_info_create_entry(const char *name)
|
||||
}
|
||||
entry->mode = S_IFREG | S_IRUGO;
|
||||
entry->content = SNDRV_INFO_CONTENT_TEXT;
|
||||
init_MUTEX(&entry->access);
|
||||
mutex_init(&entry->access);
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -896,10 +897,10 @@ int snd_info_register(struct snd_info_entry * entry)
|
||||
|
||||
snd_assert(entry != NULL, return -ENXIO);
|
||||
root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
|
||||
down(&info_mutex);
|
||||
mutex_lock(&info_mutex);
|
||||
p = snd_create_proc_entry(entry->name, entry->mode, root);
|
||||
if (!p) {
|
||||
up(&info_mutex);
|
||||
mutex_unlock(&info_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
p->owner = entry->module;
|
||||
@ -908,7 +909,7 @@ int snd_info_register(struct snd_info_entry * entry)
|
||||
p->size = entry->size;
|
||||
p->data = entry;
|
||||
entry->p = p;
|
||||
up(&info_mutex);
|
||||
mutex_unlock(&info_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -929,9 +930,9 @@ int snd_info_unregister(struct snd_info_entry * entry)
|
||||
snd_assert(entry->p != NULL, return -ENXIO);
|
||||
root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
|
||||
snd_assert(root, return -ENXIO);
|
||||
down(&info_mutex);
|
||||
mutex_lock(&info_mutex);
|
||||
snd_remove_proc_entry(root, entry->p);
|
||||
up(&info_mutex);
|
||||
mutex_unlock(&info_mutex);
|
||||
snd_info_free_entry(entry);
|
||||
return 0;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <sound/info.h>
|
||||
#include <sound/version.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
|
||||
|
||||
@ -35,7 +36,7 @@
|
||||
* OSS compatible part
|
||||
*/
|
||||
|
||||
static DECLARE_MUTEX(strings);
|
||||
static DEFINE_MUTEX(strings);
|
||||
static char *snd_sndstat_strings[SNDRV_CARDS][SNDRV_OSS_INFO_DEV_COUNT];
|
||||
static struct snd_info_entry *snd_sndstat_proc_entry;
|
||||
|
||||
@ -45,7 +46,7 @@ int snd_oss_info_register(int dev, int num, char *string)
|
||||
|
||||
snd_assert(dev >= 0 && dev < SNDRV_OSS_INFO_DEV_COUNT, return -ENXIO);
|
||||
snd_assert(num >= 0 && num < SNDRV_CARDS, return -ENXIO);
|
||||
down(&strings);
|
||||
mutex_lock(&strings);
|
||||
if (string == NULL) {
|
||||
if ((x = snd_sndstat_strings[num][dev]) != NULL) {
|
||||
kfree(x);
|
||||
@ -54,12 +55,12 @@ int snd_oss_info_register(int dev, int num, char *string)
|
||||
} else {
|
||||
x = kstrdup(string, GFP_KERNEL);
|
||||
if (x == NULL) {
|
||||
up(&strings);
|
||||
mutex_unlock(&strings);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
snd_sndstat_strings[num][dev] = x;
|
||||
up(&strings);
|
||||
mutex_unlock(&strings);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -71,7 +72,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d
|
||||
char *str;
|
||||
|
||||
snd_iprintf(buf, "\n%s:", id);
|
||||
down(&strings);
|
||||
mutex_lock(&strings);
|
||||
for (idx = 0; idx < SNDRV_CARDS; idx++) {
|
||||
str = snd_sndstat_strings[idx][dev];
|
||||
if (str) {
|
||||
@ -82,7 +83,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d
|
||||
snd_iprintf(buf, "%i: %s\n", idx, str);
|
||||
}
|
||||
}
|
||||
up(&strings);
|
||||
mutex_unlock(&strings);
|
||||
if (ok < 0)
|
||||
snd_iprintf(buf, " NOT ENABLED IN CONFIG\n");
|
||||
return ok;
|
||||
|
@ -145,7 +145,7 @@ struct snd_card *snd_card_new(int idx, const char *xid,
|
||||
init_waitqueue_head(&card->shutdown_sleep);
|
||||
INIT_WORK(&card->free_workq, snd_card_free_thread, card);
|
||||
#ifdef CONFIG_PM
|
||||
init_MUTEX(&card->power_lock);
|
||||
mutex_init(&card->power_lock);
|
||||
init_waitqueue_head(&card->power_sleep);
|
||||
#endif
|
||||
/* the control interface cannot be accessed from the user space until */
|
||||
@ -169,11 +169,44 @@ struct snd_card *snd_card_new(int idx, const char *xid,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static ssize_t snd_disconnect_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *offset)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static ssize_t snd_disconnect_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *offset)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait)
|
||||
{
|
||||
return POLLERR | POLLNVAL;
|
||||
}
|
||||
|
||||
static long snd_disconnect_ioctl(struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int snd_disconnect_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int snd_disconnect_fasync(int fd, struct file *file, int on)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_card_disconnect - disconnect all APIs from the file-operations (user space)
|
||||
* @card: soundcard structure
|
||||
@ -224,7 +257,16 @@ int snd_card_disconnect(struct snd_card *card)
|
||||
memset(f_ops, 0, sizeof(*f_ops));
|
||||
f_ops->owner = file->f_op->owner;
|
||||
f_ops->release = file->f_op->release;
|
||||
f_ops->llseek = snd_disconnect_llseek;
|
||||
f_ops->read = snd_disconnect_read;
|
||||
f_ops->write = snd_disconnect_write;
|
||||
f_ops->poll = snd_disconnect_poll;
|
||||
f_ops->unlocked_ioctl = snd_disconnect_ioctl;
|
||||
#ifdef CONFIG_COMPAT
|
||||
f_ops->compat_ioctl = snd_disconnect_ioctl;
|
||||
#endif
|
||||
f_ops->mmap = snd_disconnect_mmap;
|
||||
f_ops->fasync = snd_disconnect_fasync;
|
||||
|
||||
s_f_ops->next = card->s_f_ops;
|
||||
card->s_f_ops = s_f_ops;
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <sound/memalloc.h>
|
||||
#ifdef CONFIG_SBUS
|
||||
#include <asm/sbus.h>
|
||||
@ -54,7 +54,7 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab);
|
||||
/*
|
||||
*/
|
||||
|
||||
static DECLARE_MUTEX(list_mutex);
|
||||
static DEFINE_MUTEX(list_mutex);
|
||||
static LIST_HEAD(mem_list_head);
|
||||
|
||||
/* buffer preservation list */
|
||||
@ -83,7 +83,7 @@ struct snd_mem_list {
|
||||
* Hacks
|
||||
*/
|
||||
|
||||
#if defined(__i386__) || defined(__ppc__) || defined(__x86_64__)
|
||||
#if defined(__i386__)
|
||||
/*
|
||||
* A hack to allocate large buffers via dma_alloc_coherent()
|
||||
*
|
||||
@ -141,10 +141,6 @@ static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size,
|
||||
|
||||
#endif /* arch */
|
||||
|
||||
#if ! defined(__arm__)
|
||||
#define NEED_RESERVE_PAGES
|
||||
#endif
|
||||
|
||||
/*
|
||||
*
|
||||
* Generic memory allocators
|
||||
@ -163,20 +159,6 @@ static inline void dec_snd_pages(int order)
|
||||
snd_allocated_pages -= 1 << order;
|
||||
}
|
||||
|
||||
static void mark_pages(struct page *page, int order)
|
||||
{
|
||||
struct page *last_page = page + (1 << order);
|
||||
while (page < last_page)
|
||||
SetPageReserved(page++);
|
||||
}
|
||||
|
||||
static void unmark_pages(struct page *page, int order)
|
||||
{
|
||||
struct page *last_page = page + (1 << order);
|
||||
while (page < last_page)
|
||||
ClearPageReserved(page++);
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_malloc_pages - allocate pages with the given size
|
||||
* @size: the size to allocate in bytes
|
||||
@ -195,10 +177,8 @@ void *snd_malloc_pages(size_t size, gfp_t gfp_flags)
|
||||
snd_assert(gfp_flags != 0, return NULL);
|
||||
gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */
|
||||
pg = get_order(size);
|
||||
if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) {
|
||||
mark_pages(virt_to_page(res), pg);
|
||||
if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL)
|
||||
inc_snd_pages(pg);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -217,7 +197,6 @@ void snd_free_pages(void *ptr, size_t size)
|
||||
return;
|
||||
pg = get_order(size);
|
||||
dec_snd_pages(pg);
|
||||
unmark_pages(virt_to_page(ptr), pg);
|
||||
free_pages((unsigned long) ptr, pg);
|
||||
}
|
||||
|
||||
@ -242,12 +221,8 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d
|
||||
| __GFP_NORETRY /* don't trigger OOM-killer */
|
||||
| __GFP_NOWARN; /* no stack trace print - this call is non-critical */
|
||||
res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags);
|
||||
if (res != NULL) {
|
||||
#ifdef NEED_RESERVE_PAGES
|
||||
mark_pages(virt_to_page(res), pg); /* should be dma_to_page() */
|
||||
#endif
|
||||
if (res != NULL)
|
||||
inc_snd_pages(pg);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -262,9 +237,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
|
||||
return;
|
||||
pg = get_order(size);
|
||||
dec_snd_pages(pg);
|
||||
#ifdef NEED_RESERVE_PAGES
|
||||
unmark_pages(virt_to_page(ptr), pg); /* should be dma_to_page() */
|
||||
#endif
|
||||
dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma);
|
||||
}
|
||||
|
||||
@ -440,7 +412,7 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id)
|
||||
|
||||
snd_assert(dmab, return 0);
|
||||
|
||||
down(&list_mutex);
|
||||
mutex_lock(&list_mutex);
|
||||
list_for_each(p, &mem_list_head) {
|
||||
mem = list_entry(p, struct snd_mem_list, list);
|
||||
if (mem->id == id &&
|
||||
@ -452,11 +424,11 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id)
|
||||
if (dmab->dev.dev == NULL)
|
||||
dmab->dev.dev = dev;
|
||||
kfree(mem);
|
||||
up(&list_mutex);
|
||||
mutex_unlock(&list_mutex);
|
||||
return dmab->bytes;
|
||||
}
|
||||
}
|
||||
up(&list_mutex);
|
||||
mutex_unlock(&list_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -477,11 +449,11 @@ int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id)
|
||||
mem = kmalloc(sizeof(*mem), GFP_KERNEL);
|
||||
if (! mem)
|
||||
return -ENOMEM;
|
||||
down(&list_mutex);
|
||||
mutex_lock(&list_mutex);
|
||||
mem->buffer = *dmab;
|
||||
mem->id = id;
|
||||
list_add_tail(&mem->list, &mem_list_head);
|
||||
up(&list_mutex);
|
||||
mutex_unlock(&list_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -493,7 +465,7 @@ static void free_all_reserved_pages(void)
|
||||
struct list_head *p;
|
||||
struct snd_mem_list *mem;
|
||||
|
||||
down(&list_mutex);
|
||||
mutex_lock(&list_mutex);
|
||||
while (! list_empty(&mem_list_head)) {
|
||||
p = mem_list_head.next;
|
||||
mem = list_entry(p, struct snd_mem_list, list);
|
||||
@ -501,7 +473,7 @@ static void free_all_reserved_pages(void)
|
||||
snd_dma_free_pages(&mem->buffer);
|
||||
kfree(mem);
|
||||
}
|
||||
up(&list_mutex);
|
||||
mutex_unlock(&list_mutex);
|
||||
}
|
||||
|
||||
|
||||
@ -522,7 +494,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off,
|
||||
int devno;
|
||||
static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" };
|
||||
|
||||
down(&list_mutex);
|
||||
mutex_lock(&list_mutex);
|
||||
len += snprintf(page + len, count - len,
|
||||
"pages : %li bytes (%li pages per %likB)\n",
|
||||
pages * PAGE_SIZE, pages, PAGE_SIZE / 1024);
|
||||
@ -537,7 +509,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off,
|
||||
" addr = 0x%lx, size = %d bytes\n",
|
||||
(unsigned long)mem->buffer.addr, (int)mem->buffer.bytes);
|
||||
}
|
||||
up(&list_mutex);
|
||||
mutex_unlock(&list_mutex);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,9 @@
|
||||
*/
|
||||
|
||||
#include <sound/driver.h>
|
||||
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
|
||||
#include <linux/time.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
@ -85,3 +88,5 @@ int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug,
|
||||
*r_plugin = plugin;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -20,6 +20,9 @@
|
||||
*/
|
||||
|
||||
#include <sound/driver.h>
|
||||
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
|
||||
#include <linux/time.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
@ -132,3 +135,5 @@ int snd_pcm_plugin_build_io(struct snd_pcm_substream *plug,
|
||||
*r_plugin = plugin;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -21,6 +21,9 @@
|
||||
*/
|
||||
|
||||
#include <sound/driver.h>
|
||||
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
|
||||
#include <linux/time.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
@ -103,7 +106,7 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
|
||||
return frames;
|
||||
}
|
||||
|
||||
int conv_index(int src_format, int dst_format)
|
||||
static int conv_index(int src_format, int dst_format)
|
||||
{
|
||||
int src_endian, dst_endian, sign, src_width, dst_width;
|
||||
|
||||
@ -156,3 +159,5 @@ int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug,
|
||||
*r_plugin = plugin;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1095,7 +1095,7 @@ static void snd_mixer_oss_proc_read(struct snd_info_entry *entry,
|
||||
struct snd_mixer_oss *mixer = entry->private_data;
|
||||
int i;
|
||||
|
||||
down(&mixer->reg_mutex);
|
||||
mutex_lock(&mixer->reg_mutex);
|
||||
for (i = 0; i < SNDRV_OSS_MAX_MIXERS; i++) {
|
||||
struct slot *p;
|
||||
|
||||
@ -1110,7 +1110,7 @@ static void snd_mixer_oss_proc_read(struct snd_info_entry *entry,
|
||||
else
|
||||
snd_iprintf(buffer, "\"\" 0\n");
|
||||
}
|
||||
up(&mixer->reg_mutex);
|
||||
mutex_unlock(&mixer->reg_mutex);
|
||||
}
|
||||
|
||||
static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
|
||||
@ -1134,9 +1134,9 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
|
||||
cptr = snd_info_get_str(str, cptr, sizeof(str));
|
||||
if (! *str) {
|
||||
/* remove the entry */
|
||||
down(&mixer->reg_mutex);
|
||||
mutex_lock(&mixer->reg_mutex);
|
||||
mixer_slot_clear(&mixer->slots[ch]);
|
||||
up(&mixer->reg_mutex);
|
||||
mutex_unlock(&mixer->reg_mutex);
|
||||
continue;
|
||||
}
|
||||
snd_info_get_str(idxstr, cptr, sizeof(idxstr));
|
||||
@ -1145,7 +1145,7 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
|
||||
snd_printk(KERN_ERR "mixer_oss: invalid index %d\n", idx);
|
||||
continue;
|
||||
}
|
||||
down(&mixer->reg_mutex);
|
||||
mutex_lock(&mixer->reg_mutex);
|
||||
slot = (struct slot *)mixer->slots[ch].private_data;
|
||||
if (slot && slot->assigned &&
|
||||
slot->assigned->index == idx && ! strcmp(slot->assigned->name, str))
|
||||
@ -1168,7 +1168,7 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
|
||||
kfree(tbl);
|
||||
}
|
||||
__unlock:
|
||||
up(&mixer->reg_mutex);
|
||||
mutex_unlock(&mixer->reg_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1288,7 +1288,7 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd)
|
||||
mixer = kcalloc(2, sizeof(*mixer), GFP_KERNEL);
|
||||
if (mixer == NULL)
|
||||
return -ENOMEM;
|
||||
init_MUTEX(&mixer->reg_mutex);
|
||||
mutex_init(&mixer->reg_mutex);
|
||||
sprintf(name, "mixer%i%i", card->number, 0);
|
||||
if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER,
|
||||
card, 0,
|
||||
|
@ -22,6 +22,9 @@
|
||||
*/
|
||||
|
||||
#include <sound/driver.h>
|
||||
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
|
||||
#include <linux/time.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
@ -262,6 +265,25 @@ static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin,
|
||||
return frames;
|
||||
}
|
||||
|
||||
static int getput_index(int format)
|
||||
{
|
||||
int sign, width, endian;
|
||||
sign = !snd_pcm_format_signed(format);
|
||||
width = snd_pcm_format_width(format) / 8 - 1;
|
||||
if (width < 0 || width > 3) {
|
||||
snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format);
|
||||
width = 0;
|
||||
}
|
||||
#ifdef SNDRV_LITTLE_ENDIAN
|
||||
endian = snd_pcm_format_big_endian(format);
|
||||
#else
|
||||
endian = snd_pcm_format_little_endian(format);
|
||||
#endif
|
||||
if (endian < 0)
|
||||
endian = 0;
|
||||
return width * 4 + endian * 2 + sign;
|
||||
}
|
||||
|
||||
int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
|
||||
struct snd_pcm_plugin_format *src_format,
|
||||
struct snd_pcm_plugin_format *dst_format,
|
||||
@ -306,3 +328,5 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
|
||||
*r_plugin = plugin;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -78,6 +78,7 @@ static inline void snd_leave_user(mm_segment_t fs)
|
||||
set_fs(fs);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
@ -122,6 +123,7 @@ int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SND_PCM_OSS_PLUGINS */
|
||||
|
||||
static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames)
|
||||
{
|
||||
@ -412,6 +414,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
|
||||
oss_frame_size = snd_pcm_format_physical_width(params_format(params)) *
|
||||
params_channels(params) / 8;
|
||||
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
snd_pcm_oss_plugin_clear(substream);
|
||||
if (!direct) {
|
||||
/* add necessary plugins */
|
||||
@ -441,6 +444,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
err = snd_pcm_oss_period_size(substream, params, sparams);
|
||||
if (err < 0)
|
||||
@ -498,11 +502,13 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
|
||||
runtime->oss.periods = params_periods(sparams);
|
||||
oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams));
|
||||
snd_assert(oss_period_size >= 0, err = -EINVAL; goto failure);
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
if (runtime->oss.plugin_first) {
|
||||
err = snd_pcm_plug_alloc(substream, oss_period_size);
|
||||
if (err < 0)
|
||||
goto failure;
|
||||
}
|
||||
#endif
|
||||
oss_period_size *= oss_frame_size;
|
||||
|
||||
oss_buffer_size = oss_period_size * runtime->oss.periods;
|
||||
@ -784,6 +790,7 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_pcm_sframes_t frames, frames1;
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
if (runtime->oss.plugin_first) {
|
||||
struct snd_pcm_plugin_channel *channels;
|
||||
size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8;
|
||||
@ -800,7 +807,9 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha
|
||||
if (frames1 <= 0)
|
||||
return frames1;
|
||||
bytes = frames1 * oss_frame_bytes;
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
frames = bytes_to_frames(runtime, bytes);
|
||||
frames1 = snd_pcm_oss_write3(substream, buf, frames, in_kernel);
|
||||
if (frames1 <= 0)
|
||||
@ -871,6 +880,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf,
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_pcm_sframes_t frames, frames1;
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
char __user *final_dst = (char __user *)buf;
|
||||
if (runtime->oss.plugin_first) {
|
||||
struct snd_pcm_plugin_channel *channels;
|
||||
@ -887,7 +897,9 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf,
|
||||
bytes = frames1 * oss_frame_bytes;
|
||||
if (!in_kernel && copy_to_user(final_dst, buf, bytes))
|
||||
return -EFAULT;
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
frames = bytes_to_frames(runtime, bytes);
|
||||
frames1 = snd_pcm_oss_read3(substream, buf, frames, in_kernel);
|
||||
if (frames1 <= 0)
|
||||
@ -1631,10 +1643,10 @@ static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm,
|
||||
const char *ptr, *ptrl;
|
||||
struct snd_pcm_oss_setup *setup;
|
||||
|
||||
down(&pcm->streams[stream].oss.setup_mutex);
|
||||
mutex_lock(&pcm->streams[stream].oss.setup_mutex);
|
||||
for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) {
|
||||
if (!strcmp(setup->task_name, task_name)) {
|
||||
up(&pcm->streams[stream].oss.setup_mutex);
|
||||
mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
|
||||
return setup;
|
||||
}
|
||||
}
|
||||
@ -1650,12 +1662,12 @@ static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm,
|
||||
}
|
||||
for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) {
|
||||
if (!strcmp(setup->task_name, ptrl)) {
|
||||
up(&pcm->streams[stream].oss.setup_mutex);
|
||||
mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
|
||||
return setup;
|
||||
}
|
||||
}
|
||||
__not_found:
|
||||
up(&pcm->streams[stream].oss.setup_mutex);
|
||||
mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1692,7 +1704,9 @@ static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream)
|
||||
struct snd_pcm_runtime *runtime;
|
||||
runtime = substream->runtime;
|
||||
vfree(runtime->oss.buffer);
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
snd_pcm_oss_plugin_clear(substream);
|
||||
#endif
|
||||
substream->oss.file = NULL;
|
||||
substream->oss.oss = 0;
|
||||
}
|
||||
@ -1881,7 +1895,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
|
||||
|
||||
init_waitqueue_entry(&wait, current);
|
||||
add_wait_queue(&pcm->open_wait, &wait);
|
||||
down(&pcm->open_mutex);
|
||||
mutex_lock(&pcm->open_mutex);
|
||||
while (1) {
|
||||
err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file,
|
||||
iminor(inode), psetup, csetup);
|
||||
@ -1895,16 +1909,16 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
|
||||
} else
|
||||
break;
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
up(&pcm->open_mutex);
|
||||
mutex_unlock(&pcm->open_mutex);
|
||||
schedule();
|
||||
down(&pcm->open_mutex);
|
||||
mutex_lock(&pcm->open_mutex);
|
||||
if (signal_pending(current)) {
|
||||
err = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
remove_wait_queue(&pcm->open_wait, &wait);
|
||||
up(&pcm->open_mutex);
|
||||
mutex_unlock(&pcm->open_mutex);
|
||||
if (err < 0)
|
||||
goto __error;
|
||||
return err;
|
||||
@ -1930,9 +1944,9 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file)
|
||||
snd_assert(substream != NULL, return -ENXIO);
|
||||
pcm = substream->pcm;
|
||||
snd_pcm_oss_sync(pcm_oss_file);
|
||||
down(&pcm->open_mutex);
|
||||
mutex_lock(&pcm->open_mutex);
|
||||
snd_pcm_oss_release_file(pcm_oss_file);
|
||||
up(&pcm->open_mutex);
|
||||
mutex_unlock(&pcm->open_mutex);
|
||||
wake_up(&pcm->open_wait);
|
||||
module_put(pcm->card->module);
|
||||
snd_card_file_remove(pcm->card, file);
|
||||
@ -2246,8 +2260,10 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area)
|
||||
if ((err = snd_pcm_oss_change_params(substream)) < 0)
|
||||
return err;
|
||||
}
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
if (runtime->oss.plugin_first != NULL)
|
||||
return -EIO;
|
||||
#endif
|
||||
|
||||
if (area->vm_pgoff != 0)
|
||||
return -EINVAL;
|
||||
@ -2277,7 +2293,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
|
||||
{
|
||||
struct snd_pcm_str *pstr = entry->private_data;
|
||||
struct snd_pcm_oss_setup *setup = pstr->oss.setup_list;
|
||||
down(&pstr->oss.setup_mutex);
|
||||
mutex_lock(&pstr->oss.setup_mutex);
|
||||
while (setup) {
|
||||
snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
|
||||
setup->task_name,
|
||||
@ -2291,7 +2307,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
|
||||
setup->nosilence ? " no-silence" : "");
|
||||
setup = setup->next;
|
||||
}
|
||||
up(&pstr->oss.setup_mutex);
|
||||
mutex_unlock(&pstr->oss.setup_mutex);
|
||||
}
|
||||
|
||||
static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr)
|
||||
@ -2321,12 +2337,12 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
|
||||
struct snd_pcm_oss_setup *setup, *setup1, template;
|
||||
|
||||
while (!snd_info_get_line(buffer, line, sizeof(line))) {
|
||||
down(&pstr->oss.setup_mutex);
|
||||
mutex_lock(&pstr->oss.setup_mutex);
|
||||
memset(&template, 0, sizeof(template));
|
||||
ptr = snd_info_get_str(task_name, line, sizeof(task_name));
|
||||
if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) {
|
||||
snd_pcm_oss_proc_free_setup_list(pstr);
|
||||
up(&pstr->oss.setup_mutex);
|
||||
mutex_unlock(&pstr->oss.setup_mutex);
|
||||
continue;
|
||||
}
|
||||
for (setup = pstr->oss.setup_list; setup; setup = setup->next) {
|
||||
@ -2378,7 +2394,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
|
||||
}
|
||||
if (setup)
|
||||
*setup = template;
|
||||
up(&pstr->oss.setup_mutex);
|
||||
mutex_unlock(&pstr->oss.setup_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,9 @@
|
||||
#endif
|
||||
|
||||
#include <sound/driver.h>
|
||||
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/vmalloc.h>
|
||||
@ -36,26 +39,6 @@
|
||||
#define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first)
|
||||
#define snd_pcm_plug_last(plug) ((plug)->runtime->oss.plugin_last)
|
||||
|
||||
static int snd_pcm_plugin_src_channels_mask(struct snd_pcm_plugin *plugin,
|
||||
unsigned long *dst_vmask,
|
||||
unsigned long **src_vmask)
|
||||
{
|
||||
unsigned long *vmask = plugin->src_vmask;
|
||||
bitmap_copy(vmask, dst_vmask, plugin->src_format.channels);
|
||||
*src_vmask = vmask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_plugin_dst_channels_mask(struct snd_pcm_plugin *plugin,
|
||||
unsigned long *src_vmask,
|
||||
unsigned long **dst_vmask)
|
||||
{
|
||||
unsigned long *vmask = plugin->dst_vmask;
|
||||
bitmap_copy(vmask, src_vmask, plugin->dst_format.channels);
|
||||
*dst_vmask = vmask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* because some cards might have rates "very close", we ignore
|
||||
* all "resampling" requests within +-5%
|
||||
@ -193,19 +176,7 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug,
|
||||
snd_pcm_plugin_free(plugin);
|
||||
return -ENOMEM;
|
||||
}
|
||||
plugin->src_vmask = bitmap_alloc(src_format->channels);
|
||||
if (plugin->src_vmask == NULL) {
|
||||
snd_pcm_plugin_free(plugin);
|
||||
return -ENOMEM;
|
||||
}
|
||||
plugin->dst_vmask = bitmap_alloc(dst_format->channels);
|
||||
if (plugin->dst_vmask == NULL) {
|
||||
snd_pcm_plugin_free(plugin);
|
||||
return -ENOMEM;
|
||||
}
|
||||
plugin->client_channels = snd_pcm_plugin_client_channels;
|
||||
plugin->src_channels_mask = snd_pcm_plugin_src_channels_mask;
|
||||
plugin->dst_channels_mask = snd_pcm_plugin_dst_channels_mask;
|
||||
*ret = plugin;
|
||||
return 0;
|
||||
}
|
||||
@ -218,8 +189,6 @@ int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin)
|
||||
plugin->private_free(plugin);
|
||||
kfree(plugin->buf_channels);
|
||||
vfree(plugin->buf);
|
||||
kfree(plugin->src_vmask);
|
||||
kfree(plugin->dst_vmask);
|
||||
kfree(plugin);
|
||||
return 0;
|
||||
}
|
||||
@ -429,24 +398,14 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
|
||||
dstformat.channels);
|
||||
|
||||
/* Format change (linearization) */
|
||||
if ((srcformat.format != dstformat.format ||
|
||||
!rate_match(srcformat.rate, dstformat.rate) ||
|
||||
srcformat.channels != dstformat.channels) &&
|
||||
!snd_pcm_format_linear(srcformat.format)) {
|
||||
if (snd_pcm_format_linear(dstformat.format))
|
||||
tmpformat.format = dstformat.format;
|
||||
else
|
||||
tmpformat.format = SNDRV_PCM_FORMAT_S16;
|
||||
switch (srcformat.format) {
|
||||
case SNDRV_PCM_FORMAT_MU_LAW:
|
||||
err = snd_pcm_plugin_build_mulaw(plug,
|
||||
&srcformat, &tmpformat,
|
||||
&plugin);
|
||||
break;
|
||||
default:
|
||||
if (! rate_match(srcformat.rate, dstformat.rate) &&
|
||||
! snd_pcm_format_linear(srcformat.format)) {
|
||||
if (srcformat.format != SNDRV_PCM_FORMAT_MU_LAW)
|
||||
return -EINVAL;
|
||||
}
|
||||
pdprintf("format change: src=%i, dst=%i returns %i\n", srcformat.format, tmpformat.format, err);
|
||||
tmpformat.format = SNDRV_PCM_FORMAT_S16;
|
||||
err = snd_pcm_plugin_build_mulaw(plug,
|
||||
&srcformat, &tmpformat,
|
||||
&plugin);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = snd_pcm_plugin_append(plugin);
|
||||
@ -460,35 +419,11 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
|
||||
|
||||
/* channels reduction */
|
||||
if (srcformat.channels > dstformat.channels) {
|
||||
int sv = srcformat.channels;
|
||||
int dv = dstformat.channels;
|
||||
int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL);
|
||||
if (ttable == NULL)
|
||||
return -ENOMEM;
|
||||
#if 1
|
||||
if (sv == 2 && dv == 1) {
|
||||
ttable[0] = HALF;
|
||||
ttable[1] = HALF;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
int v;
|
||||
for (v = 0; v < dv; ++v)
|
||||
ttable[v * sv + v] = FULL;
|
||||
}
|
||||
tmpformat.channels = dstformat.channels;
|
||||
if (rate_match(srcformat.rate, dstformat.rate) &&
|
||||
snd_pcm_format_linear(dstformat.format))
|
||||
tmpformat.format = dstformat.format;
|
||||
err = snd_pcm_plugin_build_route(plug,
|
||||
&srcformat, &tmpformat,
|
||||
ttable, &plugin);
|
||||
kfree(ttable);
|
||||
err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin);
|
||||
pdprintf("channels reduction: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err);
|
||||
if (err < 0) {
|
||||
snd_pcm_plugin_free(plugin);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
err = snd_pcm_plugin_append(plugin);
|
||||
if (err < 0) {
|
||||
snd_pcm_plugin_free(plugin);
|
||||
@ -500,18 +435,29 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
|
||||
|
||||
/* rate resampling */
|
||||
if (!rate_match(srcformat.rate, dstformat.rate)) {
|
||||
if (srcformat.format != SNDRV_PCM_FORMAT_S16) {
|
||||
/* convert to S16 for resampling */
|
||||
tmpformat.format = SNDRV_PCM_FORMAT_S16;
|
||||
err = snd_pcm_plugin_build_linear(plug,
|
||||
&srcformat, &tmpformat,
|
||||
&plugin);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = snd_pcm_plugin_append(plugin);
|
||||
if (err < 0) {
|
||||
snd_pcm_plugin_free(plugin);
|
||||
return err;
|
||||
}
|
||||
srcformat = tmpformat;
|
||||
src_access = dst_access;
|
||||
}
|
||||
tmpformat.rate = dstformat.rate;
|
||||
if (srcformat.channels == dstformat.channels &&
|
||||
snd_pcm_format_linear(dstformat.format))
|
||||
tmpformat.format = dstformat.format;
|
||||
err = snd_pcm_plugin_build_rate(plug,
|
||||
&srcformat, &tmpformat,
|
||||
&plugin);
|
||||
pdprintf("rate down resampling: src=%i, dst=%i returns %i\n", srcformat.rate, tmpformat.rate, err);
|
||||
if (err < 0) {
|
||||
snd_pcm_plugin_free(plugin);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
err = snd_pcm_plugin_append(plugin);
|
||||
if (err < 0) {
|
||||
snd_pcm_plugin_free(plugin);
|
||||
@ -521,56 +467,11 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
|
||||
src_access = dst_access;
|
||||
}
|
||||
|
||||
/* channels extension */
|
||||
if (srcformat.channels < dstformat.channels) {
|
||||
int sv = srcformat.channels;
|
||||
int dv = dstformat.channels;
|
||||
int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL);
|
||||
if (ttable == NULL)
|
||||
return -ENOMEM;
|
||||
#if 0
|
||||
{
|
||||
int v;
|
||||
for (v = 0; v < sv; ++v)
|
||||
ttable[v * sv + v] = FULL;
|
||||
}
|
||||
#else
|
||||
{
|
||||
/* Playback is spreaded on all channels */
|
||||
int vd, vs;
|
||||
for (vd = 0, vs = 0; vd < dv; ++vd) {
|
||||
ttable[vd * sv + vs] = FULL;
|
||||
vs++;
|
||||
if (vs == sv)
|
||||
vs = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
tmpformat.channels = dstformat.channels;
|
||||
if (snd_pcm_format_linear(dstformat.format))
|
||||
tmpformat.format = dstformat.format;
|
||||
err = snd_pcm_plugin_build_route(plug,
|
||||
&srcformat, &tmpformat,
|
||||
ttable, &plugin);
|
||||
kfree(ttable);
|
||||
pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err);
|
||||
if (err < 0) {
|
||||
snd_pcm_plugin_free(plugin);
|
||||
return err;
|
||||
}
|
||||
err = snd_pcm_plugin_append(plugin);
|
||||
if (err < 0) {
|
||||
snd_pcm_plugin_free(plugin);
|
||||
return err;
|
||||
}
|
||||
srcformat = tmpformat;
|
||||
src_access = dst_access;
|
||||
}
|
||||
|
||||
/* format change */
|
||||
if (srcformat.format != dstformat.format) {
|
||||
tmpformat.format = dstformat.format;
|
||||
if (tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) {
|
||||
if (srcformat.format == SNDRV_PCM_FORMAT_MU_LAW ||
|
||||
tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) {
|
||||
err = snd_pcm_plugin_build_mulaw(plug,
|
||||
&srcformat, &tmpformat,
|
||||
&plugin);
|
||||
@ -595,6 +496,22 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
|
||||
src_access = dst_access;
|
||||
}
|
||||
|
||||
/* channels extension */
|
||||
if (srcformat.channels < dstformat.channels) {
|
||||
tmpformat.channels = dstformat.channels;
|
||||
err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin);
|
||||
pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = snd_pcm_plugin_append(plugin);
|
||||
if (err < 0) {
|
||||
snd_pcm_plugin_free(plugin);
|
||||
return err;
|
||||
}
|
||||
srcformat = tmpformat;
|
||||
src_access = dst_access;
|
||||
}
|
||||
|
||||
/* de-interleave */
|
||||
if (src_access != dst_access) {
|
||||
err = snd_pcm_plugin_build_copy(plug,
|
||||
@ -650,92 +567,6 @@ snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plu
|
||||
return count;
|
||||
}
|
||||
|
||||
static int snd_pcm_plug_playback_channels_mask(struct snd_pcm_substream *plug,
|
||||
unsigned long *client_vmask)
|
||||
{
|
||||
struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug);
|
||||
if (plugin == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
int schannels = plugin->dst_format.channels;
|
||||
DECLARE_BITMAP(bs, schannels);
|
||||
unsigned long *srcmask;
|
||||
unsigned long *dstmask = bs;
|
||||
int err;
|
||||
bitmap_fill(dstmask, schannels);
|
||||
|
||||
while (1) {
|
||||
err = plugin->src_channels_mask(plugin, dstmask, &srcmask);
|
||||
if (err < 0)
|
||||
return err;
|
||||
dstmask = srcmask;
|
||||
if (plugin->prev == NULL)
|
||||
break;
|
||||
plugin = plugin->prev;
|
||||
}
|
||||
bitmap_and(client_vmask, client_vmask, dstmask, plugin->src_format.channels);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int snd_pcm_plug_playback_disable_useless_channels(struct snd_pcm_substream *plug,
|
||||
struct snd_pcm_plugin_channel *src_channels)
|
||||
{
|
||||
struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug);
|
||||
unsigned int nchannels = plugin->src_format.channels;
|
||||
DECLARE_BITMAP(bs, nchannels);
|
||||
unsigned long *srcmask = bs;
|
||||
int err;
|
||||
unsigned int channel;
|
||||
for (channel = 0; channel < nchannels; channel++) {
|
||||
if (src_channels[channel].enabled)
|
||||
set_bit(channel, srcmask);
|
||||
else
|
||||
clear_bit(channel, srcmask);
|
||||
}
|
||||
err = snd_pcm_plug_playback_channels_mask(plug, srcmask);
|
||||
if (err < 0)
|
||||
return err;
|
||||
for (channel = 0; channel < nchannels; channel++) {
|
||||
if (!test_bit(channel, srcmask))
|
||||
src_channels[channel].enabled = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_plug_capture_disable_useless_channels(struct snd_pcm_substream *plug,
|
||||
struct snd_pcm_plugin_channel *src_channels,
|
||||
struct snd_pcm_plugin_channel *client_channels)
|
||||
{
|
||||
struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug);
|
||||
unsigned int nchannels = plugin->dst_format.channels;
|
||||
DECLARE_BITMAP(bs, nchannels);
|
||||
unsigned long *dstmask = bs;
|
||||
unsigned long *srcmask;
|
||||
int err;
|
||||
unsigned int channel;
|
||||
for (channel = 0; channel < nchannels; channel++) {
|
||||
if (client_channels[channel].enabled)
|
||||
set_bit(channel, dstmask);
|
||||
else
|
||||
clear_bit(channel, dstmask);
|
||||
}
|
||||
while (plugin) {
|
||||
err = plugin->src_channels_mask(plugin, dstmask, &srcmask);
|
||||
if (err < 0)
|
||||
return err;
|
||||
dstmask = srcmask;
|
||||
plugin = plugin->prev;
|
||||
}
|
||||
plugin = snd_pcm_plug_first(plug);
|
||||
nchannels = plugin->src_format.channels;
|
||||
for (channel = 0; channel < nchannels; channel++) {
|
||||
if (!test_bit(channel, dstmask))
|
||||
src_channels[channel].enabled = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *src_channels, snd_pcm_uframes_t size)
|
||||
{
|
||||
struct snd_pcm_plugin *plugin, *next;
|
||||
@ -743,9 +574,6 @@ snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, st
|
||||
int err;
|
||||
snd_pcm_sframes_t frames = size;
|
||||
|
||||
if ((err = snd_pcm_plug_playback_disable_useless_channels(plug, src_channels)) < 0)
|
||||
return err;
|
||||
|
||||
plugin = snd_pcm_plug_first(plug);
|
||||
while (plugin && frames > 0) {
|
||||
if ((next = plugin->next) != NULL) {
|
||||
@ -790,10 +618,6 @@ snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, str
|
||||
return err;
|
||||
}
|
||||
frames = err;
|
||||
if (!plugin->prev) {
|
||||
if ((err = snd_pcm_plug_capture_disable_useless_channels(plug, dst_channels, dst_channels_final)) < 0)
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
dst_channels = dst_channels_final;
|
||||
}
|
||||
@ -916,3 +740,5 @@ int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_area, size_t src_of
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -22,12 +22,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/bitmap.h>
|
||||
|
||||
static inline unsigned long *bitmap_alloc(unsigned int nbits)
|
||||
{
|
||||
return kmalloc(BITS_TO_LONGS(nbits), GFP_KERNEL);
|
||||
}
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
|
||||
#define snd_pcm_plug_stream(plug) ((plug)->stream)
|
||||
|
||||
@ -69,12 +64,6 @@ struct snd_pcm_plugin {
|
||||
snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin,
|
||||
snd_pcm_uframes_t frames,
|
||||
struct snd_pcm_plugin_channel **channels);
|
||||
int (*src_channels_mask)(struct snd_pcm_plugin *plugin,
|
||||
unsigned long *dst_vmask,
|
||||
unsigned long **src_vmask);
|
||||
int (*dst_channels_mask)(struct snd_pcm_plugin *plugin,
|
||||
unsigned long *src_vmask,
|
||||
unsigned long **dst_vmask);
|
||||
snd_pcm_sframes_t (*transfer)(struct snd_pcm_plugin *plugin,
|
||||
const struct snd_pcm_plugin_channel *src_channels,
|
||||
struct snd_pcm_plugin_channel *dst_channels,
|
||||
@ -90,8 +79,6 @@ struct snd_pcm_plugin {
|
||||
char *buf;
|
||||
snd_pcm_uframes_t buf_frames;
|
||||
struct snd_pcm_plugin_channel *buf_channels;
|
||||
unsigned long *src_vmask;
|
||||
unsigned long *dst_vmask;
|
||||
char extra_data[0];
|
||||
};
|
||||
|
||||
@ -128,7 +115,6 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *handle,
|
||||
int snd_pcm_plugin_build_route(struct snd_pcm_substream *handle,
|
||||
struct snd_pcm_plugin_format *src_format,
|
||||
struct snd_pcm_plugin_format *dst_format,
|
||||
int *ttable,
|
||||
struct snd_pcm_plugin **r_plugin);
|
||||
int snd_pcm_plugin_build_copy(struct snd_pcm_substream *handle,
|
||||
struct snd_pcm_plugin_format *src_format,
|
||||
@ -181,15 +167,13 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream,
|
||||
void **bufs, snd_pcm_uframes_t frames,
|
||||
int in_kernel);
|
||||
|
||||
#define ROUTE_PLUGIN_RESOLUTION 16
|
||||
#else
|
||||
|
||||
int getput_index(int format);
|
||||
int copy_index(int format);
|
||||
int conv_index(int src_format, int dst_format);
|
||||
static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; }
|
||||
static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; }
|
||||
static inline int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) { return format; }
|
||||
|
||||
void zero_channel(struct snd_pcm_plugin *plugin,
|
||||
const struct snd_pcm_plugin_channel *dst_channel,
|
||||
size_t samples);
|
||||
#endif
|
||||
|
||||
#ifdef PLUGIN_DEBUG
|
||||
#define pdprintf( fmt, args... ) printk( "plugin: " fmt, ##args)
|
||||
|
@ -362,172 +362,6 @@ put_s16_xx12_0029: as_u32(dst) = (u_int32_t)swab16(sample) ^ 0x80; goto PUT_S16_
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#ifdef GET32_LABELS
|
||||
/* src_wid src_endswap unsigned */
|
||||
static void *get32_labels[4 * 2 * 2] = {
|
||||
&&get32_xxx1_1000, /* 8h -> 32h */
|
||||
&&get32_xxx1_9000, /* 8h ^> 32h */
|
||||
&&get32_xxx1_1000, /* 8s -> 32h */
|
||||
&&get32_xxx1_9000, /* 8s ^> 32h */
|
||||
&&get32_xx12_1200, /* 16h -> 32h */
|
||||
&&get32_xx12_9200, /* 16h ^> 32h */
|
||||
&&get32_xx12_2100, /* 16s -> 32h */
|
||||
&&get32_xx12_A100, /* 16s ^> 32h */
|
||||
&&get32_x123_1230, /* 24h -> 32h */
|
||||
&&get32_x123_9230, /* 24h ^> 32h */
|
||||
&&get32_123x_3210, /* 24s -> 32h */
|
||||
&&get32_123x_B210, /* 24s ^> 32h */
|
||||
&&get32_1234_1234, /* 32h -> 32h */
|
||||
&&get32_1234_9234, /* 32h ^> 32h */
|
||||
&&get32_1234_4321, /* 32s -> 32h */
|
||||
&&get32_1234_C321, /* 32s ^> 32h */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef GET32_END
|
||||
while (0) {
|
||||
get32_xxx1_1000: sample = (u_int32_t)as_u8(src) << 24; goto GET32_END;
|
||||
get32_xxx1_9000: sample = (u_int32_t)(as_u8(src) ^ 0x80) << 24; goto GET32_END;
|
||||
get32_xx12_1200: sample = (u_int32_t)as_u16(src) << 16; goto GET32_END;
|
||||
get32_xx12_9200: sample = (u_int32_t)(as_u16(src) ^ 0x8000) << 16; goto GET32_END;
|
||||
get32_xx12_2100: sample = (u_int32_t)swab16(as_u16(src)) << 16; goto GET32_END;
|
||||
get32_xx12_A100: sample = (u_int32_t)swab16(as_u16(src) ^ 0x80) << 16; goto GET32_END;
|
||||
get32_x123_1230: sample = as_u32(src) << 8; goto GET32_END;
|
||||
get32_x123_9230: sample = (as_u32(src) << 8) ^ 0x80000000; goto GET32_END;
|
||||
get32_123x_3210: sample = swab32(as_u32(src) >> 8); goto GET32_END;
|
||||
get32_123x_B210: sample = swab32((as_u32(src) >> 8) ^ 0x80); goto GET32_END;
|
||||
get32_1234_1234: sample = as_u32(src); goto GET32_END;
|
||||
get32_1234_9234: sample = as_u32(src) ^ 0x80000000; goto GET32_END;
|
||||
get32_1234_4321: sample = swab32(as_u32(src)); goto GET32_END;
|
||||
get32_1234_C321: sample = swab32(as_u32(src) ^ 0x80); goto GET32_END;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PUT_U32_LABELS
|
||||
/* dst_wid dst_endswap unsigned */
|
||||
static void *put_u32_labels[4 * 2 * 2] = {
|
||||
&&put_u32_1234_xxx9, /* u32h -> s8h */
|
||||
&&put_u32_1234_xxx1, /* u32h -> u8h */
|
||||
&&put_u32_1234_xxx9, /* u32h -> s8s */
|
||||
&&put_u32_1234_xxx1, /* u32h -> u8s */
|
||||
&&put_u32_1234_xx92, /* u32h -> s16h */
|
||||
&&put_u32_1234_xx12, /* u32h -> u16h */
|
||||
&&put_u32_1234_xx29, /* u32h -> s16s */
|
||||
&&put_u32_1234_xx21, /* u32h -> u16s */
|
||||
&&put_u32_1234_x923, /* u32h -> s24h */
|
||||
&&put_u32_1234_x123, /* u32h -> u24h */
|
||||
&&put_u32_1234_329x, /* u32h -> s24s */
|
||||
&&put_u32_1234_321x, /* u32h -> u24s */
|
||||
&&put_u32_1234_9234, /* u32h -> s32h */
|
||||
&&put_u32_1234_1234, /* u32h -> u32h */
|
||||
&&put_u32_1234_4329, /* u32h -> s32s */
|
||||
&&put_u32_1234_4321, /* u32h -> u32s */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef PUT_U32_END
|
||||
while (0) {
|
||||
put_u32_1234_xxx1: as_u8(dst) = sample >> 24; goto PUT_U32_END;
|
||||
put_u32_1234_xxx9: as_u8(dst) = (sample >> 24) ^ 0x80; goto PUT_U32_END;
|
||||
put_u32_1234_xx12: as_u16(dst) = sample >> 16; goto PUT_U32_END;
|
||||
put_u32_1234_xx92: as_u16(dst) = (sample >> 16) ^ 0x8000; goto PUT_U32_END;
|
||||
put_u32_1234_xx21: as_u16(dst) = swab16(sample >> 16); goto PUT_U32_END;
|
||||
put_u32_1234_xx29: as_u16(dst) = swab16(sample >> 16) ^ 0x80; goto PUT_U32_END;
|
||||
put_u32_1234_x123: as_u32(dst) = sample >> 8; goto PUT_U32_END;
|
||||
put_u32_1234_x923: as_u32(dst) = (sample >> 8) ^ 0x800000; goto PUT_U32_END;
|
||||
put_u32_1234_321x: as_u32(dst) = swab32(sample) << 8; goto PUT_U32_END;
|
||||
put_u32_1234_329x: as_u32(dst) = (swab32(sample) ^ 0x80) << 8; goto PUT_U32_END;
|
||||
put_u32_1234_1234: as_u32(dst) = sample; goto PUT_U32_END;
|
||||
put_u32_1234_9234: as_u32(dst) = sample ^ 0x80000000; goto PUT_U32_END;
|
||||
put_u32_1234_4321: as_u32(dst) = swab32(sample); goto PUT_U32_END;
|
||||
put_u32_1234_4329: as_u32(dst) = swab32(sample) ^ 0x80; goto PUT_U32_END;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GET_U_LABELS
|
||||
/* width endswap unsigned*/
|
||||
static void *get_u_labels[4 * 2 * 2] = {
|
||||
&&get_u_s8, /* s8 -> u8 */
|
||||
&&get_u_u8, /* u8 -> u8 */
|
||||
&&get_u_s8, /* s8 -> u8 */
|
||||
&&get_u_u8, /* u8 -> u8 */
|
||||
&&get_u_s16h, /* s16h -> u16h */
|
||||
&&get_u_u16h, /* u16h -> u16h */
|
||||
&&get_u_s16s, /* s16s -> u16h */
|
||||
&&get_u_u16s, /* u16s -> u16h */
|
||||
&&get_u_s24h, /* s24h -> u32h */
|
||||
&&get_u_u24h, /* u24h -> u32h */
|
||||
&&get_u_s24s, /* s24s -> u32h */
|
||||
&&get_u_u24s, /* u24s -> u32h */
|
||||
&&get_u_s32h, /* s32h -> u32h */
|
||||
&&get_u_u32h, /* u32h -> u32h */
|
||||
&&get_u_s32s, /* s32s -> u32h */
|
||||
&&get_u_u32s, /* u32s -> u32h */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef GET_U_END
|
||||
while (0) {
|
||||
get_u_s8: sample = as_u8(src) ^ 0x80; goto GET_U_END;
|
||||
get_u_u8: sample = as_u8(src); goto GET_U_END;
|
||||
get_u_s16h: sample = as_u16(src) ^ 0x8000; goto GET_U_END;
|
||||
get_u_u16h: sample = as_u16(src); goto GET_U_END;
|
||||
get_u_s16s: sample = swab16(as_u16(src) ^ 0x80); goto GET_U_END;
|
||||
get_u_u16s: sample = swab16(as_u16(src)); goto GET_U_END;
|
||||
get_u_s24h: sample = (as_u32(src) ^ 0x800000); goto GET_U_END;
|
||||
get_u_u24h: sample = as_u32(src); goto GET_U_END;
|
||||
get_u_s24s: sample = swab32(as_u32(src) ^ 0x800000); goto GET_U_END;
|
||||
get_u_u24s: sample = swab32(as_u32(src)); goto GET_U_END;
|
||||
get_u_s32h: sample = as_u32(src) ^ 0x80000000; goto GET_U_END;
|
||||
get_u_u32h: sample = as_u32(src); goto GET_U_END;
|
||||
get_u_s32s: sample = swab32(as_u32(src) ^ 0x80); goto GET_U_END;
|
||||
get_u_u32s: sample = swab32(as_u32(src)); goto GET_U_END;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#ifdef PUT_LABELS
|
||||
/* width endswap unsigned */
|
||||
static void *put_labels[4 * 2 * 2] = {
|
||||
&&put_s8, /* s8 -> s8 */
|
||||
&&put_u8, /* u8 -> s8 */
|
||||
&&put_s8, /* s8 -> s8 */
|
||||
&&put_u8, /* u8 -> s8 */
|
||||
&&put_s16h, /* s16h -> s16h */
|
||||
&&put_u16h, /* u16h -> s16h */
|
||||
&&put_s16s, /* s16s -> s16h */
|
||||
&&put_u16s, /* u16s -> s16h */
|
||||
&&put_s24h, /* s24h -> s32h */
|
||||
&&put_u24h, /* u24h -> s32h */
|
||||
&&put_s24s, /* s24s -> s32h */
|
||||
&&put_u24s, /* u24s -> s32h */
|
||||
&&put_s32h, /* s32h -> s32h */
|
||||
&&put_u32h, /* u32h -> s32h */
|
||||
&&put_s32s, /* s32s -> s32h */
|
||||
&&put_u32s, /* u32s -> s32h */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef PUT_END
|
||||
put_s8: as_s8(dst) = sample; goto PUT_END;
|
||||
put_u8: as_u8(dst) = sample ^ 0x80; goto PUT_END;
|
||||
put_s16h: as_s16(dst) = sample; goto PUT_END;
|
||||
put_u16h: as_u16(dst) = sample ^ 0x8000; goto PUT_END;
|
||||
put_s16s: as_s16(dst) = swab16(sample); goto PUT_END;
|
||||
put_u16s: as_u16(dst) = swab16(sample ^ 0x80); goto PUT_END;
|
||||
put_s24h: as_s24(dst) = sample & 0xffffff; goto PUT_END;
|
||||
put_u24h: as_u24(dst) = sample ^ 0x80000000; goto PUT_END;
|
||||
put_s24s: as_s24(dst) = swab32(sample & 0xffffff); goto PUT_END;
|
||||
put_u24s: as_u24(dst) = swab32(sample ^ 0x80); goto PUT_END;
|
||||
put_s32h: as_s32(dst) = sample; goto PUT_END;
|
||||
put_u32h: as_u32(dst) = sample ^ 0x80000000; goto PUT_END;
|
||||
put_s32s: as_s32(dst) = swab32(sample); goto PUT_END;
|
||||
put_u32s: as_u32(dst) = swab32(sample ^ 0x80); goto PUT_END;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef as_u8
|
||||
#undef as_u16
|
||||
#undef as_u32
|
||||
|
@ -20,6 +20,9 @@
|
||||
*/
|
||||
|
||||
#include <sound/driver.h>
|
||||
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
|
||||
#include <linux/time.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
@ -47,7 +50,6 @@ struct rate_priv {
|
||||
unsigned int pitch;
|
||||
unsigned int pos;
|
||||
rate_f func;
|
||||
int get, put;
|
||||
snd_pcm_sframes_t old_src_frames, old_dst_frames;
|
||||
struct rate_channel channels[0];
|
||||
};
|
||||
@ -71,21 +73,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin,
|
||||
unsigned int pos = 0;
|
||||
signed int val;
|
||||
signed short S1, S2;
|
||||
char *src, *dst;
|
||||
signed short *src, *dst;
|
||||
unsigned int channel;
|
||||
int src_step, dst_step;
|
||||
int src_frames1, dst_frames1;
|
||||
struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
|
||||
struct rate_channel *rchannels = data->channels;
|
||||
|
||||
#define GET_S16_LABELS
|
||||
#define PUT_S16_LABELS
|
||||
#include "plugin_ops.h"
|
||||
#undef GET_S16_LABELS
|
||||
#undef PUT_S16_LABELS
|
||||
void *get = get_s16_labels[data->get];
|
||||
void *put = put_s16_labels[data->put];
|
||||
signed short sample = 0;
|
||||
|
||||
for (channel = 0; channel < plugin->src_format.channels; channel++) {
|
||||
pos = data->pos;
|
||||
@ -98,10 +91,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin,
|
||||
continue;
|
||||
}
|
||||
dst_channels[channel].enabled = 1;
|
||||
src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8;
|
||||
dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
|
||||
src_step = src_channels[channel].area.step / 8;
|
||||
dst_step = dst_channels[channel].area.step / 8;
|
||||
src = (signed short *)src_channels[channel].area.addr +
|
||||
src_channels[channel].area.first / 8 / 2;
|
||||
dst = (signed short *)dst_channels[channel].area.addr +
|
||||
dst_channels[channel].area.first / 8 / 2;
|
||||
src_step = src_channels[channel].area.step / 8 / 2;
|
||||
dst_step = dst_channels[channel].area.step / 8 / 2;
|
||||
src_frames1 = src_frames;
|
||||
dst_frames1 = dst_frames;
|
||||
while (dst_frames1-- > 0) {
|
||||
@ -109,12 +104,7 @@ static void resample_expand(struct snd_pcm_plugin *plugin,
|
||||
pos &= R_MASK;
|
||||
S1 = S2;
|
||||
if (src_frames1-- > 0) {
|
||||
goto *get;
|
||||
#define GET_S16_END after_get
|
||||
#include "plugin_ops.h"
|
||||
#undef GET_S16_END
|
||||
after_get:
|
||||
S2 = sample;
|
||||
S2 = *src;
|
||||
src += src_step;
|
||||
}
|
||||
}
|
||||
@ -123,12 +113,7 @@ static void resample_expand(struct snd_pcm_plugin *plugin,
|
||||
val = -32768;
|
||||
else if (val > 32767)
|
||||
val = 32767;
|
||||
sample = val;
|
||||
goto *put;
|
||||
#define PUT_S16_END after_put
|
||||
#include "plugin_ops.h"
|
||||
#undef PUT_S16_END
|
||||
after_put:
|
||||
*dst = val;
|
||||
dst += dst_step;
|
||||
pos += data->pitch;
|
||||
}
|
||||
@ -147,21 +132,12 @@ static void resample_shrink(struct snd_pcm_plugin *plugin,
|
||||
unsigned int pos = 0;
|
||||
signed int val;
|
||||
signed short S1, S2;
|
||||
char *src, *dst;
|
||||
signed short *src, *dst;
|
||||
unsigned int channel;
|
||||
int src_step, dst_step;
|
||||
int src_frames1, dst_frames1;
|
||||
struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
|
||||
struct rate_channel *rchannels = data->channels;
|
||||
|
||||
#define GET_S16_LABELS
|
||||
#define PUT_S16_LABELS
|
||||
#include "plugin_ops.h"
|
||||
#undef GET_S16_LABELS
|
||||
#undef PUT_S16_LABELS
|
||||
void *get = get_s16_labels[data->get];
|
||||
void *put = put_s16_labels[data->put];
|
||||
signed short sample = 0;
|
||||
|
||||
for (channel = 0; channel < plugin->src_format.channels; ++channel) {
|
||||
pos = data->pos;
|
||||
@ -174,21 +150,18 @@ static void resample_shrink(struct snd_pcm_plugin *plugin,
|
||||
continue;
|
||||
}
|
||||
dst_channels[channel].enabled = 1;
|
||||
src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8;
|
||||
dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
|
||||
src_step = src_channels[channel].area.step / 8;
|
||||
dst_step = dst_channels[channel].area.step / 8;
|
||||
src = (signed short *)src_channels[channel].area.addr +
|
||||
src_channels[channel].area.first / 8 / 2;
|
||||
dst = (signed short *)dst_channels[channel].area.addr +
|
||||
dst_channels[channel].area.first / 8 / 2;
|
||||
src_step = src_channels[channel].area.step / 8 / 2;
|
||||
dst_step = dst_channels[channel].area.step / 8 / 2;
|
||||
src_frames1 = src_frames;
|
||||
dst_frames1 = dst_frames;
|
||||
while (dst_frames1 > 0) {
|
||||
S1 = S2;
|
||||
if (src_frames1-- > 0) {
|
||||
goto *get;
|
||||
#define GET_S16_END after_get
|
||||
#include "plugin_ops.h"
|
||||
#undef GET_S16_END
|
||||
after_get:
|
||||
S2 = sample;
|
||||
S1 = *src;
|
||||
src += src_step;
|
||||
}
|
||||
if (pos & ~R_MASK) {
|
||||
@ -198,12 +171,7 @@ static void resample_shrink(struct snd_pcm_plugin *plugin,
|
||||
val = -32768;
|
||||
else if (val > 32767)
|
||||
val = 32767;
|
||||
sample = val;
|
||||
goto *put;
|
||||
#define PUT_S16_END after_put
|
||||
#include "plugin_ops.h"
|
||||
#undef PUT_S16_END
|
||||
after_put:
|
||||
*dst = val;
|
||||
dst += dst_step;
|
||||
dst_frames1--;
|
||||
}
|
||||
@ -343,8 +311,8 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
|
||||
|
||||
snd_assert(src_format->channels == dst_format->channels, return -ENXIO);
|
||||
snd_assert(src_format->channels > 0, return -ENXIO);
|
||||
snd_assert(snd_pcm_format_linear(src_format->format) != 0, return -ENXIO);
|
||||
snd_assert(snd_pcm_format_linear(dst_format->format) != 0, return -ENXIO);
|
||||
snd_assert(src_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO);
|
||||
snd_assert(dst_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO);
|
||||
snd_assert(src_format->rate != dst_format->rate, return -ENXIO);
|
||||
|
||||
err = snd_pcm_plugin_build(plug, "rate conversion",
|
||||
@ -355,11 +323,6 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
|
||||
if (err < 0)
|
||||
return err;
|
||||
data = (struct rate_priv *)plugin->extra_data;
|
||||
data->get = getput_index(src_format->format);
|
||||
snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
|
||||
data->put = getput_index(dst_format->format);
|
||||
snd_assert(data->put >= 0 && data->put < 4*2*2, return -EINVAL);
|
||||
|
||||
if (src_format->rate < dst_format->rate) {
|
||||
data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate;
|
||||
data->func = resample_expand;
|
||||
@ -377,3 +340,5 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
|
||||
*r_plugin = plugin;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Attenuated route Plug-In
|
||||
* Route Plug-In
|
||||
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
|
||||
*
|
||||
*
|
||||
@ -20,502 +20,93 @@
|
||||
*/
|
||||
|
||||
#include <sound/driver.h>
|
||||
|
||||
#ifdef CONFIG_SND_PCM_OSS_PLUGINS
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/time.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include "pcm_plugin.h"
|
||||
|
||||
/* The best possible hack to support missing optimization in gcc 2.7.2.3 */
|
||||
#if ROUTE_PLUGIN_RESOLUTION & (ROUTE_PLUGIN_RESOLUTION - 1) != 0
|
||||
#define div(a) a /= ROUTE_PLUGIN_RESOLUTION
|
||||
#elif ROUTE_PLUGIN_RESOLUTION == 16
|
||||
#define div(a) a >>= 4
|
||||
#else
|
||||
#error "Add some code here"
|
||||
#endif
|
||||
|
||||
struct ttable_dst;
|
||||
|
||||
typedef void (*route_channel_f)(struct snd_pcm_plugin *plugin,
|
||||
const struct snd_pcm_plugin_channel *src_channels,
|
||||
struct snd_pcm_plugin_channel *dst_channel,
|
||||
struct ttable_dst *ttable, snd_pcm_uframes_t frames);
|
||||
|
||||
struct ttable_src {
|
||||
int channel;
|
||||
int as_int;
|
||||
};
|
||||
|
||||
struct ttable_dst {
|
||||
int att; /* Attenuated */
|
||||
unsigned int nsrcs;
|
||||
struct ttable_src *srcs;
|
||||
route_channel_f func;
|
||||
};
|
||||
|
||||
struct route_priv {
|
||||
enum {R_UINT32=0, R_UINT64=1} sum_type;
|
||||
int get, put;
|
||||
int conv;
|
||||
int src_sample_size;
|
||||
struct ttable_dst ttable[0];
|
||||
};
|
||||
|
||||
union sum {
|
||||
u_int32_t as_uint32;
|
||||
u_int64_t as_uint64;
|
||||
};
|
||||
|
||||
|
||||
static void route_to_channel_from_zero(struct snd_pcm_plugin *plugin,
|
||||
const struct snd_pcm_plugin_channel *src_channels,
|
||||
struct snd_pcm_plugin_channel *dst_channel,
|
||||
struct ttable_dst *ttable,
|
||||
snd_pcm_uframes_t frames)
|
||||
static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts,
|
||||
snd_pcm_uframes_t frames, int format)
|
||||
{
|
||||
if (dst_channel->wanted)
|
||||
snd_pcm_area_silence(&dst_channel->area, 0, frames, plugin->dst_format.format);
|
||||
dst_channel->enabled = 0;
|
||||
}
|
||||
|
||||
static void route_to_channel_from_one(struct snd_pcm_plugin *plugin,
|
||||
const struct snd_pcm_plugin_channel *src_channels,
|
||||
struct snd_pcm_plugin_channel *dst_channel,
|
||||
struct ttable_dst *ttable,
|
||||
snd_pcm_uframes_t frames)
|
||||
{
|
||||
#define CONV_LABELS
|
||||
#include "plugin_ops.h"
|
||||
#undef CONV_LABELS
|
||||
struct route_priv *data = (struct route_priv *)plugin->extra_data;
|
||||
void *conv;
|
||||
const struct snd_pcm_plugin_channel *src_channel = NULL;
|
||||
unsigned int srcidx;
|
||||
char *src, *dst;
|
||||
int src_step, dst_step;
|
||||
for (srcidx = 0; srcidx < ttable->nsrcs; ++srcidx) {
|
||||
src_channel = &src_channels[ttable->srcs[srcidx].channel];
|
||||
if (src_channel->area.addr != NULL)
|
||||
break;
|
||||
}
|
||||
if (srcidx == ttable->nsrcs) {
|
||||
route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames);
|
||||
return;
|
||||
}
|
||||
|
||||
dst_channel->enabled = 1;
|
||||
conv = conv_labels[data->conv];
|
||||
src = src_channel->area.addr + src_channel->area.first / 8;
|
||||
src_step = src_channel->area.step / 8;
|
||||
dst = dst_channel->area.addr + dst_channel->area.first / 8;
|
||||
dst_step = dst_channel->area.step / 8;
|
||||
while (frames-- > 0) {
|
||||
goto *conv;
|
||||
#define CONV_END after
|
||||
#include "plugin_ops.h"
|
||||
#undef CONV_END
|
||||
after:
|
||||
src += src_step;
|
||||
dst += dst_step;
|
||||
int dst = 0;
|
||||
for (; dst < ndsts; ++dst) {
|
||||
if (dvp->wanted)
|
||||
snd_pcm_area_silence(&dvp->area, 0, frames, format);
|
||||
dvp->enabled = 0;
|
||||
dvp++;
|
||||
}
|
||||
}
|
||||
|
||||
static void route_to_channel(struct snd_pcm_plugin *plugin,
|
||||
const struct snd_pcm_plugin_channel *src_channels,
|
||||
static inline void copy_area(const struct snd_pcm_plugin_channel *src_channel,
|
||||
struct snd_pcm_plugin_channel *dst_channel,
|
||||
struct ttable_dst *ttable, snd_pcm_uframes_t frames)
|
||||
snd_pcm_uframes_t frames, int format)
|
||||
{
|
||||
#define GET_U_LABELS
|
||||
#define PUT_U32_LABELS
|
||||
#include "plugin_ops.h"
|
||||
#undef GET_U_LABELS
|
||||
#undef PUT_U32_LABELS
|
||||
static void *zero_labels[2] = { &&zero_int32, &&zero_int64 };
|
||||
/* sum_type att */
|
||||
static void *add_labels[2 * 2] = { &&add_int32_noatt, &&add_int32_att,
|
||||
&&add_int64_noatt, &&add_int64_att,
|
||||
};
|
||||
/* sum_type att shift */
|
||||
static void *norm_labels[2 * 2 * 4] = { NULL,
|
||||
&&norm_int32_8_noatt,
|
||||
&&norm_int32_16_noatt,
|
||||
&&norm_int32_24_noatt,
|
||||
NULL,
|
||||
&&norm_int32_8_att,
|
||||
&&norm_int32_16_att,
|
||||
&&norm_int32_24_att,
|
||||
&&norm_int64_0_noatt,
|
||||
&&norm_int64_8_noatt,
|
||||
&&norm_int64_16_noatt,
|
||||
&&norm_int64_24_noatt,
|
||||
&&norm_int64_0_att,
|
||||
&&norm_int64_8_att,
|
||||
&&norm_int64_16_att,
|
||||
&&norm_int64_24_att,
|
||||
};
|
||||
struct route_priv *data = (struct route_priv *)plugin->extra_data;
|
||||
void *zero, *get, *add, *norm, *put_u32;
|
||||
int nsrcs = ttable->nsrcs;
|
||||
char *dst;
|
||||
int dst_step;
|
||||
char *srcs[nsrcs];
|
||||
int src_steps[nsrcs];
|
||||
struct ttable_src src_tt[nsrcs];
|
||||
u_int32_t sample = 0;
|
||||
int srcidx, srcidx1 = 0;
|
||||
for (srcidx = 0; srcidx < nsrcs; ++srcidx) {
|
||||
const struct snd_pcm_plugin_channel *src_channel = &src_channels[ttable->srcs[srcidx].channel];
|
||||
if (!src_channel->enabled)
|
||||
continue;
|
||||
srcs[srcidx1] = src_channel->area.addr + src_channel->area.first / 8;
|
||||
src_steps[srcidx1] = src_channel->area.step / 8;
|
||||
src_tt[srcidx1] = ttable->srcs[srcidx];
|
||||
srcidx1++;
|
||||
}
|
||||
nsrcs = srcidx1;
|
||||
if (nsrcs == 0) {
|
||||
route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames);
|
||||
return;
|
||||
} else if (nsrcs == 1 && src_tt[0].as_int == ROUTE_PLUGIN_RESOLUTION) {
|
||||
route_to_channel_from_one(plugin, src_channels, dst_channel, ttable, frames);
|
||||
return;
|
||||
}
|
||||
|
||||
dst_channel->enabled = 1;
|
||||
zero = zero_labels[data->sum_type];
|
||||
get = get_u_labels[data->get];
|
||||
add = add_labels[data->sum_type * 2 + ttable->att];
|
||||
norm = norm_labels[data->sum_type * 8 + ttable->att * 4 + 4 - data->src_sample_size];
|
||||
put_u32 = put_u32_labels[data->put];
|
||||
dst = dst_channel->area.addr + dst_channel->area.first / 8;
|
||||
dst_step = dst_channel->area.step / 8;
|
||||
|
||||
while (frames-- > 0) {
|
||||
struct ttable_src *ttp = src_tt;
|
||||
union sum sum;
|
||||
|
||||
/* Zero sum */
|
||||
goto *zero;
|
||||
zero_int32:
|
||||
sum.as_uint32 = 0;
|
||||
goto zero_end;
|
||||
zero_int64:
|
||||
sum.as_uint64 = 0;
|
||||
goto zero_end;
|
||||
zero_end:
|
||||
for (srcidx = 0; srcidx < nsrcs; ++srcidx) {
|
||||
char *src = srcs[srcidx];
|
||||
|
||||
/* Get sample */
|
||||
goto *get;
|
||||
#define GET_U_END after_get
|
||||
#include "plugin_ops.h"
|
||||
#undef GET_U_END
|
||||
after_get:
|
||||
|
||||
/* Sum */
|
||||
goto *add;
|
||||
add_int32_att:
|
||||
sum.as_uint32 += sample * ttp->as_int;
|
||||
goto after_sum;
|
||||
add_int32_noatt:
|
||||
if (ttp->as_int)
|
||||
sum.as_uint32 += sample;
|
||||
goto after_sum;
|
||||
add_int64_att:
|
||||
sum.as_uint64 += (u_int64_t) sample * ttp->as_int;
|
||||
goto after_sum;
|
||||
add_int64_noatt:
|
||||
if (ttp->as_int)
|
||||
sum.as_uint64 += sample;
|
||||
goto after_sum;
|
||||
after_sum:
|
||||
srcs[srcidx] += src_steps[srcidx];
|
||||
ttp++;
|
||||
}
|
||||
|
||||
/* Normalization */
|
||||
goto *norm;
|
||||
norm_int32_8_att:
|
||||
sum.as_uint64 = sum.as_uint32;
|
||||
norm_int64_8_att:
|
||||
sum.as_uint64 <<= 8;
|
||||
norm_int64_0_att:
|
||||
div(sum.as_uint64);
|
||||
goto norm_int;
|
||||
|
||||
norm_int32_16_att:
|
||||
sum.as_uint64 = sum.as_uint32;
|
||||
norm_int64_16_att:
|
||||
sum.as_uint64 <<= 16;
|
||||
div(sum.as_uint64);
|
||||
goto norm_int;
|
||||
|
||||
norm_int32_24_att:
|
||||
sum.as_uint64 = sum.as_uint32;
|
||||
norm_int64_24_att:
|
||||
sum.as_uint64 <<= 24;
|
||||
div(sum.as_uint64);
|
||||
goto norm_int;
|
||||
|
||||
norm_int32_8_noatt:
|
||||
sum.as_uint64 = sum.as_uint32;
|
||||
norm_int64_8_noatt:
|
||||
sum.as_uint64 <<= 8;
|
||||
goto norm_int;
|
||||
|
||||
norm_int32_16_noatt:
|
||||
sum.as_uint64 = sum.as_uint32;
|
||||
norm_int64_16_noatt:
|
||||
sum.as_uint64 <<= 16;
|
||||
goto norm_int;
|
||||
|
||||
norm_int32_24_noatt:
|
||||
sum.as_uint64 = sum.as_uint32;
|
||||
norm_int64_24_noatt:
|
||||
sum.as_uint64 <<= 24;
|
||||
goto norm_int;
|
||||
|
||||
norm_int64_0_noatt:
|
||||
norm_int:
|
||||
if (sum.as_uint64 > (u_int32_t)0xffffffff)
|
||||
sample = (u_int32_t)0xffffffff;
|
||||
else
|
||||
sample = sum.as_uint64;
|
||||
goto after_norm;
|
||||
|
||||
after_norm:
|
||||
|
||||
/* Put sample */
|
||||
goto *put_u32;
|
||||
#define PUT_U32_END after_put_u32
|
||||
#include "plugin_ops.h"
|
||||
#undef PUT_U32_END
|
||||
after_put_u32:
|
||||
|
||||
dst += dst_step;
|
||||
}
|
||||
}
|
||||
|
||||
static int route_src_channels_mask(struct snd_pcm_plugin *plugin,
|
||||
unsigned long *dst_vmask,
|
||||
unsigned long **src_vmask)
|
||||
{
|
||||
struct route_priv *data = (struct route_priv *)plugin->extra_data;
|
||||
int schannels = plugin->src_format.channels;
|
||||
int dchannels = plugin->dst_format.channels;
|
||||
unsigned long *vmask = plugin->src_vmask;
|
||||
int channel;
|
||||
struct ttable_dst *dp = data->ttable;
|
||||
bitmap_zero(vmask, schannels);
|
||||
for (channel = 0; channel < dchannels; channel++, dp++) {
|
||||
unsigned int src;
|
||||
struct ttable_src *sp;
|
||||
if (!test_bit(channel, dst_vmask))
|
||||
continue;
|
||||
sp = dp->srcs;
|
||||
for (src = 0; src < dp->nsrcs; src++, sp++)
|
||||
set_bit(sp->channel, vmask);
|
||||
}
|
||||
*src_vmask = vmask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int route_dst_channels_mask(struct snd_pcm_plugin *plugin,
|
||||
unsigned long *src_vmask,
|
||||
unsigned long **dst_vmask)
|
||||
{
|
||||
struct route_priv *data = (struct route_priv *)plugin->extra_data;
|
||||
int dchannels = plugin->dst_format.channels;
|
||||
unsigned long *vmask = plugin->dst_vmask;
|
||||
int channel;
|
||||
struct ttable_dst *dp = data->ttable;
|
||||
bitmap_zero(vmask, dchannels);
|
||||
for (channel = 0; channel < dchannels; channel++, dp++) {
|
||||
unsigned int src;
|
||||
struct ttable_src *sp;
|
||||
sp = dp->srcs;
|
||||
for (src = 0; src < dp->nsrcs; src++, sp++) {
|
||||
if (test_bit(sp->channel, src_vmask)) {
|
||||
set_bit(channel, vmask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*dst_vmask = vmask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void route_free(struct snd_pcm_plugin *plugin)
|
||||
{
|
||||
struct route_priv *data = (struct route_priv *)plugin->extra_data;
|
||||
unsigned int dst_channel;
|
||||
for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
|
||||
kfree(data->ttable[dst_channel].srcs);
|
||||
}
|
||||
}
|
||||
|
||||
static int route_load_ttable(struct snd_pcm_plugin *plugin,
|
||||
const int *src_ttable)
|
||||
{
|
||||
struct route_priv *data;
|
||||
unsigned int src_channel, dst_channel;
|
||||
const int *sptr;
|
||||
struct ttable_dst *dptr;
|
||||
if (src_ttable == NULL)
|
||||
return 0;
|
||||
data = (struct route_priv *)plugin->extra_data;
|
||||
dptr = data->ttable;
|
||||
sptr = src_ttable;
|
||||
plugin->private_free = route_free;
|
||||
for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
|
||||
int t = 0;
|
||||
int att = 0;
|
||||
int nsrcs = 0;
|
||||
struct ttable_src srcs[plugin->src_format.channels];
|
||||
for (src_channel = 0; src_channel < plugin->src_format.channels; ++src_channel) {
|
||||
snd_assert(*sptr >= 0 || *sptr <= FULL, return -ENXIO);
|
||||
if (*sptr != 0) {
|
||||
srcs[nsrcs].channel = src_channel;
|
||||
srcs[nsrcs].as_int = *sptr;
|
||||
if (*sptr != FULL)
|
||||
att = 1;
|
||||
t += *sptr;
|
||||
nsrcs++;
|
||||
}
|
||||
sptr++;
|
||||
}
|
||||
dptr->att = att;
|
||||
dptr->nsrcs = nsrcs;
|
||||
if (nsrcs == 0)
|
||||
dptr->func = route_to_channel_from_zero;
|
||||
else if (nsrcs == 1 && !att)
|
||||
dptr->func = route_to_channel_from_one;
|
||||
else
|
||||
dptr->func = route_to_channel;
|
||||
if (nsrcs > 0) {
|
||||
int srcidx;
|
||||
dptr->srcs = kcalloc(nsrcs, sizeof(*srcs), GFP_KERNEL);
|
||||
for(srcidx = 0; srcidx < nsrcs; srcidx++)
|
||||
dptr->srcs[srcidx] = srcs[srcidx];
|
||||
} else
|
||||
dptr->srcs = NULL;
|
||||
dptr++;
|
||||
}
|
||||
return 0;
|
||||
snd_pcm_area_copy(&src_channel->area, 0, &dst_channel->area, 0, frames, format);
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin,
|
||||
const struct snd_pcm_plugin_channel *src_channels,
|
||||
struct snd_pcm_plugin_channel *dst_channels,
|
||||
snd_pcm_uframes_t frames)
|
||||
const struct snd_pcm_plugin_channel *src_channels,
|
||||
struct snd_pcm_plugin_channel *dst_channels,
|
||||
snd_pcm_uframes_t frames)
|
||||
{
|
||||
struct route_priv *data;
|
||||
int src_nchannels, dst_nchannels;
|
||||
int dst_channel;
|
||||
struct ttable_dst *ttp;
|
||||
int nsrcs, ndsts, dst;
|
||||
struct snd_pcm_plugin_channel *dvp;
|
||||
int format;
|
||||
|
||||
snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
|
||||
if (frames == 0)
|
||||
return 0;
|
||||
data = (struct route_priv *)plugin->extra_data;
|
||||
|
||||
src_nchannels = plugin->src_format.channels;
|
||||
dst_nchannels = plugin->dst_format.channels;
|
||||
nsrcs = plugin->src_format.channels;
|
||||
ndsts = plugin->dst_format.channels;
|
||||
|
||||
#ifdef CONFIG_SND_DEBUG
|
||||
{
|
||||
int src_channel;
|
||||
for (src_channel = 0; src_channel < src_nchannels; ++src_channel) {
|
||||
snd_assert(src_channels[src_channel].area.first % 8 == 0 ||
|
||||
src_channels[src_channel].area.step % 8 == 0,
|
||||
return -ENXIO);
|
||||
}
|
||||
for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) {
|
||||
snd_assert(dst_channels[dst_channel].area.first % 8 == 0 ||
|
||||
dst_channels[dst_channel].area.step % 8 == 0,
|
||||
return -ENXIO);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ttp = data->ttable;
|
||||
format = plugin->dst_format.format;
|
||||
dvp = dst_channels;
|
||||
for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) {
|
||||
ttp->func(plugin, src_channels, dvp, ttp, frames);
|
||||
dvp++;
|
||||
ttp++;
|
||||
if (nsrcs <= 1) {
|
||||
/* expand to all channels */
|
||||
for (dst = 0; dst < ndsts; ++dst) {
|
||||
copy_area(src_channels, dvp, frames, format);
|
||||
dvp++;
|
||||
}
|
||||
return frames;
|
||||
}
|
||||
return frames;
|
||||
}
|
||||
|
||||
int getput_index(int format)
|
||||
{
|
||||
int sign, width, endian;
|
||||
sign = !snd_pcm_format_signed(format);
|
||||
width = snd_pcm_format_width(format) / 8 - 1;
|
||||
if (width < 0 || width > 3) {
|
||||
snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format);
|
||||
width = 0;
|
||||
for (dst = 0; dst < ndsts && dst < nsrcs; ++dst) {
|
||||
copy_area(src_channels, dvp, frames, format);
|
||||
dvp++;
|
||||
src_channels++;
|
||||
}
|
||||
#ifdef SNDRV_LITTLE_ENDIAN
|
||||
endian = snd_pcm_format_big_endian(format);
|
||||
#else
|
||||
endian = snd_pcm_format_little_endian(format);
|
||||
#endif
|
||||
if (endian < 0)
|
||||
endian = 0;
|
||||
return width * 4 + endian * 2 + sign;
|
||||
if (dst < ndsts)
|
||||
zero_areas(dvp, ndsts - dst, frames, format);
|
||||
return frames;
|
||||
}
|
||||
|
||||
int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug,
|
||||
struct snd_pcm_plugin_format *src_format,
|
||||
struct snd_pcm_plugin_format *dst_format,
|
||||
int *ttable,
|
||||
struct snd_pcm_plugin **r_plugin)
|
||||
{
|
||||
struct route_priv *data;
|
||||
struct snd_pcm_plugin *plugin;
|
||||
int err;
|
||||
|
||||
snd_assert(r_plugin != NULL, return -ENXIO);
|
||||
*r_plugin = NULL;
|
||||
snd_assert(src_format->rate == dst_format->rate, return -ENXIO);
|
||||
snd_assert(snd_pcm_format_linear(src_format->format) != 0 &&
|
||||
snd_pcm_format_linear(dst_format->format) != 0,
|
||||
return -ENXIO);
|
||||
snd_assert(src_format->format == dst_format->format, return -ENXIO);
|
||||
|
||||
err = snd_pcm_plugin_build(plug, "attenuated route conversion",
|
||||
src_format, dst_format,
|
||||
sizeof(struct route_priv) +
|
||||
sizeof(data->ttable[0]) * dst_format->channels,
|
||||
&plugin);
|
||||
err = snd_pcm_plugin_build(plug, "route conversion",
|
||||
src_format, dst_format, 0, &plugin);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
data = (struct route_priv *)plugin->extra_data;
|
||||
|
||||
data->get = getput_index(src_format->format);
|
||||
snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
|
||||
data->put = getput_index(dst_format->format);
|
||||
snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
|
||||
data->conv = conv_index(src_format->format, dst_format->format);
|
||||
|
||||
if (snd_pcm_format_width(src_format->format) == 32)
|
||||
data->sum_type = R_UINT64;
|
||||
else
|
||||
data->sum_type = R_UINT32;
|
||||
data->src_sample_size = snd_pcm_format_width(src_format->format) / 8;
|
||||
|
||||
if ((err = route_load_ttable(plugin, ttable)) < 0) {
|
||||
snd_pcm_plugin_free(plugin);
|
||||
return err;
|
||||
}
|
||||
plugin->transfer = route_transfer;
|
||||
plugin->src_channels_mask = route_src_channels_mask;
|
||||
plugin->dst_channels_mask = route_dst_channels_mask;
|
||||
*r_plugin = plugin;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/minors.h>
|
||||
#include <sound/pcm.h>
|
||||
@ -35,7 +36,7 @@ MODULE_LICENSE("GPL");
|
||||
|
||||
static LIST_HEAD(snd_pcm_devices);
|
||||
static LIST_HEAD(snd_pcm_notify_list);
|
||||
static DECLARE_MUTEX(register_mutex);
|
||||
static DEFINE_MUTEX(register_mutex);
|
||||
|
||||
static int snd_pcm_free(struct snd_pcm *pcm);
|
||||
static int snd_pcm_dev_free(struct snd_device *device);
|
||||
@ -67,7 +68,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
|
||||
|
||||
if (get_user(device, (int __user *)arg))
|
||||
return -EFAULT;
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
device = device < 0 ? 0 : device + 1;
|
||||
while (device < SNDRV_PCM_DEVICES) {
|
||||
if (snd_pcm_search(card, device))
|
||||
@ -76,7 +77,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
|
||||
}
|
||||
if (device == SNDRV_PCM_DEVICES)
|
||||
device = -1;
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (put_user(device, (int __user *)arg))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
@ -100,7 +101,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
|
||||
return -EINVAL;
|
||||
if (get_user(subdevice, &info->subdevice))
|
||||
return -EFAULT;
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
pcm = snd_pcm_search(card, device);
|
||||
if (pcm == NULL) {
|
||||
err = -ENXIO;
|
||||
@ -125,7 +126,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
|
||||
}
|
||||
err = snd_pcm_info_user(substream, info);
|
||||
_error:
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
}
|
||||
case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE:
|
||||
@ -140,6 +141,9 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
|
||||
}
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_PROC_FS) && defined(CONFIG_SND_VERBOSE_PROCFS)
|
||||
|
||||
#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
|
||||
#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
|
||||
#define READY(v) [SNDRV_PCM_READY_##v] = #v
|
||||
@ -197,7 +201,6 @@ const char *snd_pcm_format_name(snd_pcm_format_t format)
|
||||
return snd_pcm_format_names[format];
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static char *snd_pcm_stream_names[] = {
|
||||
STREAM(PLAYBACK),
|
||||
STREAM(CAPTURE),
|
||||
@ -260,6 +263,7 @@ static const char *snd_pcm_state_name(snd_pcm_state_t state)
|
||||
|
||||
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
|
||||
#include <linux/soundcard.h>
|
||||
|
||||
static const char *snd_pcm_oss_format_name(int format)
|
||||
{
|
||||
switch (format) {
|
||||
@ -622,7 +626,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
|
||||
struct snd_pcm_substream *substream, *prev;
|
||||
|
||||
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
|
||||
init_MUTEX(&pstr->oss.setup_mutex);
|
||||
mutex_init(&pstr->oss.setup_mutex);
|
||||
#endif
|
||||
pstr->stream = stream;
|
||||
pstr->pcm = pcm;
|
||||
@ -716,7 +720,7 @@ int snd_pcm_new(struct snd_card *card, char *id, int device,
|
||||
snd_pcm_free(pcm);
|
||||
return err;
|
||||
}
|
||||
init_MUTEX(&pcm->open_mutex);
|
||||
mutex_init(&pcm->open_mutex);
|
||||
init_waitqueue_head(&pcm->open_wait);
|
||||
if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) {
|
||||
snd_pcm_free(pcm);
|
||||
@ -902,9 +906,9 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
||||
struct snd_pcm *pcm = device->device_data;
|
||||
|
||||
snd_assert(pcm != NULL && device != NULL, return -ENXIO);
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
if (snd_pcm_search(pcm->card, pcm->device)) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
list_add_tail(&pcm->list, &snd_pcm_devices);
|
||||
@ -928,7 +932,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
||||
pcm, str)) < 0)
|
||||
{
|
||||
list_del(&pcm->list);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
}
|
||||
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
|
||||
@ -939,7 +943,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
|
||||
notify = list_entry(list, struct snd_pcm_notify, list);
|
||||
notify->n_register(pcm);
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -950,7 +954,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
|
||||
struct snd_pcm_substream *substream;
|
||||
int cidx;
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
list_del_init(&pcm->list);
|
||||
for (cidx = 0; cidx < 2; cidx++)
|
||||
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
|
||||
@ -961,7 +965,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
|
||||
notify = list_entry(list, struct snd_pcm_notify, list);
|
||||
notify->n_disconnect(pcm);
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -973,7 +977,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device)
|
||||
struct snd_pcm *pcm = device->device_data;
|
||||
|
||||
snd_assert(pcm != NULL, return -ENXIO);
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
list_del(&pcm->list);
|
||||
for (cidx = 0; cidx < 2; cidx++) {
|
||||
devtype = -1;
|
||||
@ -994,7 +998,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device)
|
||||
notify = list_entry(list, struct snd_pcm_notify, list);
|
||||
notify->n_unregister(pcm);
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return snd_pcm_free(pcm);
|
||||
}
|
||||
|
||||
@ -1003,7 +1007,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
|
||||
struct list_head *p;
|
||||
|
||||
snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL);
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
if (nfree) {
|
||||
list_del(¬ify->list);
|
||||
list_for_each(p, &snd_pcm_devices)
|
||||
@ -1014,7 +1018,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
|
||||
list_for_each(p, &snd_pcm_devices)
|
||||
notify->n_register(list_entry(p, struct snd_pcm, list));
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1029,7 +1033,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry,
|
||||
struct list_head *p;
|
||||
struct snd_pcm *pcm;
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
list_for_each(p, &snd_pcm_devices) {
|
||||
pcm = list_entry(p, struct snd_pcm, list);
|
||||
snd_iprintf(buffer, "%02i-%02i: %s : %s",
|
||||
@ -1042,7 +1046,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry,
|
||||
pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);
|
||||
snd_iprintf(buffer, "\n");
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
}
|
||||
|
||||
static struct snd_info_entry *snd_pcm_proc_entry = NULL;
|
||||
@ -1101,7 +1105,6 @@ EXPORT_SYMBOL(snd_pcm_new_stream);
|
||||
EXPORT_SYMBOL(snd_pcm_notify);
|
||||
EXPORT_SYMBOL(snd_pcm_open_substream);
|
||||
EXPORT_SYMBOL(snd_pcm_release_substream);
|
||||
EXPORT_SYMBOL(snd_pcm_format_name);
|
||||
/* pcm_native.c */
|
||||
EXPORT_SYMBOL(snd_pcm_link_rwlock);
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -2112,7 +2112,7 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
|
||||
}
|
||||
init_waitqueue_entry(&wait, current);
|
||||
add_wait_queue(&pcm->open_wait, &wait);
|
||||
down(&pcm->open_mutex);
|
||||
mutex_lock(&pcm->open_mutex);
|
||||
while (1) {
|
||||
err = snd_pcm_open_file(file, pcm, stream, &pcm_file);
|
||||
if (err >= 0)
|
||||
@ -2125,16 +2125,16 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
|
||||
} else
|
||||
break;
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
up(&pcm->open_mutex);
|
||||
mutex_unlock(&pcm->open_mutex);
|
||||
schedule();
|
||||
down(&pcm->open_mutex);
|
||||
mutex_lock(&pcm->open_mutex);
|
||||
if (signal_pending(current)) {
|
||||
err = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
remove_wait_queue(&pcm->open_wait, &wait);
|
||||
up(&pcm->open_mutex);
|
||||
mutex_unlock(&pcm->open_mutex);
|
||||
if (err < 0)
|
||||
goto __error;
|
||||
return err;
|
||||
@ -2160,9 +2160,9 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
|
||||
pcm = substream->pcm;
|
||||
snd_pcm_drop(substream);
|
||||
fasync_helper(-1, file, 0, &substream->runtime->fasync);
|
||||
down(&pcm->open_mutex);
|
||||
mutex_lock(&pcm->open_mutex);
|
||||
snd_pcm_release_file(pcm_file);
|
||||
up(&pcm->open_mutex);
|
||||
mutex_unlock(&pcm->open_mutex);
|
||||
wake_up(&pcm->open_wait);
|
||||
module_put(pcm->card->module);
|
||||
snd_card_file_remove(pcm->card, file);
|
||||
@ -2539,6 +2539,14 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
|
||||
return snd_pcm_drain(substream);
|
||||
case SNDRV_PCM_IOCTL_DROP:
|
||||
return snd_pcm_drop(substream);
|
||||
case SNDRV_PCM_IOCTL_PAUSE:
|
||||
{
|
||||
int res;
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
res = snd_pcm_pause(substream, (int)(unsigned long)arg);
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
snd_printd("unknown ioctl = 0x%x\n", cmd);
|
||||
return -ENOTTY;
|
||||
@ -2619,14 +2627,6 @@ static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
|
||||
__put_user(result, _frames);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
case SNDRV_PCM_IOCTL_PAUSE:
|
||||
{
|
||||
int res;
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
res = snd_pcm_pause(substream, (int)(unsigned long)arg);
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return snd_pcm_common_ioctl1(substream, cmd, arg);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/wait.h>
|
||||
@ -57,7 +58,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device);
|
||||
static int snd_rawmidi_dev_unregister(struct snd_device *device);
|
||||
|
||||
static LIST_HEAD(snd_rawmidi_devices);
|
||||
static DECLARE_MUTEX(register_mutex);
|
||||
static DEFINE_MUTEX(register_mutex);
|
||||
|
||||
static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device)
|
||||
{
|
||||
@ -237,9 +238,9 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
|
||||
|
||||
if (rfile)
|
||||
rfile->input = rfile->output = NULL;
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
rmidi = snd_rawmidi_search(card, device);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (rmidi == NULL) {
|
||||
err = -ENODEV;
|
||||
goto __error1;
|
||||
@ -249,7 +250,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
|
||||
goto __error1;
|
||||
}
|
||||
if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK))
|
||||
down(&rmidi->open_mutex);
|
||||
mutex_lock(&rmidi->open_mutex);
|
||||
if (mode & SNDRV_RAWMIDI_LFLG_INPUT) {
|
||||
if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT)) {
|
||||
err = -ENXIO;
|
||||
@ -359,7 +360,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
|
||||
soutput = NULL;
|
||||
}
|
||||
if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK))
|
||||
up(&rmidi->open_mutex);
|
||||
mutex_unlock(&rmidi->open_mutex);
|
||||
if (rfile) {
|
||||
rfile->rmidi = rmidi;
|
||||
rfile->input = sinput;
|
||||
@ -374,7 +375,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
|
||||
snd_rawmidi_runtime_free(soutput);
|
||||
module_put(rmidi->card->module);
|
||||
if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK))
|
||||
up(&rmidi->open_mutex);
|
||||
mutex_unlock(&rmidi->open_mutex);
|
||||
__error1:
|
||||
return err;
|
||||
}
|
||||
@ -422,7 +423,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
|
||||
}
|
||||
init_waitqueue_entry(&wait, current);
|
||||
add_wait_queue(&rmidi->open_wait, &wait);
|
||||
down(&rmidi->open_mutex);
|
||||
mutex_lock(&rmidi->open_mutex);
|
||||
while (1) {
|
||||
subdevice = -1;
|
||||
down_read(&card->controls_rwsem);
|
||||
@ -446,9 +447,9 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
|
||||
} else
|
||||
break;
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
up(&rmidi->open_mutex);
|
||||
mutex_unlock(&rmidi->open_mutex);
|
||||
schedule();
|
||||
down(&rmidi->open_mutex);
|
||||
mutex_lock(&rmidi->open_mutex);
|
||||
if (signal_pending(current)) {
|
||||
err = -ERESTARTSYS;
|
||||
break;
|
||||
@ -467,7 +468,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
|
||||
snd_card_file_remove(card, file);
|
||||
kfree(rawmidi_file);
|
||||
}
|
||||
up(&rmidi->open_mutex);
|
||||
mutex_unlock(&rmidi->open_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -480,7 +481,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile)
|
||||
snd_assert(rfile != NULL, return -ENXIO);
|
||||
snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO);
|
||||
rmidi = rfile->rmidi;
|
||||
down(&rmidi->open_mutex);
|
||||
mutex_lock(&rmidi->open_mutex);
|
||||
if (rfile->input != NULL) {
|
||||
substream = rfile->input;
|
||||
rfile->input = NULL;
|
||||
@ -514,7 +515,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile)
|
||||
}
|
||||
rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened--;
|
||||
}
|
||||
up(&rmidi->open_mutex);
|
||||
mutex_unlock(&rmidi->open_mutex);
|
||||
module_put(rmidi->card->module);
|
||||
return 0;
|
||||
}
|
||||
@ -576,9 +577,9 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info
|
||||
struct snd_rawmidi_substream *substream;
|
||||
struct list_head *list;
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
rmidi = snd_rawmidi_search(card, info->device);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (!rmidi)
|
||||
return -ENXIO;
|
||||
if (info->stream < 0 || info->stream > 1)
|
||||
@ -818,7 +819,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
|
||||
|
||||
if (get_user(device, (int __user *)argp))
|
||||
return -EFAULT;
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
device = device < 0 ? 0 : device + 1;
|
||||
while (device < SNDRV_RAWMIDI_DEVICES) {
|
||||
if (snd_rawmidi_search(card, device))
|
||||
@ -827,7 +828,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
|
||||
}
|
||||
if (device == SNDRV_RAWMIDI_DEVICES)
|
||||
device = -1;
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (put_user(device, (int __user *)argp))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
@ -1314,7 +1315,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
|
||||
|
||||
rmidi = entry->private_data;
|
||||
snd_iprintf(buffer, "%s\n\n", rmidi->name);
|
||||
down(&rmidi->open_mutex);
|
||||
mutex_lock(&rmidi->open_mutex);
|
||||
if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) {
|
||||
list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
|
||||
substream = list_entry(list, struct snd_rawmidi_substream, list);
|
||||
@ -1355,7 +1356,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
|
||||
}
|
||||
}
|
||||
}
|
||||
up(&rmidi->open_mutex);
|
||||
mutex_unlock(&rmidi->open_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1436,7 +1437,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device,
|
||||
}
|
||||
rmidi->card = card;
|
||||
rmidi->device = device;
|
||||
init_MUTEX(&rmidi->open_mutex);
|
||||
mutex_init(&rmidi->open_mutex);
|
||||
init_waitqueue_head(&rmidi->open_wait);
|
||||
if (id != NULL)
|
||||
strlcpy(rmidi->id, id, sizeof(rmidi->id));
|
||||
@ -1507,9 +1508,9 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
|
||||
|
||||
if (rmidi->device >= SNDRV_RAWMIDI_DEVICES)
|
||||
return -ENOMEM;
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
if (snd_rawmidi_search(rmidi->card, rmidi->device)) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
list_add_tail(&rmidi->list, &snd_rawmidi_devices);
|
||||
@ -1519,14 +1520,14 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
|
||||
&snd_rawmidi_f_ops, rmidi, name)) < 0) {
|
||||
snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device);
|
||||
list_del(&rmidi->list);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
}
|
||||
if (rmidi->ops && rmidi->ops->dev_register &&
|
||||
(err = rmidi->ops->dev_register(rmidi)) < 0) {
|
||||
snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
|
||||
list_del(&rmidi->list);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
}
|
||||
#ifdef CONFIG_SND_OSSEMUL
|
||||
@ -1553,7 +1554,7 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_SND_OSSEMUL */
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
sprintf(name, "midi%d", rmidi->device);
|
||||
entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
|
||||
if (entry) {
|
||||
@ -1583,9 +1584,9 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device)
|
||||
{
|
||||
struct snd_rawmidi *rmidi = device->device_data;
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
list_del_init(&rmidi->list);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1594,7 +1595,7 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device)
|
||||
struct snd_rawmidi *rmidi = device->device_data;
|
||||
|
||||
snd_assert(rmidi != NULL, return -ENXIO);
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
list_del(&rmidi->list);
|
||||
if (rmidi->proc_entry) {
|
||||
snd_info_unregister(rmidi->proc_entry);
|
||||
@ -1616,7 +1617,7 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device)
|
||||
if (rmidi->ops && rmidi->ops->dev_unregister)
|
||||
rmidi->ops->dev_unregister(rmidi);
|
||||
snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
|
||||
if (rmidi->seq_dev) {
|
||||
snd_device_free(rmidi->card, rmidi->seq_dev);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/minors.h>
|
||||
#include <sound/initval.h>
|
||||
@ -124,7 +125,7 @@ module_exit(alsa_seq_oss_exit)
|
||||
* ALSA minor device interface
|
||||
*/
|
||||
|
||||
static DECLARE_MUTEX(register_mutex);
|
||||
static DEFINE_MUTEX(register_mutex);
|
||||
|
||||
static int
|
||||
odev_open(struct inode *inode, struct file *file)
|
||||
@ -136,9 +137,9 @@ odev_open(struct inode *inode, struct file *file)
|
||||
else
|
||||
level = SNDRV_SEQ_OSS_MODE_SYNTH;
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
rc = snd_seq_oss_open(file, level);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -153,9 +154,9 @@ odev_release(struct inode *inode, struct file *file)
|
||||
|
||||
snd_seq_oss_drain_write(dp);
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
snd_seq_oss_release(dp);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -224,13 +225,13 @@ register_device(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER,
|
||||
NULL, 0,
|
||||
&seq_oss_f_ops, NULL,
|
||||
SNDRV_SEQ_OSS_DEVNAME)) < 0) {
|
||||
snd_printk(KERN_ERR "can't register device seq\n");
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return rc;
|
||||
}
|
||||
if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC,
|
||||
@ -239,24 +240,24 @@ register_device(void)
|
||||
SNDRV_SEQ_OSS_DEVNAME)) < 0) {
|
||||
snd_printk(KERN_ERR "can't register device music\n");
|
||||
snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return rc;
|
||||
}
|
||||
debug_printk(("device registered\n"));
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
unregister_device(void)
|
||||
{
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
debug_printk(("device unregistered\n"));
|
||||
if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0)
|
||||
snd_printk(KERN_ERR "error unregister device music\n");
|
||||
if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0)
|
||||
snd_printk(KERN_ERR "error unregister device seq\n");
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -270,12 +271,12 @@ static struct snd_info_entry *info_entry;
|
||||
static void
|
||||
info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf)
|
||||
{
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR);
|
||||
snd_seq_oss_system_info_read(buf);
|
||||
snd_seq_oss_synth_info_read(buf);
|
||||
snd_seq_oss_midi_info_read(buf);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,7 +67,7 @@
|
||||
#define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT)
|
||||
|
||||
static DEFINE_SPINLOCK(clients_lock);
|
||||
static DECLARE_MUTEX(register_mutex);
|
||||
static DEFINE_MUTEX(register_mutex);
|
||||
|
||||
/*
|
||||
* client table
|
||||
@ -237,7 +237,7 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize)
|
||||
client->type = NO_CLIENT;
|
||||
snd_use_lock_init(&client->use_lock);
|
||||
rwlock_init(&client->ports_lock);
|
||||
init_MUTEX(&client->ports_mutex);
|
||||
mutex_init(&client->ports_mutex);
|
||||
INIT_LIST_HEAD(&client->ports_list_head);
|
||||
|
||||
/* find free slot in the client table */
|
||||
@ -290,7 +290,7 @@ static int seq_free_client1(struct snd_seq_client *client)
|
||||
|
||||
static void seq_free_client(struct snd_seq_client * client)
|
||||
{
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
switch (client->type) {
|
||||
case NO_CLIENT:
|
||||
snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n",
|
||||
@ -306,7 +306,7 @@ static void seq_free_client(struct snd_seq_client * client)
|
||||
snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n",
|
||||
client->number, client->type);
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
|
||||
snd_seq_system_client_ev_client_exit(client->number);
|
||||
}
|
||||
@ -322,11 +322,11 @@ static int snd_seq_open(struct inode *inode, struct file *file)
|
||||
struct snd_seq_client *client;
|
||||
struct snd_seq_user_client *user;
|
||||
|
||||
if (down_interruptible(®ister_mutex))
|
||||
if (mutex_lock_interruptible(®ister_mutex))
|
||||
return -ERESTARTSYS;
|
||||
client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS);
|
||||
if (client == NULL) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -ENOMEM; /* failure code */
|
||||
}
|
||||
|
||||
@ -346,14 +346,14 @@ static int snd_seq_open(struct inode *inode, struct file *file)
|
||||
if (user->fifo == NULL) {
|
||||
seq_free_client1(client);
|
||||
kfree(client);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
usage_alloc(&client_usage, 1);
|
||||
client->type = USER_CLIENT;
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
|
||||
c = client->number;
|
||||
file->private_data = client;
|
||||
@ -1743,7 +1743,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
|
||||
if (queue == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (down_interruptible(&queue->timer_mutex)) {
|
||||
if (mutex_lock_interruptible(&queue->timer_mutex)) {
|
||||
queuefree(queue);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
@ -1756,7 +1756,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
|
||||
timer.u.alsa.id = tmr->alsa_id;
|
||||
timer.u.alsa.resolution = tmr->preferred_resolution;
|
||||
}
|
||||
up(&queue->timer_mutex);
|
||||
mutex_unlock(&queue->timer_mutex);
|
||||
queuefree(queue);
|
||||
|
||||
if (copy_to_user(arg, &timer, sizeof(timer)))
|
||||
@ -1785,7 +1785,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
|
||||
q = queueptr(timer.queue);
|
||||
if (q == NULL)
|
||||
return -ENXIO;
|
||||
if (down_interruptible(&q->timer_mutex)) {
|
||||
if (mutex_lock_interruptible(&q->timer_mutex)) {
|
||||
queuefree(q);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
@ -1797,7 +1797,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
|
||||
tmr->preferred_resolution = timer.u.alsa.resolution;
|
||||
}
|
||||
result = snd_seq_queue_timer_open(timer.queue);
|
||||
up(&q->timer_mutex);
|
||||
mutex_unlock(&q->timer_mutex);
|
||||
queuefree(q);
|
||||
} else {
|
||||
return -EPERM;
|
||||
@ -1866,8 +1866,7 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
|
||||
info.output_pool = cptr->pool->size;
|
||||
info.output_room = cptr->pool->room;
|
||||
info.output_free = info.output_pool;
|
||||
if (cptr->pool)
|
||||
info.output_free = snd_seq_unused_cells(cptr->pool);
|
||||
info.output_free = snd_seq_unused_cells(cptr->pool);
|
||||
if (cptr->type == USER_CLIENT) {
|
||||
info.input_pool = cptr->data.user.fifo_pool_size;
|
||||
info.input_free = info.input_pool;
|
||||
@ -2230,7 +2229,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
|
||||
if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS)
|
||||
return -EINVAL;
|
||||
|
||||
if (down_interruptible(®ister_mutex))
|
||||
if (mutex_lock_interruptible(®ister_mutex))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (card) {
|
||||
@ -2243,7 +2242,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
|
||||
/* empty write queue as default */
|
||||
client = seq_create_client1(client_index, 0);
|
||||
if (client == NULL) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -EBUSY; /* failure code */
|
||||
}
|
||||
usage_alloc(&client_usage, 1);
|
||||
@ -2256,7 +2255,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
|
||||
va_end(args);
|
||||
|
||||
client->type = KERNEL_CLIENT;
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
|
||||
/* make others aware this new client */
|
||||
snd_seq_system_client_ev_client_start(client->number);
|
||||
@ -2464,7 +2463,7 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
|
||||
{
|
||||
struct list_head *l;
|
||||
|
||||
down(&client->ports_mutex);
|
||||
mutex_lock(&client->ports_mutex);
|
||||
list_for_each(l, &client->ports_list_head) {
|
||||
struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list);
|
||||
snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c)\n",
|
||||
@ -2476,7 +2475,7 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
|
||||
snd_seq_info_dump_subscribers(buffer, &p->c_src, 1, " Connecting To: ");
|
||||
snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: ");
|
||||
}
|
||||
up(&client->ports_mutex);
|
||||
mutex_unlock(&client->ports_mutex);
|
||||
}
|
||||
|
||||
|
||||
@ -2550,16 +2549,16 @@ int __init snd_sequencer_device_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (down_interruptible(®ister_mutex))
|
||||
if (mutex_lock_interruptible(®ister_mutex))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0,
|
||||
&snd_seq_f_ops, NULL, "seq")) < 0) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ struct snd_seq_client {
|
||||
int num_ports; /* number of ports */
|
||||
struct list_head ports_list_head;
|
||||
rwlock_t ports_lock;
|
||||
struct semaphore ports_mutex;
|
||||
struct mutex ports_mutex;
|
||||
int convert32; /* convert 32->64bit */
|
||||
|
||||
/* output pool */
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <sound/initval.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
|
||||
MODULE_DESCRIPTION("ALSA sequencer device management");
|
||||
@ -69,7 +70,7 @@ struct ops_list {
|
||||
struct list_head dev_list; /* list of devices */
|
||||
int num_devices; /* number of associated devices */
|
||||
int num_init_devices; /* number of initialized devices */
|
||||
struct semaphore reg_mutex;
|
||||
struct mutex reg_mutex;
|
||||
|
||||
struct list_head list; /* next driver */
|
||||
};
|
||||
@ -77,7 +78,7 @@ struct ops_list {
|
||||
|
||||
static LIST_HEAD(opslist);
|
||||
static int num_ops;
|
||||
static DECLARE_MUTEX(ops_mutex);
|
||||
static DEFINE_MUTEX(ops_mutex);
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static struct snd_info_entry *info_entry = NULL;
|
||||
#endif
|
||||
@ -108,7 +109,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry,
|
||||
{
|
||||
struct list_head *head;
|
||||
|
||||
down(&ops_mutex);
|
||||
mutex_lock(&ops_mutex);
|
||||
list_for_each(head, &opslist) {
|
||||
struct ops_list *ops = list_entry(head, struct ops_list, list);
|
||||
snd_iprintf(buffer, "snd-%s%s%s%s,%d\n",
|
||||
@ -118,7 +119,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry,
|
||||
ops->driver & DRIVER_LOCKED ? ",locked" : "",
|
||||
ops->num_devices);
|
||||
}
|
||||
up(&ops_mutex);
|
||||
mutex_unlock(&ops_mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -154,20 +155,20 @@ void snd_seq_device_load_drivers(void)
|
||||
if (! current->fs->root)
|
||||
return;
|
||||
|
||||
down(&ops_mutex);
|
||||
mutex_lock(&ops_mutex);
|
||||
list_for_each(head, &opslist) {
|
||||
struct ops_list *ops = list_entry(head, struct ops_list, list);
|
||||
if (! (ops->driver & DRIVER_LOADED) &&
|
||||
! (ops->driver & DRIVER_REQUESTED)) {
|
||||
ops->used++;
|
||||
up(&ops_mutex);
|
||||
mutex_unlock(&ops_mutex);
|
||||
ops->driver |= DRIVER_REQUESTED;
|
||||
request_module("snd-%s", ops->id);
|
||||
down(&ops_mutex);
|
||||
mutex_lock(&ops_mutex);
|
||||
ops->used--;
|
||||
}
|
||||
}
|
||||
up(&ops_mutex);
|
||||
mutex_unlock(&ops_mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -214,10 +215,10 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize,
|
||||
dev->status = SNDRV_SEQ_DEVICE_FREE;
|
||||
|
||||
/* add this device to the list */
|
||||
down(&ops->reg_mutex);
|
||||
mutex_lock(&ops->reg_mutex);
|
||||
list_add_tail(&dev->list, &ops->dev_list);
|
||||
ops->num_devices++;
|
||||
up(&ops->reg_mutex);
|
||||
mutex_unlock(&ops->reg_mutex);
|
||||
|
||||
unlock_driver(ops);
|
||||
|
||||
@ -246,10 +247,10 @@ static int snd_seq_device_free(struct snd_seq_device *dev)
|
||||
return -ENXIO;
|
||||
|
||||
/* remove the device from the list */
|
||||
down(&ops->reg_mutex);
|
||||
mutex_lock(&ops->reg_mutex);
|
||||
list_del(&dev->list);
|
||||
ops->num_devices--;
|
||||
up(&ops->reg_mutex);
|
||||
mutex_unlock(&ops->reg_mutex);
|
||||
|
||||
free_device(dev, ops);
|
||||
if (dev->private_free)
|
||||
@ -344,7 +345,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
down(&ops->reg_mutex);
|
||||
mutex_lock(&ops->reg_mutex);
|
||||
/* copy driver operators */
|
||||
ops->ops = *entry;
|
||||
ops->driver |= DRIVER_LOADED;
|
||||
@ -355,7 +356,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
|
||||
struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list);
|
||||
init_device(dev, ops);
|
||||
}
|
||||
up(&ops->reg_mutex);
|
||||
mutex_unlock(&ops->reg_mutex);
|
||||
|
||||
unlock_driver(ops);
|
||||
snd_seq_autoload_unlock();
|
||||
@ -378,17 +379,17 @@ static struct ops_list * create_driver(char *id)
|
||||
|
||||
/* set up driver entry */
|
||||
strlcpy(ops->id, id, sizeof(ops->id));
|
||||
init_MUTEX(&ops->reg_mutex);
|
||||
mutex_init(&ops->reg_mutex);
|
||||
ops->driver = DRIVER_EMPTY;
|
||||
INIT_LIST_HEAD(&ops->dev_list);
|
||||
/* lock this instance */
|
||||
ops->used = 1;
|
||||
|
||||
/* register driver entry */
|
||||
down(&ops_mutex);
|
||||
mutex_lock(&ops_mutex);
|
||||
list_add_tail(&ops->list, &opslist);
|
||||
num_ops++;
|
||||
up(&ops_mutex);
|
||||
mutex_unlock(&ops_mutex);
|
||||
|
||||
return ops;
|
||||
}
|
||||
@ -414,7 +415,7 @@ int snd_seq_device_unregister_driver(char *id)
|
||||
}
|
||||
|
||||
/* close and release all devices associated with this driver */
|
||||
down(&ops->reg_mutex);
|
||||
mutex_lock(&ops->reg_mutex);
|
||||
ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */
|
||||
list_for_each(head, &ops->dev_list) {
|
||||
struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list);
|
||||
@ -425,7 +426,7 @@ int snd_seq_device_unregister_driver(char *id)
|
||||
if (ops->num_init_devices > 0)
|
||||
snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n",
|
||||
ops->num_init_devices);
|
||||
up(&ops->reg_mutex);
|
||||
mutex_unlock(&ops->reg_mutex);
|
||||
|
||||
unlock_driver(ops);
|
||||
|
||||
@ -443,7 +444,7 @@ static void remove_drivers(void)
|
||||
{
|
||||
struct list_head *head;
|
||||
|
||||
down(&ops_mutex);
|
||||
mutex_lock(&ops_mutex);
|
||||
head = opslist.next;
|
||||
while (head != &opslist) {
|
||||
struct ops_list *ops = list_entry(head, struct ops_list, list);
|
||||
@ -456,7 +457,7 @@ static void remove_drivers(void)
|
||||
} else
|
||||
head = head->next;
|
||||
}
|
||||
up(&ops_mutex);
|
||||
mutex_unlock(&ops_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -519,16 +520,16 @@ static struct ops_list * find_driver(char *id, int create_if_empty)
|
||||
{
|
||||
struct list_head *head;
|
||||
|
||||
down(&ops_mutex);
|
||||
mutex_lock(&ops_mutex);
|
||||
list_for_each(head, &opslist) {
|
||||
struct ops_list *ops = list_entry(head, struct ops_list, list);
|
||||
if (strcmp(ops->id, id) == 0) {
|
||||
ops->used++;
|
||||
up(&ops_mutex);
|
||||
mutex_unlock(&ops_mutex);
|
||||
return ops;
|
||||
}
|
||||
}
|
||||
up(&ops_mutex);
|
||||
mutex_unlock(&ops_mutex);
|
||||
if (create_if_empty)
|
||||
return create_driver(id);
|
||||
return NULL;
|
||||
@ -536,9 +537,9 @@ static struct ops_list * find_driver(char *id, int create_if_empty)
|
||||
|
||||
static void unlock_driver(struct ops_list *ops)
|
||||
{
|
||||
down(&ops_mutex);
|
||||
mutex_lock(&ops_mutex);
|
||||
ops->used--;
|
||||
up(&ops_mutex);
|
||||
mutex_unlock(&ops_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,7 +36,7 @@ static void snd_instr_lock_ops(struct snd_seq_kinstr_list *list)
|
||||
if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) {
|
||||
spin_lock_irqsave(&list->ops_lock, list->ops_flags);
|
||||
} else {
|
||||
down(&list->ops_mutex);
|
||||
mutex_lock(&list->ops_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ static void snd_instr_unlock_ops(struct snd_seq_kinstr_list *list)
|
||||
if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) {
|
||||
spin_unlock_irqrestore(&list->ops_lock, list->ops_flags);
|
||||
} else {
|
||||
up(&list->ops_mutex);
|
||||
mutex_unlock(&list->ops_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ struct snd_seq_kinstr_list *snd_seq_instr_list_new(void)
|
||||
return NULL;
|
||||
spin_lock_init(&list->lock);
|
||||
spin_lock_init(&list->ops_lock);
|
||||
init_MUTEX(&list->ops_mutex);
|
||||
mutex_init(&list->ops_mutex);
|
||||
list->owner = -1;
|
||||
return list;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ Possible options for midisynth module:
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/rawmidi.h>
|
||||
#include <sound/seq_kernel.h>
|
||||
@ -70,7 +70,7 @@ struct seq_midisynth_client {
|
||||
};
|
||||
|
||||
static struct seq_midisynth_client *synths[SNDRV_CARDS];
|
||||
static DECLARE_MUTEX(register_mutex);
|
||||
static DEFINE_MUTEX(register_mutex);
|
||||
|
||||
/* handle rawmidi input event (MIDI v1.0 stream) */
|
||||
static void snd_midi_input_event(struct snd_rawmidi_substream *substream)
|
||||
@ -308,13 +308,13 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
|
||||
if (ports > (256 / SNDRV_RAWMIDI_DEVICES))
|
||||
ports = 256 / SNDRV_RAWMIDI_DEVICES;
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
client = synths[card->number];
|
||||
if (client == NULL) {
|
||||
newclient = 1;
|
||||
client = kzalloc(sizeof(*client), GFP_KERNEL);
|
||||
if (client == NULL) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
kfree(info);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -324,7 +324,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
|
||||
(const char *)info->name : "External MIDI");
|
||||
if (client->seq_client < 0) {
|
||||
kfree(client);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
kfree(info);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -397,7 +397,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
|
||||
client->num_ports++;
|
||||
if (newclient)
|
||||
synths[card->number] = client;
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
kfree(info);
|
||||
kfree(port);
|
||||
return 0; /* success */
|
||||
@ -414,7 +414,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
|
||||
}
|
||||
kfree(info);
|
||||
kfree(port);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -427,10 +427,10 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev)
|
||||
struct snd_card *card = dev->card;
|
||||
int device = dev->device, p, ports;
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
client = synths[card->number];
|
||||
if (client == NULL || client->ports[device] == NULL) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
ports = client->ports_per_device[device];
|
||||
@ -446,7 +446,7 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev)
|
||||
synths[card->number] = NULL;
|
||||
kfree(client);
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
|
||||
port_subs_info_init(&new_port->c_dest);
|
||||
|
||||
num = port >= 0 ? port : 0;
|
||||
down(&client->ports_mutex);
|
||||
mutex_lock(&client->ports_mutex);
|
||||
write_lock_irqsave(&client->ports_lock, flags);
|
||||
list_for_each(l, &client->ports_list_head) {
|
||||
struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list);
|
||||
@ -173,7 +173,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
|
||||
client->num_ports++;
|
||||
new_port->addr.port = num; /* store the port number in the port */
|
||||
write_unlock_irqrestore(&client->ports_lock, flags);
|
||||
up(&client->ports_mutex);
|
||||
mutex_unlock(&client->ports_mutex);
|
||||
sprintf(new_port->name, "port-%d", num);
|
||||
|
||||
return new_port;
|
||||
@ -292,7 +292,7 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port)
|
||||
struct list_head *l;
|
||||
struct snd_seq_client_port *found = NULL;
|
||||
|
||||
down(&client->ports_mutex);
|
||||
mutex_lock(&client->ports_mutex);
|
||||
write_lock_irqsave(&client->ports_lock, flags);
|
||||
list_for_each(l, &client->ports_list_head) {
|
||||
struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list);
|
||||
@ -305,7 +305,7 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port)
|
||||
}
|
||||
}
|
||||
write_unlock_irqrestore(&client->ports_lock, flags);
|
||||
up(&client->ports_mutex);
|
||||
mutex_unlock(&client->ports_mutex);
|
||||
if (found)
|
||||
return port_delete(client, found);
|
||||
else
|
||||
@ -321,7 +321,7 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client)
|
||||
/* move the port list to deleted_list, and
|
||||
* clear the port list in the client data.
|
||||
*/
|
||||
down(&client->ports_mutex);
|
||||
mutex_lock(&client->ports_mutex);
|
||||
write_lock_irqsave(&client->ports_lock, flags);
|
||||
if (! list_empty(&client->ports_list_head)) {
|
||||
__list_add(&deleted_list,
|
||||
@ -341,7 +341,7 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client)
|
||||
snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port);
|
||||
port_delete(client, port);
|
||||
}
|
||||
up(&client->ports_mutex);
|
||||
mutex_unlock(&client->ports_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ static struct snd_seq_queue *queue_new(int owner, int locked)
|
||||
|
||||
spin_lock_init(&q->owner_lock);
|
||||
spin_lock_init(&q->check_lock);
|
||||
init_MUTEX(&q->timer_mutex);
|
||||
mutex_init(&q->timer_mutex);
|
||||
snd_use_lock_init(&q->use_lock);
|
||||
q->queue = -1;
|
||||
|
||||
@ -516,7 +516,7 @@ int snd_seq_queue_use(int queueid, int client, int use)
|
||||
queue = queueptr(queueid);
|
||||
if (queue == NULL)
|
||||
return -EINVAL;
|
||||
down(&queue->timer_mutex);
|
||||
mutex_lock(&queue->timer_mutex);
|
||||
if (use) {
|
||||
if (!test_and_set_bit(client, queue->clients_bitmap))
|
||||
queue->clients++;
|
||||
@ -531,7 +531,7 @@ int snd_seq_queue_use(int queueid, int client, int use)
|
||||
} else {
|
||||
snd_seq_timer_close(queue);
|
||||
}
|
||||
up(&queue->timer_mutex);
|
||||
mutex_unlock(&queue->timer_mutex);
|
||||
queuefree(queue);
|
||||
return 0;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ struct snd_seq_queue {
|
||||
/* clients which uses this queue (bitmap) */
|
||||
DECLARE_BITMAP(clients_bitmap, SNDRV_SEQ_MAX_CLIENTS);
|
||||
unsigned int clients; /* users of this queue */
|
||||
struct semaphore timer_mutex;
|
||||
struct mutex timer_mutex;
|
||||
|
||||
snd_use_lock_t use_lock;
|
||||
};
|
||||
|
@ -167,7 +167,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
|
||||
return; /* ignored */
|
||||
}
|
||||
if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
|
||||
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0)
|
||||
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
|
||||
return;
|
||||
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
|
||||
}
|
||||
@ -186,7 +186,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
|
||||
pbuf += res;
|
||||
count -= res;
|
||||
if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
|
||||
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0)
|
||||
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
|
||||
return;
|
||||
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <sound/initval.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/devfs_fs_kernel.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#define SNDRV_OS_MINORS 256
|
||||
|
||||
@ -61,7 +62,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
|
||||
int snd_ecards_limit;
|
||||
|
||||
static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
|
||||
static DECLARE_MUTEX(sound_mutex);
|
||||
static DEFINE_MUTEX(sound_mutex);
|
||||
|
||||
extern struct class *sound_class;
|
||||
|
||||
@ -120,15 +121,15 @@ void *snd_lookup_minor_data(unsigned int minor, int type)
|
||||
struct snd_minor *mreg;
|
||||
void *private_data;
|
||||
|
||||
if (minor > ARRAY_SIZE(snd_minors))
|
||||
if (minor >= ARRAY_SIZE(snd_minors))
|
||||
return NULL;
|
||||
down(&sound_mutex);
|
||||
mutex_lock(&sound_mutex);
|
||||
mreg = snd_minors[minor];
|
||||
if (mreg && mreg->type == type)
|
||||
private_data = mreg->private_data;
|
||||
else
|
||||
private_data = NULL;
|
||||
up(&sound_mutex);
|
||||
mutex_unlock(&sound_mutex);
|
||||
return private_data;
|
||||
}
|
||||
|
||||
@ -139,7 +140,7 @@ static int snd_open(struct inode *inode, struct file *file)
|
||||
struct file_operations *old_fops;
|
||||
int err = 0;
|
||||
|
||||
if (minor > ARRAY_SIZE(snd_minors))
|
||||
if (minor >= ARRAY_SIZE(snd_minors))
|
||||
return -ENODEV;
|
||||
mptr = snd_minors[minor];
|
||||
if (mptr == NULL) {
|
||||
@ -256,7 +257,7 @@ int snd_register_device(int type, struct snd_card *card, int dev,
|
||||
preg->f_ops = f_ops;
|
||||
preg->private_data = private_data;
|
||||
strcpy(preg->name, name);
|
||||
down(&sound_mutex);
|
||||
mutex_lock(&sound_mutex);
|
||||
#ifdef CONFIG_SND_DYNAMIC_MINORS
|
||||
minor = snd_find_free_minor();
|
||||
#else
|
||||
@ -265,7 +266,7 @@ int snd_register_device(int type, struct snd_card *card, int dev,
|
||||
minor = -EBUSY;
|
||||
#endif
|
||||
if (minor < 0) {
|
||||
up(&sound_mutex);
|
||||
mutex_unlock(&sound_mutex);
|
||||
kfree(preg);
|
||||
return minor;
|
||||
}
|
||||
@ -276,7 +277,7 @@ int snd_register_device(int type, struct snd_card *card, int dev,
|
||||
device = card->dev;
|
||||
class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name);
|
||||
|
||||
up(&sound_mutex);
|
||||
mutex_unlock(&sound_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -297,7 +298,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
|
||||
struct snd_minor *mptr;
|
||||
|
||||
cardnum = card ? card->number : -1;
|
||||
down(&sound_mutex);
|
||||
mutex_lock(&sound_mutex);
|
||||
for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor)
|
||||
if ((mptr = snd_minors[minor]) != NULL &&
|
||||
mptr->type == type &&
|
||||
@ -305,7 +306,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
|
||||
mptr->device == dev)
|
||||
break;
|
||||
if (minor == ARRAY_SIZE(snd_minors)) {
|
||||
up(&sound_mutex);
|
||||
mutex_unlock(&sound_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -315,7 +316,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
|
||||
class_device_destroy(sound_class, MKDEV(major, minor));
|
||||
|
||||
snd_minors[minor] = NULL;
|
||||
up(&sound_mutex);
|
||||
mutex_unlock(&sound_mutex);
|
||||
kfree(mptr);
|
||||
return 0;
|
||||
}
|
||||
@ -354,7 +355,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu
|
||||
int minor;
|
||||
struct snd_minor *mptr;
|
||||
|
||||
down(&sound_mutex);
|
||||
mutex_lock(&sound_mutex);
|
||||
for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) {
|
||||
if (!(mptr = snd_minors[minor]))
|
||||
continue;
|
||||
@ -371,7 +372,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu
|
||||
snd_iprintf(buffer, "%3i: : %s\n", minor,
|
||||
snd_device_type_name(mptr->type));
|
||||
}
|
||||
up(&sound_mutex);
|
||||
mutex_unlock(&sound_mutex);
|
||||
}
|
||||
|
||||
int __init snd_minor_info_init(void)
|
||||
|
@ -34,26 +34,27 @@
|
||||
#include <sound/minors.h>
|
||||
#include <sound/info.h>
|
||||
#include <linux/sound.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#define SNDRV_OSS_MINORS 128
|
||||
|
||||
static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
|
||||
static DECLARE_MUTEX(sound_oss_mutex);
|
||||
static DEFINE_MUTEX(sound_oss_mutex);
|
||||
|
||||
void *snd_lookup_oss_minor_data(unsigned int minor, int type)
|
||||
{
|
||||
struct snd_minor *mreg;
|
||||
void *private_data;
|
||||
|
||||
if (minor > ARRAY_SIZE(snd_oss_minors))
|
||||
if (minor >= ARRAY_SIZE(snd_oss_minors))
|
||||
return NULL;
|
||||
down(&sound_oss_mutex);
|
||||
mutex_lock(&sound_oss_mutex);
|
||||
mreg = snd_oss_minors[minor];
|
||||
if (mreg && mreg->type == type)
|
||||
private_data = mreg->private_data;
|
||||
else
|
||||
private_data = NULL;
|
||||
up(&sound_oss_mutex);
|
||||
mutex_unlock(&sound_oss_mutex);
|
||||
return private_data;
|
||||
}
|
||||
|
||||
@ -117,7 +118,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
|
||||
preg->device = dev;
|
||||
preg->f_ops = f_ops;
|
||||
preg->private_data = private_data;
|
||||
down(&sound_oss_mutex);
|
||||
mutex_lock(&sound_oss_mutex);
|
||||
snd_oss_minors[minor] = preg;
|
||||
minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
|
||||
switch (minor_unit) {
|
||||
@ -143,7 +144,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
|
||||
goto __end;
|
||||
snd_oss_minors[track2] = preg;
|
||||
}
|
||||
up(&sound_oss_mutex);
|
||||
mutex_unlock(&sound_oss_mutex);
|
||||
return 0;
|
||||
|
||||
__end:
|
||||
@ -152,7 +153,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
|
||||
if (register1 >= 0)
|
||||
unregister_sound_special(register1);
|
||||
snd_oss_minors[minor] = NULL;
|
||||
up(&sound_oss_mutex);
|
||||
mutex_unlock(&sound_oss_mutex);
|
||||
kfree(preg);
|
||||
return -EBUSY;
|
||||
}
|
||||
@ -168,10 +169,10 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
|
||||
return 0;
|
||||
if (minor < 0)
|
||||
return minor;
|
||||
down(&sound_oss_mutex);
|
||||
mutex_lock(&sound_oss_mutex);
|
||||
mptr = snd_oss_minors[minor];
|
||||
if (mptr == NULL) {
|
||||
up(&sound_oss_mutex);
|
||||
mutex_unlock(&sound_oss_mutex);
|
||||
return -ENOENT;
|
||||
}
|
||||
unregister_sound_special(minor);
|
||||
@ -191,7 +192,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
|
||||
snd_oss_minors[track2] = NULL;
|
||||
}
|
||||
snd_oss_minors[minor] = NULL;
|
||||
up(&sound_oss_mutex);
|
||||
mutex_unlock(&sound_oss_mutex);
|
||||
kfree(mptr);
|
||||
return 0;
|
||||
}
|
||||
@ -229,7 +230,7 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry,
|
||||
int minor;
|
||||
struct snd_minor *mptr;
|
||||
|
||||
down(&sound_oss_mutex);
|
||||
mutex_lock(&sound_oss_mutex);
|
||||
for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) {
|
||||
if (!(mptr = snd_oss_minors[minor]))
|
||||
continue;
|
||||
@ -241,7 +242,7 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry,
|
||||
snd_iprintf(buffer, "%3i: : %s\n", minor,
|
||||
snd_oss_device_type_name(mptr->type));
|
||||
}
|
||||
up(&sound_oss_mutex);
|
||||
mutex_unlock(&sound_oss_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/string.h>
|
||||
#include <sound/core.h>
|
||||
@ -70,7 +71,7 @@ struct snd_timer_user {
|
||||
struct timespec tstamp; /* trigger tstamp */
|
||||
wait_queue_head_t qchange_sleep;
|
||||
struct fasync_struct *fasync;
|
||||
struct semaphore tread_sem;
|
||||
struct mutex tread_sem;
|
||||
};
|
||||
|
||||
/* list of timers */
|
||||
@ -82,7 +83,7 @@ static LIST_HEAD(snd_timer_slave_list);
|
||||
/* lock for slave active lists */
|
||||
static DEFINE_SPINLOCK(slave_active_lock);
|
||||
|
||||
static DECLARE_MUTEX(register_mutex);
|
||||
static DEFINE_MUTEX(register_mutex);
|
||||
|
||||
static int snd_timer_free(struct snd_timer *timer);
|
||||
static int snd_timer_dev_free(struct snd_device *device);
|
||||
@ -252,10 +253,10 @@ int snd_timer_open(struct snd_timer_instance **ti,
|
||||
snd_printd("invalid slave class %i\n", tid->dev_sclass);
|
||||
return -EINVAL;
|
||||
}
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
timeri = snd_timer_instance_new(owner, NULL);
|
||||
if (!timeri) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
timeri->slave_class = tid->dev_sclass;
|
||||
@ -263,37 +264,37 @@ int snd_timer_open(struct snd_timer_instance **ti,
|
||||
timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
|
||||
list_add_tail(&timeri->open_list, &snd_timer_slave_list);
|
||||
snd_timer_check_slave(timeri);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
*ti = timeri;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* open a master instance */
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
timer = snd_timer_find(tid);
|
||||
#ifdef CONFIG_KMOD
|
||||
if (timer == NULL) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
snd_timer_request(tid);
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
timer = snd_timer_find(tid);
|
||||
}
|
||||
#endif
|
||||
if (!timer) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!list_empty(&timer->open_list_head)) {
|
||||
timeri = list_entry(timer->open_list_head.next,
|
||||
struct snd_timer_instance, open_list);
|
||||
if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
timeri = snd_timer_instance_new(owner, timer);
|
||||
if (!timeri) {
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
timeri->slave_class = tid->dev_sclass;
|
||||
@ -302,7 +303,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
|
||||
timer->hw.open(timer);
|
||||
list_add_tail(&timeri->open_list, &timer->open_list_head);
|
||||
snd_timer_check_master(timeri);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
*ti = timeri;
|
||||
return 0;
|
||||
}
|
||||
@ -333,9 +334,9 @@ int snd_timer_close(struct snd_timer_instance *timeri)
|
||||
spin_lock_irq(&slave_active_lock);
|
||||
}
|
||||
spin_unlock_irq(&slave_active_lock);
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
list_del(&timeri->open_list);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
} else {
|
||||
timer = timeri->timer;
|
||||
/* wait, until the active callback is finished */
|
||||
@ -346,7 +347,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
|
||||
spin_lock_irq(&timer->lock);
|
||||
}
|
||||
spin_unlock_irq(&timer->lock);
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
list_del(&timeri->open_list);
|
||||
if (timer && list_empty(&timer->open_list_head) &&
|
||||
timer->hw.close)
|
||||
@ -362,7 +363,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
|
||||
slave->timer = NULL;
|
||||
spin_unlock_irq(&slave_active_lock);
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
}
|
||||
if (timeri->private_free)
|
||||
timeri->private_free(timeri);
|
||||
@ -835,7 +836,7 @@ static int snd_timer_dev_register(struct snd_device *dev)
|
||||
!timer->hw.resolution && timer->hw.c_resolution == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
list_for_each(p, &snd_timer_list) {
|
||||
timer1 = list_entry(p, struct snd_timer, device_list);
|
||||
if (timer1->tmr_class > timer->tmr_class)
|
||||
@ -857,11 +858,11 @@ static int snd_timer_dev_register(struct snd_device *dev)
|
||||
if (timer1->tmr_subdevice < timer->tmr_subdevice)
|
||||
continue;
|
||||
/* conflicts.. */
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
list_add_tail(&timer->device_list, p);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -871,7 +872,7 @@ static int snd_timer_unregister(struct snd_timer *timer)
|
||||
struct snd_timer_instance *ti;
|
||||
|
||||
snd_assert(timer != NULL, return -ENXIO);
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
if (! list_empty(&timer->open_list_head)) {
|
||||
snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer);
|
||||
list_for_each_safe(p, n, &timer->open_list_head) {
|
||||
@ -881,7 +882,7 @@ static int snd_timer_unregister(struct snd_timer *timer)
|
||||
}
|
||||
}
|
||||
list_del(&timer->device_list);
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return snd_timer_free(timer);
|
||||
}
|
||||
|
||||
@ -1065,7 +1066,7 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
|
||||
struct snd_timer_instance *ti;
|
||||
struct list_head *p, *q;
|
||||
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
list_for_each(p, &snd_timer_list) {
|
||||
timer = list_entry(p, struct snd_timer, device_list);
|
||||
switch (timer->tmr_class) {
|
||||
@ -1105,7 +1106,7 @@ static void snd_timer_proc_read(struct snd_info_entry *entry,
|
||||
}
|
||||
spin_unlock_irqrestore(&timer->lock, flags);
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
}
|
||||
|
||||
static struct snd_info_entry *snd_timer_proc_entry = NULL;
|
||||
@ -1269,7 +1270,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
|
||||
return -ENOMEM;
|
||||
spin_lock_init(&tu->qlock);
|
||||
init_waitqueue_head(&tu->qchange_sleep);
|
||||
init_MUTEX(&tu->tread_sem);
|
||||
mutex_init(&tu->tread_sem);
|
||||
tu->ticks = 1;
|
||||
tu->queue_size = 128;
|
||||
tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
|
||||
@ -1325,7 +1326,7 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
|
||||
|
||||
if (copy_from_user(&id, _tid, sizeof(id)))
|
||||
return -EFAULT;
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
if (id.dev_class < 0) { /* first item */
|
||||
if (list_empty(&snd_timer_list))
|
||||
snd_timer_user_zero_id(&id);
|
||||
@ -1407,7 +1408,7 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
|
||||
snd_timer_user_zero_id(&id);
|
||||
}
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (copy_to_user(_tid, &id, sizeof(*_tid)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
@ -1432,7 +1433,7 @@ static int snd_timer_user_ginfo(struct file *file,
|
||||
tid = ginfo->tid;
|
||||
memset(ginfo, 0, sizeof(*ginfo));
|
||||
ginfo->tid = tid;
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
t = snd_timer_find(&tid);
|
||||
if (t != NULL) {
|
||||
ginfo->card = t->card ? t->card->number : -1;
|
||||
@ -1451,7 +1452,7 @@ static int snd_timer_user_ginfo(struct file *file,
|
||||
} else {
|
||||
err = -ENODEV;
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo)))
|
||||
err = -EFAULT;
|
||||
kfree(ginfo);
|
||||
@ -1467,7 +1468,7 @@ static int snd_timer_user_gparams(struct file *file,
|
||||
|
||||
if (copy_from_user(&gparams, _gparams, sizeof(gparams)))
|
||||
return -EFAULT;
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
t = snd_timer_find(&gparams.tid);
|
||||
if (!t) {
|
||||
err = -ENODEV;
|
||||
@ -1483,7 +1484,7 @@ static int snd_timer_user_gparams(struct file *file,
|
||||
}
|
||||
err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
|
||||
_error:
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1500,7 +1501,7 @@ static int snd_timer_user_gstatus(struct file *file,
|
||||
tid = gstatus.tid;
|
||||
memset(&gstatus, 0, sizeof(gstatus));
|
||||
gstatus.tid = tid;
|
||||
down(®ister_mutex);
|
||||
mutex_lock(®ister_mutex);
|
||||
t = snd_timer_find(&tid);
|
||||
if (t != NULL) {
|
||||
if (t->hw.c_resolution)
|
||||
@ -1517,7 +1518,7 @@ static int snd_timer_user_gstatus(struct file *file,
|
||||
} else {
|
||||
err = -ENODEV;
|
||||
}
|
||||
up(®ister_mutex);
|
||||
mutex_unlock(®ister_mutex);
|
||||
if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus)))
|
||||
err = -EFAULT;
|
||||
return err;
|
||||
@ -1532,7 +1533,7 @@ static int snd_timer_user_tselect(struct file *file,
|
||||
int err = 0;
|
||||
|
||||
tu = file->private_data;
|
||||
down(&tu->tread_sem);
|
||||
mutex_lock(&tu->tread_sem);
|
||||
if (tu->timeri) {
|
||||
snd_timer_close(tu->timeri);
|
||||
tu->timeri = NULL;
|
||||
@ -1576,7 +1577,7 @@ static int snd_timer_user_tselect(struct file *file,
|
||||
}
|
||||
|
||||
__err:
|
||||
up(&tu->tread_sem);
|
||||
mutex_unlock(&tu->tread_sem);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1797,17 +1798,17 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
|
||||
{
|
||||
int xarg;
|
||||
|
||||
down(&tu->tread_sem);
|
||||
mutex_lock(&tu->tread_sem);
|
||||
if (tu->timeri) { /* too late */
|
||||
up(&tu->tread_sem);
|
||||
mutex_unlock(&tu->tread_sem);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (get_user(xarg, p)) {
|
||||
up(&tu->tread_sem);
|
||||
mutex_unlock(&tu->tread_sem);
|
||||
return -EFAULT;
|
||||
}
|
||||
tu->tread = xarg ? 1 : 0;
|
||||
up(&tu->tread_sem);
|
||||
mutex_unlock(&tu->tread_sem);
|
||||
return 0;
|
||||
}
|
||||
case SNDRV_TIMER_IOCTL_GINFO:
|
||||
|
@ -669,8 +669,10 @@ static int __init alsa_card_dummy_init(void)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(SND_DUMMY_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device)) {
|
||||
|
@ -240,8 +240,10 @@ static int __init alsa_card_mpu401_init(void)
|
||||
return err;
|
||||
|
||||
devices = 0;
|
||||
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
#ifdef CONFIG_PNP
|
||||
if (pnp[i])
|
||||
continue;
|
||||
|
@ -358,7 +358,7 @@ int snd_opl3_new(struct snd_card *card,
|
||||
opl3->hardware = hardware;
|
||||
spin_lock_init(&opl3->reg_lock);
|
||||
spin_lock_init(&opl3->timer_lock);
|
||||
init_MUTEX(&opl3->access_mutex);
|
||||
mutex_init(&opl3->access_mutex);
|
||||
|
||||
if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) {
|
||||
snd_opl3_free(opl3);
|
||||
|
@ -104,8 +104,10 @@ static int snd_opl3_oss_create_port(struct snd_opl3 * opl3)
|
||||
voices, voices,
|
||||
name);
|
||||
if (opl3->oss_chset->port < 0) {
|
||||
int port;
|
||||
port = opl3->oss_chset->port;
|
||||
snd_midi_channel_free_set(opl3->oss_chset);
|
||||
return opl3->oss_chset->port;
|
||||
return port;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -136,10 +138,10 @@ void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name)
|
||||
arg->oper = oss_callback;
|
||||
arg->private_data = opl3;
|
||||
|
||||
snd_opl3_oss_create_port(opl3);
|
||||
|
||||
/* register to OSS synth table */
|
||||
snd_device_register(opl3->card, dev);
|
||||
if (snd_opl3_oss_create_port(opl3)) {
|
||||
/* register to OSS synth table */
|
||||
snd_device_register(opl3->card, dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* unregister */
|
||||
|
@ -52,13 +52,13 @@ int snd_opl3_synth_setup(struct snd_opl3 * opl3)
|
||||
{
|
||||
int idx;
|
||||
|
||||
down(&opl3->access_mutex);
|
||||
mutex_lock(&opl3->access_mutex);
|
||||
if (opl3->used) {
|
||||
up(&opl3->access_mutex);
|
||||
mutex_unlock(&opl3->access_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
opl3->used++;
|
||||
up(&opl3->access_mutex);
|
||||
mutex_unlock(&opl3->access_mutex);
|
||||
|
||||
snd_opl3_reset(opl3);
|
||||
|
||||
@ -91,9 +91,9 @@ void snd_opl3_synth_cleanup(struct snd_opl3 * opl3)
|
||||
spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
|
||||
|
||||
snd_opl3_reset(opl3);
|
||||
down(&opl3->access_mutex);
|
||||
mutex_lock(&opl3->access_mutex);
|
||||
opl3->used--;
|
||||
up(&opl3->access_mutex);
|
||||
mutex_unlock(&opl3->access_mutex);
|
||||
}
|
||||
|
||||
static int snd_opl3_synth_use(void *private_data, struct snd_seq_port_subscribe * info)
|
||||
@ -207,8 +207,10 @@ static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
|
||||
16, voices,
|
||||
name);
|
||||
if (opl3->chset->port < 0) {
|
||||
int port;
|
||||
port = opl3->chset->port;
|
||||
snd_midi_channel_free_set(opl3->chset);
|
||||
return opl3->chset->port;
|
||||
return port;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -218,7 +220,7 @@ static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
|
||||
static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
|
||||
{
|
||||
struct snd_opl3 *opl3;
|
||||
int client;
|
||||
int client, err;
|
||||
char name[32];
|
||||
int opl_ver;
|
||||
|
||||
@ -239,7 +241,11 @@ static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
|
||||
if (client < 0)
|
||||
return client;
|
||||
|
||||
snd_opl3_synth_create_port(opl3);
|
||||
if ((err = snd_opl3_synth_create_port(opl3)) < 0) {
|
||||
snd_seq_delete_kernel_client(client);
|
||||
opl3->seq_client = -1;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* initialize instrument list */
|
||||
opl3->ilist = snd_seq_instr_list_new();
|
||||
|
@ -76,13 +76,13 @@ int snd_opl3_open(struct snd_hwdep * hw, struct file *file)
|
||||
{
|
||||
struct snd_opl3 *opl3 = hw->private_data;
|
||||
|
||||
down(&opl3->access_mutex);
|
||||
mutex_lock(&opl3->access_mutex);
|
||||
if (opl3->used) {
|
||||
up(&opl3->access_mutex);
|
||||
mutex_unlock(&opl3->access_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
opl3->used++;
|
||||
up(&opl3->access_mutex);
|
||||
mutex_unlock(&opl3->access_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -179,9 +179,9 @@ int snd_opl3_release(struct snd_hwdep * hw, struct file *file)
|
||||
struct snd_opl3 *opl3 = hw->private_data;
|
||||
|
||||
snd_opl3_reset(opl3);
|
||||
down(&opl3->access_mutex);
|
||||
mutex_lock(&opl3->access_mutex);
|
||||
opl3->used--;
|
||||
up(&opl3->access_mutex);
|
||||
mutex_unlock(&opl3->access_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ int snd_opl4_create(struct snd_card *card,
|
||||
opl4->fm_port = fm_port;
|
||||
opl4->pcm_port = pcm_port;
|
||||
spin_lock_init(&opl4->reg_lock);
|
||||
init_MUTEX(&opl4->access_mutex);
|
||||
mutex_init(&opl4->access_mutex);
|
||||
|
||||
err = snd_opl4_detect(opl4);
|
||||
if (err < 0) {
|
||||
|
@ -182,7 +182,7 @@ struct snd_opl4 {
|
||||
struct snd_info_entry *proc_entry;
|
||||
int memory_access;
|
||||
#endif
|
||||
struct semaphore access_mutex;
|
||||
struct mutex access_mutex;
|
||||
|
||||
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
|
||||
int used;
|
||||
|
@ -28,13 +28,13 @@ static int snd_opl4_mem_proc_open(struct snd_info_entry *entry,
|
||||
{
|
||||
struct snd_opl4 *opl4 = entry->private_data;
|
||||
|
||||
down(&opl4->access_mutex);
|
||||
mutex_lock(&opl4->access_mutex);
|
||||
if (opl4->memory_access) {
|
||||
up(&opl4->access_mutex);
|
||||
mutex_unlock(&opl4->access_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
opl4->memory_access++;
|
||||
up(&opl4->access_mutex);
|
||||
mutex_unlock(&opl4->access_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -43,9 +43,9 @@ static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
|
||||
{
|
||||
struct snd_opl4 *opl4 = entry->private_data;
|
||||
|
||||
down(&opl4->access_mutex);
|
||||
mutex_lock(&opl4->access_mutex);
|
||||
opl4->memory_access--;
|
||||
up(&opl4->access_mutex);
|
||||
mutex_unlock(&opl4->access_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -62,10 +62,10 @@ static int snd_opl4_seq_use(void *private_data, struct snd_seq_port_subscribe *i
|
||||
struct snd_opl4 *opl4 = private_data;
|
||||
int err;
|
||||
|
||||
down(&opl4->access_mutex);
|
||||
mutex_lock(&opl4->access_mutex);
|
||||
|
||||
if (opl4->used) {
|
||||
up(&opl4->access_mutex);
|
||||
mutex_unlock(&opl4->access_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
opl4->used++;
|
||||
@ -73,12 +73,12 @@ static int snd_opl4_seq_use(void *private_data, struct snd_seq_port_subscribe *i
|
||||
if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM) {
|
||||
err = snd_opl4_seq_use_inc(opl4);
|
||||
if (err < 0) {
|
||||
up(&opl4->access_mutex);
|
||||
mutex_unlock(&opl4->access_mutex);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
up(&opl4->access_mutex);
|
||||
mutex_unlock(&opl4->access_mutex);
|
||||
|
||||
snd_opl4_synth_reset(opl4);
|
||||
return 0;
|
||||
@ -90,9 +90,9 @@ static int snd_opl4_seq_unuse(void *private_data, struct snd_seq_port_subscribe
|
||||
|
||||
snd_opl4_synth_shutdown(opl4);
|
||||
|
||||
down(&opl4->access_mutex);
|
||||
mutex_lock(&opl4->access_mutex);
|
||||
opl4->used--;
|
||||
up(&opl4->access_mutex);
|
||||
mutex_unlock(&opl4->access_mutex);
|
||||
|
||||
if (info->sender.client != SNDRV_SEQ_CLIENT_SYSTEM)
|
||||
snd_opl4_seq_use_dec(opl4);
|
||||
|
@ -789,6 +789,7 @@ static int __init snd_uart16550_create(struct snd_card *card,
|
||||
|
||||
if ((err = snd_uart16550_detect(uart)) <= 0) {
|
||||
printk(KERN_ERR "no UART detected at 0x%lx\n", iobase);
|
||||
snd_uart16550_free(uart);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -989,8 +990,10 @@ static int __init alsa_card_serial_init(void)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(SND_SERIAL_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device)) {
|
||||
|
@ -163,8 +163,10 @@ static int __init alsa_card_virmidi_init(void)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(SND_VIRMIDI_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device)) {
|
||||
|
@ -778,7 +778,7 @@ struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
|
||||
chip->type = hw->type;
|
||||
chip->ops = ops;
|
||||
tasklet_init(&chip->tq, vx_interrupt, (unsigned long)chip);
|
||||
init_MUTEX(&chip->mixer_mutex);
|
||||
mutex_init(&chip->mixer_mutex);
|
||||
|
||||
chip->card = card;
|
||||
card->private_data = chip;
|
||||
|
@ -427,10 +427,10 @@ static int vx_output_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
|
||||
{
|
||||
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
|
||||
int codec = kcontrol->id.index;
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
ucontrol->value.integer.value[0] = chip->output_level[codec][0];
|
||||
ucontrol->value.integer.value[1] = chip->output_level[codec][1];
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -438,7 +438,7 @@ static int vx_output_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
|
||||
{
|
||||
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
|
||||
int codec = kcontrol->id.index;
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
if (ucontrol->value.integer.value[0] != chip->output_level[codec][0] ||
|
||||
ucontrol->value.integer.value[1] != chip->output_level[codec][1]) {
|
||||
vx_set_analog_output_level(chip, codec,
|
||||
@ -446,10 +446,10 @@ static int vx_output_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
|
||||
ucontrol->value.integer.value[1]);
|
||||
chip->output_level[codec][0] = ucontrol->value.integer.value[0];
|
||||
chip->output_level[codec][1] = ucontrol->value.integer.value[1];
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 1;
|
||||
}
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -502,14 +502,14 @@ static int vx_audio_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
|
||||
static int vx_audio_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
if (chip->audio_source_target != ucontrol->value.enumerated.item[0]) {
|
||||
chip->audio_source_target = ucontrol->value.enumerated.item[0];
|
||||
vx_sync_audio_source(chip);
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 1;
|
||||
}
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -550,14 +550,14 @@ static int vx_clock_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
|
||||
static int vx_clock_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
if (chip->clock_mode != ucontrol->value.enumerated.item[0]) {
|
||||
chip->clock_mode = ucontrol->value.enumerated.item[0];
|
||||
vx_set_clock(chip, chip->freq);
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 1;
|
||||
}
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -587,10 +587,10 @@ static int vx_audio_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
|
||||
int audio = kcontrol->private_value & 0xff;
|
||||
int capture = (kcontrol->private_value >> 8) & 1;
|
||||
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
ucontrol->value.integer.value[0] = chip->audio_gain[capture][audio];
|
||||
ucontrol->value.integer.value[1] = chip->audio_gain[capture][audio+1];
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -600,15 +600,15 @@ static int vx_audio_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
|
||||
int audio = kcontrol->private_value & 0xff;
|
||||
int capture = (kcontrol->private_value >> 8) & 1;
|
||||
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
if (ucontrol->value.integer.value[0] != chip->audio_gain[capture][audio] ||
|
||||
ucontrol->value.integer.value[1] != chip->audio_gain[capture][audio+1]) {
|
||||
vx_set_audio_gain(chip, audio, capture, ucontrol->value.integer.value[0]);
|
||||
vx_set_audio_gain(chip, audio+1, capture, ucontrol->value.integer.value[1]);
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 1;
|
||||
}
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -617,10 +617,10 @@ static int vx_audio_monitor_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el
|
||||
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
|
||||
int audio = kcontrol->private_value & 0xff;
|
||||
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
ucontrol->value.integer.value[0] = chip->audio_monitor[audio];
|
||||
ucontrol->value.integer.value[1] = chip->audio_monitor[audio+1];
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -629,17 +629,17 @@ static int vx_audio_monitor_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
|
||||
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
|
||||
int audio = kcontrol->private_value & 0xff;
|
||||
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
if (ucontrol->value.integer.value[0] != chip->audio_monitor[audio] ||
|
||||
ucontrol->value.integer.value[1] != chip->audio_monitor[audio+1]) {
|
||||
vx_set_monitor_level(chip, audio, ucontrol->value.integer.value[0],
|
||||
chip->audio_monitor_active[audio]);
|
||||
vx_set_monitor_level(chip, audio+1, ucontrol->value.integer.value[1],
|
||||
chip->audio_monitor_active[audio+1]);
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 1;
|
||||
}
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -657,10 +657,10 @@ static int vx_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
|
||||
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
|
||||
int audio = kcontrol->private_value & 0xff;
|
||||
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
ucontrol->value.integer.value[0] = chip->audio_active[audio];
|
||||
ucontrol->value.integer.value[1] = chip->audio_active[audio+1];
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -669,15 +669,15 @@ static int vx_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va
|
||||
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
|
||||
int audio = kcontrol->private_value & 0xff;
|
||||
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
if (ucontrol->value.integer.value[0] != chip->audio_active[audio] ||
|
||||
ucontrol->value.integer.value[1] != chip->audio_active[audio+1]) {
|
||||
vx_set_audio_switch(chip, audio, ucontrol->value.integer.value[0]);
|
||||
vx_set_audio_switch(chip, audio+1, ucontrol->value.integer.value[1]);
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 1;
|
||||
}
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -686,10 +686,10 @@ static int vx_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
|
||||
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
|
||||
int audio = kcontrol->private_value & 0xff;
|
||||
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
ucontrol->value.integer.value[0] = chip->audio_monitor_active[audio];
|
||||
ucontrol->value.integer.value[1] = chip->audio_monitor_active[audio+1];
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -698,17 +698,17 @@ static int vx_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
|
||||
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
|
||||
int audio = kcontrol->private_value & 0xff;
|
||||
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
if (ucontrol->value.integer.value[0] != chip->audio_monitor_active[audio] ||
|
||||
ucontrol->value.integer.value[1] != chip->audio_monitor_active[audio+1]) {
|
||||
vx_set_monitor_level(chip, audio, chip->audio_monitor[audio],
|
||||
ucontrol->value.integer.value[0]);
|
||||
vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1],
|
||||
ucontrol->value.integer.value[1]);
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 1;
|
||||
}
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -756,12 +756,12 @@ static int vx_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
|
||||
{
|
||||
struct vx_core *chip = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
ucontrol->value.iec958.status[0] = (chip->uer_bits >> 0) & 0xff;
|
||||
ucontrol->value.iec958.status[1] = (chip->uer_bits >> 8) & 0xff;
|
||||
ucontrol->value.iec958.status[2] = (chip->uer_bits >> 16) & 0xff;
|
||||
ucontrol->value.iec958.status[3] = (chip->uer_bits >> 24) & 0xff;
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -783,14 +783,14 @@ static int vx_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu
|
||||
(ucontrol->value.iec958.status[1] << 8) |
|
||||
(ucontrol->value.iec958.status[2] << 16) |
|
||||
(ucontrol->value.iec958.status[3] << 24);
|
||||
down(&chip->mixer_mutex);
|
||||
mutex_lock(&chip->mixer_mutex);
|
||||
if (chip->uer_bits != val) {
|
||||
chip->uer_bits = val;
|
||||
vx_set_iec958_status(chip, val);
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 1;
|
||||
}
|
||||
up(&chip->mixer_mutex);
|
||||
mutex_unlock(&chip->mixer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -98,10 +98,9 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s
|
||||
static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = subs->runtime;
|
||||
if (runtime->dma_area) {
|
||||
vfree(runtime->dma_area);
|
||||
runtime->dma_area = NULL;
|
||||
}
|
||||
|
||||
vfree(runtime->dma_area);
|
||||
runtime->dma_area = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1254,9 +1253,13 @@ static int vx_init_audio_io(struct vx_core *chip)
|
||||
|
||||
/* allocate pipes */
|
||||
chip->playback_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_outs, GFP_KERNEL);
|
||||
chip->capture_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_ins, GFP_KERNEL);
|
||||
if (! chip->playback_pipes || ! chip->capture_pipes)
|
||||
if (!chip->playback_pipes)
|
||||
return -ENOMEM;
|
||||
chip->capture_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_ins, GFP_KERNEL);
|
||||
if (!chip->capture_pipes) {
|
||||
kfree(chip->playback_pipes);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(chip->playback_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_outs);
|
||||
memset(chip->capture_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_ins);
|
||||
|
@ -291,11 +291,13 @@ static void snd_cs8427_reset(struct snd_i2c_device *cs8427)
|
||||
{
|
||||
struct cs8427 *chip;
|
||||
unsigned long end_time;
|
||||
int data;
|
||||
int data, aes3input = 0;
|
||||
|
||||
snd_assert(cs8427, return);
|
||||
chip = cs8427->private_data;
|
||||
snd_i2c_lock(cs8427->bus);
|
||||
if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) == CS8427_RXDAES3INPUT) /* AES3 bit is set */
|
||||
aes3input = 1;
|
||||
chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~(CS8427_RUN | CS8427_RXDMASK);
|
||||
snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
|
||||
chip->regmap[CS8427_REG_CLOCKSOURCE]);
|
||||
@ -316,7 +318,8 @@ static void snd_cs8427_reset(struct snd_i2c_device *cs8427)
|
||||
}
|
||||
snd_i2c_lock(cs8427->bus);
|
||||
chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK;
|
||||
chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT;
|
||||
if (aes3input)
|
||||
chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT;
|
||||
snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
|
||||
chip->regmap[CS8427_REG_CLOCKSOURCE]);
|
||||
snd_i2c_unlock(cs8427->bus);
|
||||
|
@ -88,7 +88,7 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name,
|
||||
bus = kzalloc(sizeof(*bus), GFP_KERNEL);
|
||||
if (bus == NULL)
|
||||
return -ENOMEM;
|
||||
init_MUTEX(&bus->lock_mutex);
|
||||
mutex_init(&bus->lock_mutex);
|
||||
INIT_LIST_HEAD(&bus->devices);
|
||||
INIT_LIST_HEAD(&bus->buses);
|
||||
bus->card = card;
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
ad1816a.c - lowlevel code for Analog Devices AD1816A chip.
|
||||
Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
|
||||
@ -175,7 +174,7 @@ static void snd_ad1816a_close(struct snd_ad1816a *chip, unsigned int mode)
|
||||
|
||||
|
||||
static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what,
|
||||
int channel, int cmd)
|
||||
int channel, int cmd, int iscapture)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
@ -184,10 +183,14 @@ static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what,
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
spin_lock(&chip->lock);
|
||||
cmd = (cmd == SNDRV_PCM_TRIGGER_START) ? 0xff: 0x00;
|
||||
if (what & AD1816A_PLAYBACK_ENABLE)
|
||||
/* if (what & AD1816A_PLAYBACK_ENABLE) */
|
||||
/* That is not valid, because playback and capture enable
|
||||
* are the same bit pattern, just to different addresses
|
||||
*/
|
||||
if (! iscapture)
|
||||
snd_ad1816a_out_mask(chip, AD1816A_PLAYBACK_CONFIG,
|
||||
AD1816A_PLAYBACK_ENABLE, cmd);
|
||||
if (what & AD1816A_CAPTURE_ENABLE)
|
||||
else
|
||||
snd_ad1816a_out_mask(chip, AD1816A_CAPTURE_CONFIG,
|
||||
AD1816A_CAPTURE_ENABLE, cmd);
|
||||
spin_unlock(&chip->lock);
|
||||
@ -204,14 +207,14 @@ static int snd_ad1816a_playback_trigger(struct snd_pcm_substream *substream, int
|
||||
{
|
||||
struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
|
||||
return snd_ad1816a_trigger(chip, AD1816A_PLAYBACK_ENABLE,
|
||||
SNDRV_PCM_STREAM_PLAYBACK, cmd);
|
||||
SNDRV_PCM_STREAM_PLAYBACK, cmd, 0);
|
||||
}
|
||||
|
||||
static int snd_ad1816a_capture_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
{
|
||||
struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
|
||||
return snd_ad1816a_trigger(chip, AD1816A_CAPTURE_ENABLE,
|
||||
SNDRV_PCM_STREAM_CAPTURE, cmd);
|
||||
SNDRV_PCM_STREAM_CAPTURE, cmd, 1);
|
||||
}
|
||||
|
||||
static int snd_ad1816a_hw_params(struct snd_pcm_substream *substream,
|
||||
|
@ -187,8 +187,10 @@ static int __init alsa_card_ad1848_init(void)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(SND_AD1848_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device)) {
|
||||
|
@ -387,9 +387,9 @@ static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
down(&chip->open_mutex);
|
||||
mutex_lock(&chip->open_mutex);
|
||||
if (chip->mode & AD1848_MODE_OPEN) {
|
||||
up(&chip->open_mutex);
|
||||
mutex_unlock(&chip->open_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
snd_ad1848_mce_down(chip);
|
||||
@ -432,7 +432,7 @@ static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode)
|
||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
||||
|
||||
chip->mode = mode;
|
||||
up(&chip->open_mutex);
|
||||
mutex_unlock(&chip->open_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -441,9 +441,9 @@ static void snd_ad1848_close(struct snd_ad1848 *chip)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
down(&chip->open_mutex);
|
||||
mutex_lock(&chip->open_mutex);
|
||||
if (!chip->mode) {
|
||||
up(&chip->open_mutex);
|
||||
mutex_unlock(&chip->open_mutex);
|
||||
return;
|
||||
}
|
||||
/* disable IRQ */
|
||||
@ -471,7 +471,7 @@ static void snd_ad1848_close(struct snd_ad1848 *chip)
|
||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
||||
|
||||
chip->mode = 0;
|
||||
up(&chip->open_mutex);
|
||||
mutex_unlock(&chip->open_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -889,7 +889,7 @@ int snd_ad1848_create(struct snd_card *card,
|
||||
if (chip == NULL)
|
||||
return -ENOMEM;
|
||||
spin_lock_init(&chip->reg_lock);
|
||||
init_MUTEX(&chip->open_mutex);
|
||||
mutex_init(&chip->open_mutex);
|
||||
chip->card = card;
|
||||
chip->port = port;
|
||||
chip->irq = -1;
|
||||
@ -1202,10 +1202,8 @@ int snd_ad1848_add_ctl(struct snd_ad1848 *chip, const char *name, int index, int
|
||||
strlcpy(ctl->id.name, name, sizeof(ctl->id.name));
|
||||
ctl->id.index = index;
|
||||
ctl->private_value = value;
|
||||
if ((err = snd_ctl_add(chip->card, ctl)) < 0) {
|
||||
snd_ctl_free_one(ctl);
|
||||
if ((err = snd_ctl_add(chip->card, ctl)) < 0)
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -203,8 +203,10 @@ static int __init alsa_card_cs4231_init(void)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(SND_CS4231_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device)) {
|
||||
|
@ -531,7 +531,7 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip,
|
||||
unsigned long flags;
|
||||
int full_calib = 1;
|
||||
|
||||
down(&chip->mce_mutex);
|
||||
mutex_lock(&chip->mce_mutex);
|
||||
snd_cs4231_calibrate_mute(chip, 1);
|
||||
if (chip->hardware == CS4231_HW_CS4231A ||
|
||||
(chip->hardware & CS4231_HW_CS4232_MASK)) {
|
||||
@ -560,7 +560,7 @@ static void snd_cs4231_playback_format(struct snd_cs4231 *chip,
|
||||
snd_cs4231_mce_down(chip);
|
||||
}
|
||||
snd_cs4231_calibrate_mute(chip, 0);
|
||||
up(&chip->mce_mutex);
|
||||
mutex_unlock(&chip->mce_mutex);
|
||||
}
|
||||
|
||||
static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
|
||||
@ -570,7 +570,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
|
||||
unsigned long flags;
|
||||
int full_calib = 1;
|
||||
|
||||
down(&chip->mce_mutex);
|
||||
mutex_lock(&chip->mce_mutex);
|
||||
snd_cs4231_calibrate_mute(chip, 1);
|
||||
if (chip->hardware == CS4231_HW_CS4231A ||
|
||||
(chip->hardware & CS4231_HW_CS4232_MASK)) {
|
||||
@ -603,7 +603,7 @@ static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
|
||||
snd_cs4231_mce_down(chip);
|
||||
}
|
||||
snd_cs4231_calibrate_mute(chip, 0);
|
||||
up(&chip->mce_mutex);
|
||||
mutex_unlock(&chip->mce_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -709,15 +709,15 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
down(&chip->open_mutex);
|
||||
mutex_lock(&chip->open_mutex);
|
||||
if ((chip->mode & mode) ||
|
||||
((chip->mode & CS4231_MODE_OPEN) && chip->single_dma)) {
|
||||
up(&chip->open_mutex);
|
||||
mutex_unlock(&chip->open_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
if (chip->mode & CS4231_MODE_OPEN) {
|
||||
chip->mode |= mode;
|
||||
up(&chip->open_mutex);
|
||||
mutex_unlock(&chip->open_mutex);
|
||||
return 0;
|
||||
}
|
||||
/* ok. now enable and ack CODEC IRQ */
|
||||
@ -737,7 +737,7 @@ static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
|
||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
||||
|
||||
chip->mode = mode;
|
||||
up(&chip->open_mutex);
|
||||
mutex_unlock(&chip->open_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -745,10 +745,10 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
down(&chip->open_mutex);
|
||||
mutex_lock(&chip->open_mutex);
|
||||
chip->mode &= ~mode;
|
||||
if (chip->mode & CS4231_MODE_OPEN) {
|
||||
up(&chip->open_mutex);
|
||||
mutex_unlock(&chip->open_mutex);
|
||||
return;
|
||||
}
|
||||
snd_cs4231_calibrate_mute(chip, 1);
|
||||
@ -785,7 +785,7 @@ static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
|
||||
snd_cs4231_calibrate_mute(chip, 0);
|
||||
|
||||
chip->mode = 0;
|
||||
up(&chip->open_mutex);
|
||||
mutex_unlock(&chip->open_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1408,8 +1408,8 @@ static int snd_cs4231_new(struct snd_card *card,
|
||||
chip->hwshare = hwshare;
|
||||
|
||||
spin_lock_init(&chip->reg_lock);
|
||||
init_MUTEX(&chip->mce_mutex);
|
||||
init_MUTEX(&chip->open_mutex);
|
||||
mutex_init(&chip->mce_mutex);
|
||||
mutex_init(&chip->open_mutex);
|
||||
chip->card = card;
|
||||
chip->rate_constraint = snd_cs4231_xrate;
|
||||
chip->set_playback_format = snd_cs4231_playback_format;
|
||||
@ -1538,8 +1538,8 @@ int snd_cs4231_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm)
|
||||
return err;
|
||||
|
||||
spin_lock_init(&chip->reg_lock);
|
||||
init_MUTEX(&chip->mce_mutex);
|
||||
init_MUTEX(&chip->open_mutex);
|
||||
mutex_init(&chip->mce_mutex);
|
||||
mutex_init(&chip->open_mutex);
|
||||
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs4231_playback_ops);
|
||||
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4231_capture_ops);
|
||||
|
@ -771,9 +771,9 @@ static int __init alsa_card_cs423x_init(void)
|
||||
if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (is_isapnp_selected(i))
|
||||
if (! enable[i] || is_isapnp_selected(i))
|
||||
continue;
|
||||
device = platform_device_register_simple(CS423X_DRIVER,
|
||||
i, NULL, 0);
|
||||
|
@ -644,7 +644,7 @@ static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct s
|
||||
val2 = (chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)] & ~0x7f) | val2;
|
||||
change = val1 != chip->eimage[CS4236_REG(CS4236_LEFT_MASTER)] || val2 != chip->eimage[CS4236_REG(CS4236_RIGHT_MASTER)];
|
||||
snd_cs4236_ext_out(chip, CS4236_LEFT_MASTER, val1);
|
||||
snd_cs4236_ext_out(chip, CS4236_RIGHT_MASTER, val1);
|
||||
snd_cs4236_ext_out(chip, CS4236_RIGHT_MASTER, val2);
|
||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
||||
return change;
|
||||
}
|
||||
@ -841,7 +841,7 @@ static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct sn
|
||||
|
||||
enable = ucontrol->value.integer.value[0] & 1;
|
||||
|
||||
down(&chip->mce_mutex);
|
||||
mutex_lock(&chip->mce_mutex);
|
||||
snd_cs4231_mce_up(chip);
|
||||
spin_lock_irqsave(&chip->reg_lock, flags);
|
||||
val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x0e) | (0<<2) | (enable << 1);
|
||||
@ -854,7 +854,7 @@ static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct sn
|
||||
snd_cs4236_ctrl_out(chip, 4, val);
|
||||
spin_unlock_irqrestore(&chip->reg_lock, flags);
|
||||
snd_cs4231_mce_down(chip);
|
||||
up(&chip->mce_mutex);
|
||||
mutex_unlock(&chip->mce_mutex);
|
||||
|
||||
#if 0
|
||||
printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n",
|
||||
|
@ -207,8 +207,10 @@ static int __init alsa_card_es1688_init(void)
|
||||
return err;
|
||||
|
||||
cards = 0;
|
||||
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (! enable[i])
|
||||
continue;
|
||||
device = platform_device_register_simple(ES1688_DRIVER,
|
||||
i, NULL, 0);
|
||||
if (IS_ERR(device)) {
|
||||
|
@ -49,6 +49,10 @@
|
||||
* - contrarily to some pages in DS_1869.PDF the rates can be set
|
||||
* independently.
|
||||
*
|
||||
* - Zoom Video is implemented by sharing the FM DAC, thus the user can
|
||||
* have either FM playback or Video playback but not both simultaneously.
|
||||
* The Video Playback Switch mixer control toggles this choice.
|
||||
*
|
||||
* BUGS:
|
||||
*
|
||||
* - There is a major trouble I noted:
|
||||
@ -63,7 +67,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* ES1879 NOTES:
|
||||
* - When Zoom Video is enabled (reg 0x71 bit 6 toggled on) the PCM playback
|
||||
* seems to be effected (speaker_test plays a lower frequency). Can't find
|
||||
* anything in the datasheet to account for this, so a Video Playback Switch
|
||||
* control has been included to allow ZV to be enabled only when necessary.
|
||||
* Then again on at least one test system the 0x71 bit 6 enable bit is not
|
||||
* needed for ZV, so maybe the datasheet is entirely wrong here.
|
||||
*/
|
||||
|
||||
#include <sound/driver.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
@ -148,7 +161,7 @@ struct snd_audiodrive {
|
||||
#define ES18XX_DUPLEX_SAME 0x0010 /* Playback and record must share the same rate */
|
||||
#define ES18XX_NEW_RATE 0x0020 /* More precise rate setting */
|
||||
#define ES18XX_AUXB 0x0040 /* AuxB mixer control */
|
||||
#define ES18XX_HWV 0x0080 /* Has hardware volume */
|
||||
#define ES18XX_HWV 0x0080 /* Has seperate hardware volume mixer controls*/
|
||||
#define ES18XX_MONO 0x0100 /* Mono_in mixer control */
|
||||
#define ES18XX_I2S 0x0200 /* I2S mixer control */
|
||||
#define ES18XX_MUTEREC 0x0400 /* Record source can be muted */
|
||||
@ -788,9 +801,12 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id, struct pt_regs *r
|
||||
|
||||
/* Hardware volume */
|
||||
if (status & HWV_IRQ) {
|
||||
int split = snd_es18xx_mixer_read(chip, 0x64) & 0x80;
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id);
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id);
|
||||
int split = 0;
|
||||
if (chip->caps & ES18XX_HWV) {
|
||||
split = snd_es18xx_mixer_read(chip, 0x64) & 0x80;
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id);
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id);
|
||||
}
|
||||
if (!split) {
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id);
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id);
|
||||
@ -939,37 +955,118 @@ static int snd_es18xx_capture_close(struct snd_pcm_substream *substream)
|
||||
* MIXER part
|
||||
*/
|
||||
|
||||
/* Record source mux routines:
|
||||
* Depending on the chipset this mux switches between 4, 5, or 8 possible inputs.
|
||||
* bit table for the 4/5 source mux:
|
||||
* reg 1C:
|
||||
* b2 b1 b0 muxSource
|
||||
* x 0 x microphone
|
||||
* 0 1 x CD
|
||||
* 1 1 0 line
|
||||
* 1 1 1 mixer
|
||||
* if it's "mixer" and it's a 5 source mux chipset then reg 7A bit 3 determines
|
||||
* either the play mixer or the capture mixer.
|
||||
*
|
||||
* "map4Source" translates from source number to reg bit pattern
|
||||
* "invMap4Source" translates from reg bit pattern to source number
|
||||
*/
|
||||
|
||||
static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
static char *texts[8] = {
|
||||
static char *texts4Source[4] = {
|
||||
"Mic", "CD", "Line", "Master"
|
||||
};
|
||||
static char *texts5Source[5] = {
|
||||
"Mic", "CD", "Line", "Master", "Mix"
|
||||
};
|
||||
static char *texts8Source[8] = {
|
||||
"Mic", "Mic Master", "CD", "AOUT",
|
||||
"Mic1", "Mix", "Line", "Master"
|
||||
};
|
||||
struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
|
||||
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
|
||||
uinfo->count = 1;
|
||||
uinfo->value.enumerated.items = 8;
|
||||
if (uinfo->value.enumerated.item > 7)
|
||||
uinfo->value.enumerated.item = 7;
|
||||
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
|
||||
switch (chip->version) {
|
||||
case 0x1868:
|
||||
case 0x1878:
|
||||
uinfo->value.enumerated.items = 4;
|
||||
if (uinfo->value.enumerated.item > 3)
|
||||
uinfo->value.enumerated.item = 3;
|
||||
strcpy(uinfo->value.enumerated.name, texts4Source[uinfo->value.enumerated.item]);
|
||||
break;
|
||||
case 0x1887:
|
||||
case 0x1888:
|
||||
uinfo->value.enumerated.items = 5;
|
||||
if (uinfo->value.enumerated.item > 4)
|
||||
uinfo->value.enumerated.item = 4;
|
||||
strcpy(uinfo->value.enumerated.name, texts5Source[uinfo->value.enumerated.item]);
|
||||
break;
|
||||
case 0x1869: /* DS somewhat contradictory for 1869: could be be 5 or 8 */
|
||||
case 0x1879:
|
||||
uinfo->value.enumerated.items = 8;
|
||||
if (uinfo->value.enumerated.item > 7)
|
||||
uinfo->value.enumerated.item = 7;
|
||||
strcpy(uinfo->value.enumerated.name, texts8Source[uinfo->value.enumerated.item]);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
static unsigned char invMap4Source[8] = {0, 0, 1, 1, 0, 0, 2, 3};
|
||||
struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
|
||||
ucontrol->value.enumerated.item[0] = snd_es18xx_mixer_read(chip, 0x1c) & 0x07;
|
||||
int muxSource = snd_es18xx_mixer_read(chip, 0x1c) & 0x07;
|
||||
if (!(chip->version == 0x1869 || chip->version == 0x1879)) {
|
||||
muxSource = invMap4Source[muxSource];
|
||||
if (muxSource==3 &&
|
||||
(chip->version == 0x1887 || chip->version == 0x1888) &&
|
||||
(snd_es18xx_mixer_read(chip, 0x7a) & 0x08)
|
||||
)
|
||||
muxSource = 4;
|
||||
}
|
||||
ucontrol->value.enumerated.item[0] = muxSource;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
static unsigned char map4Source[4] = {0, 2, 6, 7};
|
||||
struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
|
||||
unsigned char val = ucontrol->value.enumerated.item[0];
|
||||
|
||||
if (val > 7)
|
||||
unsigned char retVal = 0;
|
||||
|
||||
switch (chip->version) {
|
||||
/* 5 source chips */
|
||||
case 0x1887:
|
||||
case 0x1888:
|
||||
if (val > 4)
|
||||
return -EINVAL;
|
||||
if (val == 4) {
|
||||
retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x08) != 0x08;
|
||||
val = 3;
|
||||
} else
|
||||
retVal = snd_es18xx_mixer_bits(chip, 0x7a, 0x08, 0x00) != 0x00;
|
||||
/* 4 source chips */
|
||||
case 0x1868:
|
||||
case 0x1878:
|
||||
if (val > 3)
|
||||
return -EINVAL;
|
||||
val = map4Source[val];
|
||||
break;
|
||||
/* 8 source chips */
|
||||
case 0x1869:
|
||||
case 0x1879:
|
||||
if (val > 7)
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
return snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val;
|
||||
}
|
||||
return (snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val) || retVal;
|
||||
}
|
||||
|
||||
static int snd_es18xx_info_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
@ -1191,19 +1288,22 @@ static int snd_es18xx_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
|
||||
return change;
|
||||
}
|
||||
|
||||
/* Mixer controls
|
||||
* These arrays contain setup data for mixer controls.
|
||||
*
|
||||
* The controls that are universal to all chipsets are fully initialized
|
||||
* here.
|
||||
*/
|
||||
static struct snd_kcontrol_new snd_es18xx_base_controls[] = {
|
||||
ES18XX_DOUBLE("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0),
|
||||
ES18XX_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1),
|
||||
ES18XX_DOUBLE("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("CD Playback Volume", 0, 0x38, 0x38, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("FM Playback Volume", 0, 0x36, 0x36, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0),
|
||||
ES18XX_SINGLE("PC Speaker Playback Volume", 0, 0x3c, 0, 7, 0),
|
||||
ES18XX_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0),
|
||||
ES18XX_DOUBLE("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0),
|
||||
ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Capture Source",
|
||||
@ -1213,19 +1313,37 @@ ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
|
||||
}
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new snd_es18xx_mono_in_control =
|
||||
ES18XX_DOUBLE("Mono Input Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0);
|
||||
|
||||
static struct snd_kcontrol_new snd_es18xx_recmix_controls[] = {
|
||||
ES18XX_DOUBLE("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("FM Capture Volume", 0, 0x6b, 0x6b, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("CD Capture Volume", 0, 0x6a, 0x6a, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0)
|
||||
};
|
||||
|
||||
/*
|
||||
* The chipset specific mixer controls
|
||||
*/
|
||||
static struct snd_kcontrol_new snd_es18xx_opt_speaker =
|
||||
ES18XX_SINGLE("PC Speaker Playback Volume", 0, 0x3c, 0, 7, 0);
|
||||
|
||||
static struct snd_kcontrol_new snd_es18xx_opt_1869[] = {
|
||||
ES18XX_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
|
||||
ES18XX_SINGLE("Video Playback Switch", 0, 0x7f, 0, 1, 0),
|
||||
ES18XX_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0)
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new snd_es18xx_opt_1878 =
|
||||
ES18XX_DOUBLE("Video Playback Volume", 0, 0x68, 0x68, 4, 0, 15, 0);
|
||||
|
||||
static struct snd_kcontrol_new snd_es18xx_opt_1879[] = {
|
||||
ES18XX_SINGLE("Video Playback Switch", 0, 0x71, 6, 1, 0),
|
||||
ES18XX_DOUBLE("Video Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
|
||||
ES18XX_DOUBLE("Video Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0)
|
||||
};
|
||||
|
||||
static struct snd_kcontrol_new snd_es18xx_pcm1_controls[] = {
|
||||
ES18XX_DOUBLE("PCM Playback Volume", 0, 0x14, 0x14, 4, 0, 15, 0),
|
||||
};
|
||||
@ -1270,7 +1388,6 @@ static struct snd_kcontrol_new snd_es18xx_hw_volume_controls[] = {
|
||||
ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0),
|
||||
};
|
||||
|
||||
#if 0
|
||||
static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg)
|
||||
{
|
||||
int data;
|
||||
@ -1281,7 +1398,6 @@ static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned ch
|
||||
spin_unlock_irqrestore(&chip->ctrl_lock, flags);
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip,
|
||||
unsigned char reg, unsigned char data)
|
||||
@ -1427,6 +1543,17 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
|
||||
snd_es18xx_mixer_write(chip, 0x58, 0x94);
|
||||
snd_es18xx_mixer_write(chip, 0x5a, 0x80);
|
||||
}
|
||||
/* Flip the "enable I2S" bits for those chipsets that need it */
|
||||
switch (chip->version) {
|
||||
case 0x1879:
|
||||
//Leaving I2S enabled on the 1879 screws up the PCM playback (rate effected somehow)
|
||||
//so a Switch control has been added to toggle this 0x71 bit on/off:
|
||||
//snd_es18xx_mixer_bits(chip, 0x71, 0x40, 0x40);
|
||||
/* Note: we fall through on purpose here. */
|
||||
case 0x1878:
|
||||
snd_es18xx_config_write(chip, 0x29, snd_es18xx_config_read(chip, 0x29) | 0x40);
|
||||
break;
|
||||
}
|
||||
/* Mute input source */
|
||||
if (chip->caps & ES18XX_MUTEREC)
|
||||
mask = 0x10;
|
||||
@ -1476,11 +1603,14 @@ static int __devinit snd_es18xx_identify(struct snd_es18xx *chip)
|
||||
}
|
||||
|
||||
outb(0x40, chip->port + 0x04);
|
||||
udelay(10);
|
||||
hi = inb(chip->port + 0x05);
|
||||
udelay(10);
|
||||
lo = inb(chip->port + 0x05);
|
||||
if (hi != lo) {
|
||||
chip->version = hi << 8 | lo;
|
||||
chip->ctrl_port = inb(chip->port + 0x05) << 8;
|
||||
udelay(10);
|
||||
chip->ctrl_port += inb(chip->port + 0x05);
|
||||
|
||||
if ((chip->res_ctrl_port = request_region(chip->ctrl_port, 8, "ES18xx - CTRL")) == NULL) {
|
||||
@ -1519,22 +1649,22 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
|
||||
|
||||
switch (chip->version) {
|
||||
case 0x1868:
|
||||
chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL | ES18XX_HWV;
|
||||
chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_CONTROL;
|
||||
break;
|
||||
case 0x1869:
|
||||
chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_MONO | ES18XX_MUTEREC | ES18XX_CONTROL | ES18XX_HWV;
|
||||
break;
|
||||
case 0x1878:
|
||||
chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV;
|
||||
chip->caps = ES18XX_DUPLEX_MONO | ES18XX_DUPLEX_SAME | ES18XX_I2S | ES18XX_CONTROL;
|
||||
break;
|
||||
case 0x1879:
|
||||
chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV;
|
||||
break;
|
||||
case 0x1887:
|
||||
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV;
|
||||
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
|
||||
break;
|
||||
case 0x1888:
|
||||
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV;
|
||||
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
|
||||
break;
|
||||
default:
|
||||
snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n",
|
||||
@ -1778,10 +1908,6 @@ static int __devinit snd_es18xx_mixer(struct snd_es18xx *chip)
|
||||
}
|
||||
}
|
||||
|
||||
if (chip->caps & ES18XX_MONO) {
|
||||
if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_mono_in_control, chip))) < 0)
|
||||
return err;
|
||||
}
|
||||
if (chip->caps & ES18XX_RECMIX) {
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_recmix_controls); idx++) {
|
||||
if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_recmix_controls[idx], chip))) < 0)
|
||||
@ -1819,6 +1945,36 @@ static int __devinit snd_es18xx_mixer(struct snd_es18xx *chip)
|
||||
|
||||
}
|
||||
}
|
||||
/* finish initializing other chipset specific controls
|
||||
*/
|
||||
if (chip->version != 0x1868) {
|
||||
err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_speaker,
|
||||
chip));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
if (chip->version == 0x1869) {
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1869); idx++) {
|
||||
err = snd_ctl_add(card,
|
||||
snd_ctl_new1(&snd_es18xx_opt_1869[idx],
|
||||
chip));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
} else if (chip->version == 0x1878) {
|
||||
err = snd_ctl_add(card, snd_ctl_new1(&snd_es18xx_opt_1878,
|
||||
chip));
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else if (chip->version == 0x1879) {
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_opt_1879); idx++) {
|
||||
err = snd_ctl_add(card,
|
||||
snd_ctl_new1(&snd_es18xx_opt_1879[idx],
|
||||
chip));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1927,6 +2083,7 @@ static int __devinit snd_audiodrive_pnp(int dev, struct snd_audiodrive *acard,
|
||||
err = pnp_activate_dev(acard->devc);
|
||||
if (err < 0) {
|
||||
snd_printk(KERN_ERR PFX "PnP control configure failure (out of resources?)\n");
|
||||
kfree(cfg);
|
||||
return -EAGAIN;
|
||||
}
|
||||
snd_printdd("pnp: port=0x%lx\n", pnp_port_start(acard->devc, 0));
|
||||
@ -2225,9 +2382,9 @@ static int __init alsa_card_es18xx_init(void)
|
||||
if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
|
||||
for (i = 0; i < SNDRV_CARDS; i++) {
|
||||
struct platform_device *device;
|
||||
if (is_isapnp_selected(i))
|
||||
if (! enable[i] || is_isapnp_selected(i))
|
||||
continue;
|
||||
device = platform_device_register_simple(ES18XX_DRIVER,
|
||||
i, NULL, 0);
|
||||
|
@ -149,10 +149,10 @@ static void snd_gf1_dma_interrupt(struct snd_gus_card * gus)
|
||||
|
||||
int snd_gf1_dma_init(struct snd_gus_card * gus)
|
||||
{
|
||||
down(&gus->dma_mutex);
|
||||
mutex_lock(&gus->dma_mutex);
|
||||
gus->gf1.dma_shared++;
|
||||
if (gus->gf1.dma_shared > 1) {
|
||||
up(&gus->dma_mutex);
|
||||
mutex_unlock(&gus->dma_mutex);
|
||||
return 0;
|
||||
}
|
||||
gus->gf1.interrupt_handler_dma_write = snd_gf1_dma_interrupt;
|
||||
@ -160,7 +160,7 @@ int snd_gf1_dma_init(struct snd_gus_card * gus)
|
||||
gus->gf1.dma_data_pcm_last =
|
||||
gus->gf1.dma_data_synth =
|
||||
gus->gf1.dma_data_synth_last = NULL;
|
||||
up(&gus->dma_mutex);
|
||||
mutex_unlock(&gus->dma_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ int snd_gf1_dma_done(struct snd_gus_card * gus)
|
||||
{
|
||||
struct snd_gf1_dma_block *block;
|
||||
|
||||
down(&gus->dma_mutex);
|
||||
mutex_lock(&gus->dma_mutex);
|
||||
gus->gf1.dma_shared--;
|
||||
if (!gus->gf1.dma_shared) {
|
||||
snd_dma_disable(gus->gf1.dma1);
|
||||
@ -185,7 +185,7 @@ int snd_gf1_dma_done(struct snd_gus_card * gus)
|
||||
gus->gf1.dma_data_pcm_last =
|
||||
gus->gf1.dma_data_synth_last = NULL;
|
||||
}
|
||||
up(&gus->dma_mutex);
|
||||
mutex_unlock(&gus->dma_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -225,7 +225,7 @@ int snd_gus_create(struct snd_card *card,
|
||||
spin_lock_init(&gus->dma_lock);
|
||||
spin_lock_init(&gus->pcm_volume_level_lock);
|
||||
spin_lock_init(&gus->uart_cmd_lock);
|
||||
init_MUTEX(&gus->dma_mutex);
|
||||
mutex_init(&gus->dma_mutex);
|
||||
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops)) < 0) {
|
||||
snd_gus_free(gus);
|
||||
return err;
|
||||
|
@ -34,9 +34,9 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry,
|
||||
void snd_gf1_mem_lock(struct snd_gf1_mem * alloc, int xup)
|
||||
{
|
||||
if (!xup) {
|
||||
down(&alloc->memory_mutex);
|
||||
mutex_lock(&alloc->memory_mutex);
|
||||
} else {
|
||||
up(&alloc->memory_mutex);
|
||||
mutex_unlock(&alloc->memory_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ static struct snd_gf1_mem_block *snd_gf1_mem_xalloc(struct snd_gf1_mem * alloc,
|
||||
alloc->first = nblock;
|
||||
else
|
||||
nblock->prev->next = nblock;
|
||||
up(&alloc->memory_mutex);
|
||||
mutex_unlock(&alloc->memory_mutex);
|
||||
return NULL;
|
||||
}
|
||||
pblock = pblock->next;
|
||||
@ -80,7 +80,7 @@ int snd_gf1_mem_xfree(struct snd_gf1_mem * alloc, struct snd_gf1_mem_block * blo
|
||||
{
|
||||
if (block->share) { /* ok.. shared block */
|
||||
block->share--;
|
||||
up(&alloc->memory_mutex);
|
||||
mutex_unlock(&alloc->memory_mutex);
|
||||
return 0;
|
||||
}
|
||||
if (alloc->first == block) {
|
||||
@ -244,7 +244,7 @@ int snd_gf1_mem_init(struct snd_gus_card * gus)
|
||||
#endif
|
||||
|
||||
alloc = &gus->gf1.mem_alloc;
|
||||
init_MUTEX(&alloc->memory_mutex);
|
||||
mutex_init(&alloc->memory_mutex);
|
||||
alloc->first = alloc->last = NULL;
|
||||
if (!gus->gf1.memory)
|
||||
return 0;
|
||||
@ -299,7 +299,7 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry,
|
||||
|
||||
gus = entry->private_data;
|
||||
alloc = &gus->gf1.mem_alloc;
|
||||
down(&alloc->memory_mutex);
|
||||
mutex_lock(&alloc->memory_mutex);
|
||||
snd_iprintf(buffer, "8-bit banks : \n ");
|
||||
for (i = 0; i < 4; i++)
|
||||
snd_iprintf(buffer, "0x%06x (%04ik)%s", alloc->banks_8[i].address, alloc->banks_8[i].size >> 10, i + 1 < 4 ? "," : "");
|
||||
@ -343,7 +343,7 @@ static void snd_gf1_mem_info_read(struct snd_info_entry *entry,
|
||||
}
|
||||
snd_iprintf(buffer, " Total: memory = %i, used = %i, free = %i\n",
|
||||
total, used, total - used);
|
||||
up(&alloc->memory_mutex);
|
||||
mutex_unlock(&alloc->memory_mutex);
|
||||
#if 0
|
||||
ultra_iprintf(buffer, " Verify: free = %i, max 8-bit block = %i, max 16-bit block = %i\n",
|
||||
ultra_memory_free_size(card, &card->gf1.mem_alloc),
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user